美文网首页
Android 学习(二):Java 反射

Android 学习(二):Java 反射

作者: 翟小乙 | 来源:发表于2021-09-26 14:02 被阅读0次

上一篇 Android 学习(一):Java 泛型

Java反射学习

  • 什么时候反射?
    Java反射机制是在运行状态中,对任意一个类,都能知道该类的所有属性和方法;对任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及调用对象的方法的功能成为java语言的反射机制。

前提:必须先要获取到该类的字节码文件对应的Class类型的对象,而解剖类中的各成分使用的就是Class类中的方法。

其实,反射就是把java类中的各种成分映射成一个个的java对象

  • 主要API
  1. 类java.lang.Class
  2. 构造方法 Constructor
  3. 成员变量 Field
  4. 方法 Method

原理图

5.jpg
1. Class对象

每一个对象运行时都有一个对于的Class对象,Class(查API)的获取有三种方式

  • 已有对象,调用对象的getClass方法(Object类中的getClass方法)
User user = new User();
Class<?> c1 = user.getClass();
  • 类型.class
User user = new User();
Class<?> c2 = User.class;
  • 不知道对象,只有对象的全限名字符串Class.forName(String classNmae)
Class<?> c3 = Class.forName("包名.类名")
  • 重点

Class.forName("包名.类名"); 根据全限名获得Class对象
newInstance(); 通过Class创建实例,相当于调用无参数构造器创建实例

  • 列子说明:
// 通过 .class 获取对象
Class<?> c2 = User.class;
// 通过 c2 创建一个实例(无参构造器)
Object obj = c2.newInstance();
// 打印结果 为([name = null])
System.out.println("obj:"+obj);
2. Field成员变量
  • Class.forName("包名.类名") 获取Class对象
  • Class.getDeclaredFields() 获取对象中所有的成员变量Field
  • Field.getName() 获取变量名字
  • Field.getType() 获取变量类型
  • Class.getDeclaredField(String name) 根据成员变量名字找到成员变量
  • Field.set(Object,Object) 给对象赋值
  • Filed.get(Object obj) 获取对象上的该成员变量Field
  • Filed.isAccessible() 是否可以直接使用: 因为私有方法返回的是flase 不能直接赋值
  • Filed.setAccessible(true) 如果不能直接使用,可手动设置可以直接使用
Class<?> c3 = Class.forName("包名.Animal");
// 1.0 打印所有成员变量
Field[] fields = c3.getDeclaredFields();
for (Field field : fields) {
System.out.println(field.getType()+"----"+field.getName());
              // 打印结果为:class java.lang.String----name
}
// 2.0 根据成员变量名字找到成员变量
Field field = c3.getDeclaredField("name");
System.out.println(field.getType()+"----"+field.getName());
               // 打印结果为:class java.lang.String----name 
//3.0 给对象赋值
Object obj =  c3.newInstance();//給对象创建实例
if(!filed.isAccessible) {
    filed.setAccessible(true);
}
  field.set(obj,"小狗"); // 设置对象的name 为小狗
System.out.println(obj);
             // 打印结果为 Animal [ name = 小狗 ]
//4.0 获取对象上的该成员变量Field
Object object = field.get(obj); // 获取对象内成员变量为name的值
System.out.println(object );
             // 打印结果为  小狗 
3. 方法 Method
  • Class.getDeclaredMethods() 获取对象中所有的方法不包括继承方法
  • Class.getDeclaredMethod(String name,类<?>...parameterTypes) 标识类或者接口的指定声明方法,类对象
  • Method.invoke(Object,...paramete) 调用对象内该方法且可以传递参数,也可无参调用
Class<?> c3 = Class.forName("包名.Animal");
Method[] methods = c3.getDeclaredMethods();
for (Method method : methods) {
System.out.println("方法名:"+method .getName()+"----参数个数 :"+method.getParameterCount);
           // 打印结果为 方法名: getName 参数个数 0  方法名: setName 参数个数 1 
// 1.0 获取所有参数类型
Class<?> classesTypes = method.getParameterTypes();
for (Class<?>  clasType : classesTypes  ) {
System.out.println(clasType );
          // 打印结果为: java.lang.String
}
// 2.0 根据方法的名字和参数类型获取方法
Method method = c3.getDeclaredMethod("setName",String.class); // 获取setName方法
Object objectC3 = c3.newInstance();// 类对象实例化

method .invoke(objectC3 ,"小鹏");// 调用对象内该方法并且赋值

Method getMethod = c3.getDeclaredMethod("getName");// 获取getName方法
Object objectGetMeth = getMethod.invoke(objectC3); // 调用对象内该方法 并返回对象
System.out.println(objectGetMeth );
            // 打印结果为: 小鹏
3. 构造方法Constructor
  • getDeclaredConstructors() 获取对象内所有的构造器
  • getDeclaredConstructor(类<?>...parameterTypes) 返回对象内指定参数的Constructor构造器
  • newInstance() 根据构造器创建对象
Class<?> c4 = Class.forName("报名.Animal"); //获取类对象
Object obj = c4.newInstance(); //获取类对象的实例
Constructor<?>[] constructors = c4.getDeclaredConstructors();
//1.0 获取构造器的名字和参数个数及参数类型
for (Constructor<?>[] constructor : constructors ) {
System.out.println("构造器名字:"+constructor.getName+"构造器参数个数:"+constructor.getParameterCount());
           //打印结果为:  构造器名字:包名.Animal 构造器参数个数:0
Class<?> constructorParameterTypes =  constructor.getParameterTypes();//获取此构造器内所有的参数类型
for (Class<?> constructorParameterType : constructorParameterTypes ) {
System.out.println(constructorParameterType);
}
// 2.0 通过构造器创建对象
       // 第一步拿到构造器 第二步通过构造器创建对象
      // 无参数 类似于 Animal animal = new Animal();
Constructor<?> constructor = c4.getConstructor();
Object object = constructor .newInstance(null);
System.out.println(object );
            // 因为结果为: Animal [ name = null ]
    // 有参数 Animal animal = new Animal(String name);
Constructor<?> constructor1 = c4.getConstructor(String.class);
Object object = constructor1 .newInstance("小斋");
System.out.println(object );
            // 因为结果为: Animal [ name = 小斋]

下一篇 Android 学习(三):Java 注解

相关文章

网友评论

      本文标题:Android 学习(二):Java 反射

      本文链接:https://www.haomeiwen.com/subject/myszgltx.html