反射
反射是在运行状态中,对于任意一个类,都能够知道这个类的属性和方法。对于任何一个对象,都能调用它的任意一个方法和属性(哪怕是是私有)
常规功能:
- 在运行时判断一个对象所属的类。
- 在运行时构造任意的一个类的对象。
- 在运行时判断任意一个类所具有的成员变量和方法
- 在运行是调用任意一个对象的方法。
- 动态代理(底层)
获取方式:
//1.第一种
Class<?> clazz=Class.forName(className);//className 为全包名 会有Classnofind异常
//2.第二种
Class<?> clazz=className.class; //类名.class
//3.第三种
className className=new className();
className.getclass();//对象名.getclass();
获取公共方法:
会获得
public 全类名(返回类型) 方法名(全类名+方法名)的格式值
获得本类以及父类接口中的公有方法
Method[] m=clazz.getMethods();//
获取接口:
多接口所以为数组对象
Class<?>[] ints=clazz.getInterfaces();
获取父类:
单父类所以为单对象
Class<?> clazz3=clazz.getSuperclass();
获取构造方法:
Constructor<?>[] aaa= clazz.getConstructors();//获取所有构造方法
Constructor bbb=clazz.getConstructor(null);//获取单独的构造方法,其中null可以为该方法所须参数。
获取公共属性:
其操作类似获取方法。
Field[] fd=clazz.getFields();//获取所有公共属性
获取所有当前类的所有方法
Method[] m=clazz.getDeclaredMethods();
获取当前所有属性:
Field[] fd=clazz.getDeclaredFields();
获取实例对象
className a=(className)clazz.newInstance();
操作私有方法:
Method method=clazz.getDeclaredMethod("",className.class);//获得方法名 ,参数分别为方法名,以及参数类型
method.setAccessible(true);//修改访问权限
method.invoke(obj,arg)//invoke执行方法。方法.invoke(对象,参数(..))
操作私有属性:
Field fd=clazz.getDeclaredField(FieldName);//获得属性名
fd.setAccessible(true);//修改访问权限
fd.set(Class,value);//方法.set(对象名,值)
操作构造方法:
Constructor<?> aaa1= clazz.getConstructor();//参数为类型例如 className.class
aaa1..setAccessible(true);//修改访问权限
className a=(className)clazz.newInstance();
小总结:获取当前类的私有的 都需要加Declared。私有的方法属性都需要修改权限。
代理
Properties prop=new Properties();
prop.load(new FileReader("AAA.Properties"));
String classname=prop.getProperty("classname");
String methodname=prop.getProperty("methodname");
Class<?> clazz=Class.forName(classname);
Method method =clazz.getMethod("methodname");
method.invoke(clazz.newInstance());
从property文件中修改类名以及方法名 得到动态方式修改执行哪个类哪个方法。
越过泛型检查(emm 可以有但没必要)
ArrayList<Integer> list=new ArrayList<>();
Class<?> listClazz=list.getClass();
listClazz.getMethod("add", Object.class).invoke(list, "aaa");
万能赋值方法
public void setProperty(Object obj,String propertyName,Object.value){
Class<?> clazz=obj.getClass();
Field field=clazz.getDeclaredField(propertyName);
field.setAccessidle(true);
field.set(obj,value);
}