什么是反射
反射机制允许程序在运行时通过反射的API取得类的内部信息,并且可以访问任何属性和方法.
在类加载完毕后,java堆中会有一个Class对象.这个对象包含了这个类的结构信息,我们可以通过一定的方法来得到这个对象.这种方法就是反射.
获取Class对象
package com;
public class Test {
public static void main(String[] args) throws ClassNotFoundException {
Class c1=Class.forName("com.User");
System.out.println(c1);
}
}
class User{
String name;
int age;
}
一个类只有一个Class对象
package com;
public class Test {
public static void main(String[] args) throws ClassNotFoundException {
Class c1=Class.forName("com.User");
Class c2=Class.forName("com.User");
System.out.println(c1==c2);
System.out.println(c1);
}
}
class User{
String name;
int age;
}
有三种获取Class对象的方法.
package com;
public class Test {
public static void main(String[] args) throws ClassNotFoundException {
Person person1=new Student("学生");
Class clazz1=person1.getClass();//通过对象来获得
Class clazz2=Student.class;//通过获得静态属性来获得.
Class clazz3=Class.forName("com.Student");//通过forName来获得.
System.out.println(clazz1==clazz2&&clazz2==clazz3);
}
}
class Person{
String name;
int age;
}
class Student extends Person{
Student(String name){
this.name=name;
}
}
万物皆有Class对象
package com;
public class Test {
public static void main(String[] args) throws ClassNotFoundException {
Class c1=int.class;
Class c2=boolean.class;
Class c3=void.class;
Class c4=String.class;
Class c5=Class.class;
Class c6=Person.class;
Class c7=Integer.class;
System.out.println(c1);
System.out.println(c2);
System.out.println(c3);
System.out.println(c4);
System.out.println(c5);
System.out.println(c6);
System.out.println(c7);
}
}
class Person{
String name;
int age;
}
class Student extends Person{
Student(String name){
this.name=name;
}
}
Class对象产生的时期
在通过类加载器加载数据到内存中后,会在方法区存入一些元数据.通过这些元数据在堆中创建Class对象.
static变量的经历过程
1,在链接过程中static变量会被设为初始值.(这里变量类型已经确定了)
2,在初始化过程中会将static变量和static代码块合并并运行.
public class Test {
public static void main(String[] args) throws ClassNotFoundException {
System.out.println(Person.m);
}
}
class Person{
static int m=100;
static {
m=1000;
}
String name;
int age;
}
三种类型的类加载器
引导类加载器: 用C++编写的,是JVM自带的类加载器,负责Java平台核心库,用来装载核心类库,该加载器无法直接获取.
扩展类加载器: 负责jre/lib/ext目录下的jar包或 -D java.ext.dirs指定目录下的jar包装入工作库
系统类加载器: 负责java -classpath或-D java.class.path所指的目录下的类与jar包装入工作,是最常用的加载器.
public class Test {
public static void main(String[] args) throws ClassNotFoundException {
ClassLoader systemLoader=ClassLoader.getSystemClassLoader();
System.out.println(systemLoader);//系统类加载器
System.out.println(systemLoader.getParent());//扩展类加载器
System.out.println(systemLoader.getParent().getParent());//引导类加载器
}
}
可以发现引导类加载器无法获得.