反射
Java 反射机制,可以实现以下功能:
①在运行时判断任意一个对象所属的类;
②在运行时构造任意一个类的对象;
③在运行时判断任意一个类所具有的成员变量和方法;
④在运行时调用任意一个对象的方法;
⑤生成动态代理
注意:
1、在创建类型的对象的时候,获取的是类型的Class对象的一个镜像|复制体
2、在一个类加载到内存时就会存在这个类型唯一的Class对象(方法,属性,构造器…)
3、如果能够拿到一个类型的Class对象,就可以操作这个类
- 获取一个类型的Class对象的方式:
1、类名.class
2、对象.getClass()
3、Class.forName(报名+类名|权限定名)
4、通过子类的class对象获取父类的class对象
5、通过基本数据类型的包装类型TYPE属性,获取基本数据类型的class对象
public static void main(String[] args) throws ClassNotFoundException {
//1.类名.class
Class<String> cls1=String.class;
System.out.println(cls1);
//2.对象.getClass()
Class cls2="你好".getClass();
System.out.println(cls1==cls2); //true
//3.Class.forName(报名+类名|权限定名)
Class cls3=Class.forName("java.lang.String");
System.out.println(cls1==cls3); //true
//4.通过子类的Class对象获取父类的Class对象
Class cls4=cls1.getSuperclass();
System.out.println(cls4);
//基本数据类型的Class对象
Class clsInt=int.class;
System.out.println(clsInt); //int
Class clsInteger=Integer.class;
System.out.println(clsInteger); //class java.lang.Integer
System.out.println(clsInt==clsInteger);//false
//Integer.TYPE-->int的Class类型的对象
System.out.println(int.class==Integer.TYPE);
//常用方法
//Class<?>[] getInterfaces() 当前Class对象所表示的类|接口所实现的接口的Class对象数组
Class<?>[] arr=cls1.getInterfaces();
System.out.println(Arrays.toString(arr));
//int getModifiers() 返回此类或接口以整数编码的 Java 语言修饰符。
System.out.println("类的修饰符的和"+Modifier.toString(cls1.getModifiers()));
// String getName() 报名+类名
System.out.println(cls1.getName());
//String getSimpleName() 类名
System.out.println(cls1.getSimpleName());
//boolean isPrimitive() 判定指定的 Class 对象是否表示一个基本类型。
System.out.println(Integer.TYPE.isPrimitive());
}
-
通过反射获取类中构造器:
1、Constructor getConstructor(Class<?>… parameterTypes)
返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法。
2、Constructor<?>[] getConstructors()
返回一个包含某些 Constructor 对象的数组,这些对象反映此 Class 对象所表示的类的所有公共构造方法。
3、Constructor getDeclaredConstructor(Class<?>… parameterTypes)
返回一个 Constructor 对象,该对象反映此 Class 对象所表示的类或接口的指定构造方法。
4、Constructor<?>[] getDeclaredConstructors()
返回 Constructor 对象的一个数组,这些对象反映此 Class 对象表示的类声明的所有构造方法。 -
通过反射创建对象:
1、Constructor->newInstance(参数的class对象…)
2、Class类中newInstance() -
通过反射获取方法:
1、Method getDeclaredMethod(String name, Class<?>… parameterTypes)
返回一个 Method 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明方法。
2、 Method[] getDeclaredMethods()
返回 Method 对象的一个数组,这些对象反映此 Class 对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。
3、Method getMethod(String name, Class<?>… parameterTypes)
返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法。
4、Method[] getMethods()
返回一个包含某些 Method 对象的数组,这些对象反映此 Class 对象所表示的类或接口(包括那些由该类或接口声明的以及从超类和超接口继承的那些的类或接口)的公共 member 方法。 -
通过反射执行方法:
Object invoke(Object obj, Object… args) 返回值:调用执行的方法的返回值
obj调用当前成员方法的对象
可变参数args 方法的实参 -
通过反射获取字段:
1、Field getDeclaredField(String name)
返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段。
2、Field[] getDeclaredFields()
返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或接口所声明的所有字段。
3、Field getField(String name)
返回一个 Field 对象,它反映此 Class 对象所表示的类或接口的指定公共成员字段。
4、Field[] getFields()
返回一个包含某些 Field 对象的数组,这些对象反映此 Class 对象所表示的类或接口的所有可访问公共字段。 -
操作字段:
1、设置值 void set(Object obj, Object value)将指定对象变量上此 Field 对象表示的字段设置为指定的新值。
2、获取值 Object get(Object obj)返回指定对象上此 Field 表示的字段的值。 -
反射操作数组:
Array 类提供了动态创建和访问 Java 数组的方法。
public static void main(String[] args) {
//static Object newInstance(Class<?> componentType, int length) 创建一个具有指定的组件类型和长度的新数组。
Object obj=Array.newInstance(int.class, 8);
System.out.println("判断是否为数组"+obj.getClass().isArray()); //true
//static void set(Object array, int index, Object value) 将指定数组对象中索引组件的值设置为指定的新值。
Array.set(obj,1,111);
//static Object get(Object array, int index) 返回指定数组对象中索引组件的值。
System.out.println(Array.get(obj, 1));
System.out.println(Arrays.toString((int[])obj));
}