Java反射-1

Posted rttrti

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java反射-1相关的知识,希望对你有一定的参考价值。

1.基本概念

a.编译器与运行期

  1. 编译期:把源码交给编译器编译成计算机可以执行的文件的过程(Java代码编程.class文件的过程),只是做了一些翻译功能。
  2. 运行期:将编译后的文件交给计算机执行直至程序运行结束。(在磁盘中的代码放到内存中执行起来)

b.Java反射机制概念及作用

  • Java反射机制: 动态获取信息以及动态调用对象方法的功能。在运行状态中,对于任意一个类,都能知道这个类的所有属性以及方法;对于任意一个对象,都能够调用它的任意方法和属性。

  • Java反射机制在服务器程序和中间件程序中应用广泛(服务器端根据客户请求动态调用某个对象的特定方法)。

c.Java反射机制提供的主要功能

  1. 运行时判断任意一个对象所属的类。
  2. 运行时构造任意一个类的对象。
  3. 运行时判断任意一个类所具有的成员变量和方法。
  4. 运行时调用任意一个对象的方法。
  5. 生成动态代理。(关于动态代理见 https://www.jianshu.com/p/9bcac608c714)

下表:反射可访问的常用信息

d.Java反射机制的优缺点

优点
  1. 能够运行时动态获取类的实例,大大提高系统的灵活性和扩展性
  2. 与Java动态编译相结合,可以实现无比强大的功能
  3. 对于Java这种先编译后运行的而语言,能让我们很方便的创建灵活的代码。这些代码可以在运行时装配,无需在组件之间进行源代码的连接,更加容易实现面向对象。
缺点
  1. 反射会消耗一定的系统资源(不需动态创建对象时不必使用反射)
  2. 反射调用方法时可以忽略权限检查获取类的私有方法和属性,可能会破环类的封装性导致安全问题。

2.Java反射机制API

java.lang.Class类(实现反射的关键所在)

  • Class类的一个实例表示Java的一种数据类型(类、接口、枚举、注解、数组、基本数据类型、void)。Class无公有构造方法,Class实例是由JVM在类加载时自动创建的。

获取Class实例的方法

  1. 每一种类型(类、接口)都有一个class静态变量可以获得Class实例
    Class clz1 = String.class;
  2. 每一个对象都有getClass()方法获得Class实例(Object类提供的实例方法)
    String str = "Hello"; Class clz2 = str.getClass();

java.lang.reflect包

  • 该包提供了反射用到的类,主要类说明如下:
  1. Constructor类:提供类的构造方法信息
  2. Field类:提供类或接口中成员变量信息
  3. Method类:提供类或接口成员方法信息
  4. Array类:提供了动态创建和访问Java数组的方法
  5. Modifier类:提供类和成员访问修饰符信息

代码实例(forName(String))创建某个类的运行时对象,若无则抛出ClassNotFoundException异常

        //动态加载String类的运行时对象
        Class c = Class.forName("java.lang.Integer");
        //获取成员方法集合
        Method[] methods = c.getDeclaredMethods();
        //遍历成员方法集合
        for(Method method: methods){
            //打印修饰符
            System.out.println(Modifier.toString(method.getModifiers()));
            //打印返回值类型名
            System.out.println(method.getReturnType().getName() + " ");
            //打印方法名
            System.out.println(method.getName() + " ");
            System.out.println();

3.Java通过反射访问构造方法

  • 为动态获取对象构造方法的信息,首先需创建一个Constructor类型的对象或数组via下列方法之一
  1. getConstructors()
  2. getConstructors(Class<?>...parameterTypes)
  3. getDeclaredConstructors()
  4. getDeclaredConstructor(Class<?>...parameterTypes)

注:若访问指定的构造方法,需根据该构造方法的入口参数的类型来访问。
eg访问一入口参数为int和String类型的构造方法
objectClass.getDeclaredConstructor(int.class, String.class)

创建的Constructor对象标识一个构造方法,然年后利用Constructor对象的方法操作构造方法。常用方法如下:

对于getModifiers()方法,通过java.lang.reflect.Modifier类可以解析出该方法的返回值所表示的修饰符信息。
在该类中提供了一系列用来解析的静态方法,既可以查看是否被指定的修饰符修饰,还可以字符串形式获得所修饰符。

4.Java通过反射执行方法(获取方法)

  • 要动态获取一个对象方法的信息,需通过下列方法之一创建一个Method类型的对象或数组。
  1. getMethods()
  2. getMethods(String name,Class<?>...parameterTypes)
  3. getDeclaredMethods()
  4. getDeclaredMethods(String name,Class<?>...parameterTypes)

Method类常用方法如下

注:invoke需先指定对象obj eg.
test1 a = new test1("Mike", 22);
Object obj = method.invoke(a, "baby", "I");

5.Java通过反射访问成员变量

  • 通过下列方法访问成员变量时将返回Field类型的对象或数组
  1. getFields()
  2. getField(String name)
  3. getDeclaredFields()
  4. getDeclaredField(String name)

Field类常用方法如下:

以上是关于Java反射-1的主要内容,如果未能解决你的问题,请参考以下文章

反射机制入门

反射机制入门

反射机制入门

使用反射在外部JAR / CLASS上调用包含Hibernate事务的方法(Java EE)

为啥我的 Ray March 片段着色器反射纹理查找会减慢我的帧速率?

OpenGL片段着色器不照亮场景