越努力越幸运!
超级超级推荐参考好文!!!!! (请点击)
反射
一.反射是什么?
反射是java中强大的一种机制,是为了能够动态的加载一个类,能够动态的调用一个方法,能够动态的访问一个属性等动态要求设计的。
二.反射的原理是什么?
反射机制的基础是jvm在加载一个类的时候,都会为这个类生成一个java.lang.Class类的实例对象,可以通过这个对象去获取这个类的信息,然后通过使用java.lang.reflect包下的API以达到各种动态需求。
三.怎么使用反射
java.lang.Class; //类
java.lang.reflect.Constructor;//构造方法
java.lang.reflect.Field; //类的成员变量
java.lang.reflect.Method;//类的方法
java.lang.reflect.Modifier;//访问权限
1.怎么获取某个类的class对象
1.可以通过java.lang.Class的静态方法forName()方法
2.可以通过每个类都会拥有的静态class属性。
3.可以通过每个对象都会有的getClass()方法。
//第一种方式 通过对象getClass方法
Person person = new Person();
Class<?> class1 = person.getClass();
//第二种方式 通过类的class属性
class1 = Person.class;
try {
//第三种方式 通过Class类的静态方法——forName()来实现
class1 = Class.forName("com.whoislcj.reflectdemo.Person");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
2.怎么实例化一个对象(只知道类名)
1.可以通过Class类中的newInstance()方法(前提是那个类中必须有无参构造方法)
2.可以通过Class类中的getConstructor()方法获得Constructor,再根据Constructor的newInstance()实例化。
所以还是建议每个类中都要无参构造函数比较方便。
//第一种方式 Class对象调用newInstance()方法生成
Object obj = class1.newInstance();
//第二种方式 对象获得对应的Constructor对象,再通过该Constructor对象的newInstance()方法生成
Constructor<?> constructor = class1.getDeclaredConstructor(new Class[]{String.class});//获取指定声明构造函数
obj = constructor.newInstance(new Object[]{"lcj"});
3..怎么操作类的成员变量
主要是依靠java.lang.reflect.Field类中的get(),set()方法
1.使用的是Class类中的方法getDeclaredField()获得指定变量的Field实例,再调用通过对象获得属性
Field[] allFields = class1.getDeclaredFields();//获取class对象的所有属性
Field[] publicFields = class1.getFields();//获取class对象的public属性
try {
Field ageField = class1.getDeclaredField("age");//获取class指定属性
Field desField = class1.getField("des");//获取class指定的public属性
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
4.怎么调用方法
主要依靠的是java.lang.reflect.Method方法中的invoke()
1.根据Class类中的方法获Method实例,再调用invoke来实现方法被动态调用(参数是对象)
try {
// 生成新的对象:用newInstance()方法
Object obj = class1.newInstance();
//判断该对象是否是Person的子类
boolean isInstanceOf = obj instanceof Person;
//首先需要获得与该方法对应的Method对象
Method method = class1.getDeclaredMethod("setAge", new Class[]{int.class});
//调用指定的函数并传递参数
method.invoke(obj, 28);
method = class1.getDeclaredMethod("getAge");
Object result = method.invoke(obj, new Class[]{});
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
5.怎么调用私有变量/方法
调用setAccessible(true)方法。
四.反射的使用场景
1.jdk动态代理