反射
即所有的类全部都存在一个类对象(Class 类),这个类对象用于提供本身的信息,比如几种构造方法,多少属性,普通方法
获取反射对象的方式有三种
-
class.forName() 全限定类名
-
对象.class
-
类名.getClass()
public static void main(String[] args) {
String className = "charactor.Hero";
try {
Class pClass1=Class.forName(className);
Class pClass2=Hero.class;
Class pClass3=new Hero().getClass();
System.out.println(pClass1==pClass2);
System.out.println(pClass1==pClass3);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//以上代码会打印两个true, 因为一个类只有一个类对象, 所以上面三种方法获取的都是同一个类对象
获取类对象时会导致属性初始化,无论什么途径获取类对象,都会导致静态属性被初始化,而且只会执行一次。(除了直接使用 Class c = Hero.class 这种方式,这种方式不会导致静态属性被初始化)
通过反射获取对象
public class TestReflection {
public static void main(String[] args) {
//传统的使用new的方式创建对象
Hero h1 =new Hero();
h1.name = "teemo";
System.out.println(h1);
try {
//使用反射的方式创建对象
String className = "charactor.Hero";
//类对象
Class pClass=Class.forName(className);
//构造器
Constructor c= pClass.getConstructor();
//通过构造器实例化
Hero h2= (Hero) c.newInstance();
h2.name="gareen";
System.out.println(h2);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//写成一行
//Hero h2=Class.forName("charactor.Hero").getConstructor().newInstance();
//获取类对象 获取类的构造方法,执行进行实例化操作
通过反射操作属性
public static void main(String[] args) {
Hero h =new Hero();
//使用传统方式修改name的值为garen
h.name = "garen";
try {
//获取类Hero的名字叫做name的字段
Field f1= h.getClass().getDeclaredField("name");
//修改这个字段的值
f1.set(h, "teemo");
//打印被修改后的值
System.out.println(h.name);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
getField 和 getDeclaredField 的区别 这两个方法都是用于获取属性字段,getField 只能获取 public 的,包括从父类继承来的字段。getDeclaredField 可以获取本类所有的字段,包括 private 的,但是不能获取继承来的字段,通过 field.setAccessible(true)强行反射
通过反射调用方法
public static void main(String[] args) {
Hero h = new Hero();
try {
// 获取方法名setName,参数类型是String的方法
Method m = h.getClass().getMethod("setName", String.class);
// 对h对象,调用这个方法
m.invoke(h, "盖伦");//调用方法用invoke()
// 使用传统的方式,调用getName方法
System.out.println(h.getName());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
双亲委派机制
当一个类被加载的时候会通过本身的加载器中加载,如果没有向上查找双亲加载器(这就叫做双亲委派机制)加载成功,生成模板Class,也就是描述了类所有的信息的大Class类