天天看点

Java反射机制,反射机制原理,学习与记录

JAVA反射机制,先看下百度百科解释

百度百科:

JAVA反射机制是在运行状态中,对于任意一个实体类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。

JAVA反射(放射)机制:“程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言”。从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态语言。但是JAVA有着一个非常突出的动态相关机制:Reflection,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。

简单理解

通俗来讲:就是java文件编译成class文件后,jvm运行后将class文件读取并把它们加入到内存中,每个class分配了一个class对象(有且只有一个即:后面实例化的对象都是同一个class对象)。在java.lang.Class 这个类中提供了一些方法来获取这些class对象中的成员变量、属性、方法等。

获取方式

其中第3种方式用得较多,如:JDBC加载数据库驱动用到。

  1. Object ——> getClass(); 用父类Object创建。
  2. 类.class属性获取,如:Class userClass = User.class;
  3. Class userClass= Class.forName(“com.User”);//注意此字符串必须是真实路径(包路径.类),

常用方法

  • 1.加载

    Class class= Class.forName(“com.User”);

构造方法:
  • 2.获取所有公有构造方法

    Constructor[] conArray = class.getConstructors();

  • 3.获取所有的构造方法(包括:私有、受保护、默认、公有)

    conArray = class.getDeclaredConstructors();

    for(Constructor c : conArray){

    System.out.println©;

    }

  • 4.获取公有、无参的构造方法

    Constructor con = class.getConstructor();

    //调用构造方法

    Object obj = con.newInstance();

  • 5.获取私有构造方法,并调用

    con = class.getDeclaredConstructor(char.class);

    //调用构造方法

    con.setAccessible(true);//暴力访问(忽略掉访问修饰符)

    obj = con.newInstance(‘A’);

成员变量:
  • 6.获取所有公有的字段

    Field[] fieldArray = stuClass.getFields();

    for(Field f : fieldArray){

    System.out.println(f);

    }

  • 7.获取所有的字段(包括私有、受保护、默认的)

    fieldArray = class.getDeclaredFields();

    for(Field f : fieldArray){

    // 获取字段中带有某个注解属性(可用于自定义注解,如获取导出字段相关属性用于导入导出,ExcelAnnotation :自定义excel注解)

    ExcelAnnotation excelAnnotation = f

    .getAnnotation(ExcelAnnotation.class);

    if (excelAnnotation != null) {

    System.out.println(f+" 字段带有ExcelAnnotation 注解属性");

    }

    System.out.println(f);

    }

  • 8.获取公有字段,并调用

    Field f = class.getField(“name”);

    System.out.println(f);

    //获取一个对象

    Object obj = class.getConstructor().newInstance();// 相当于new User()

    //为字段设置值

    f.set(obj, “李四”);

  • 9.获取私有字段,并调用

    f = class.getDeclaredField(“phoneNum”);

    System.out.println(f);

    f.setAccessible(true);//暴力反射,解除私有限定

    f.set(obj, “18888889999”);

获取成员方法并调用:
  • 10.获取所有的”公有“方法

    Method[] methodArray = class.getMethods();

    for(Method m : methodArray){

    System.out.println(m);

    }

  • 11.获取所有的方法,包括私有的

    Method[] methodArray = class.getDeclaredMethods();

  • 12.获取公有的test()方法

    Method m = class.getMethod(“test”, String.class);

    System.out.println(m);

  • 13.获取私有的test2()方法

    m = class.getDeclaredMethod(“test2”, int.class);//int.class是参数类型

    System.out.println(m);

    m.setAccessible(true);//解除私有限定

    Object result = m.invoke(obj, 20);//需要两个参数,一个是要调用的对象(获取有反射),一个是实参

    System.out.println(“返回值:” + result);

  • 14.调用某个类的某个方法

    public void Test(String s){

    System.out.print(“Test方法被调用”+s);

    }

    //通过反射获取Class对象

    Class class= Class.forName(“cn.com.test.User”);

    //2获取Test()方法

    Method m = class.getMethod(“Test”);

    //3.调用Test()方法

    m.invoke(class.getConstructor().newInstance(),“是我调用的”);