怎么用反射调用_除了new对象,你还得会反射

首先看下JAVA创建对象的四种方式:

  • 用new关键字创建;(最常用的)
  • 调用对象的clone方法;
  • 利用反射,调用Class类的或者是Constructor类的newInstance()方法;
  • 用反序列化,调用ObjectInputStream类的readObject()方法;

在学习 Java 反射机制前,大家应该先了解两个概念,编译期运行期

编译期:

是指把源码交给编译器编译成计算机可以执行的文件的过程。在 Java 中也就是把 Java 代码编成 class 文件的过程。编译期只是做了一些翻译功能,并没有把代码放在内存中运行起来,而只是把代码当成文本进行操作,比如检查错误。

运行期:

是把编译后的文件交给计算机执行,直到程序运行结束。所谓运行期就把在磁盘中的代码放到内存中执行起来。

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

c29a510fd38d0bd86c2aa82df8f382a1.png

new创建实例

8c360b3c179941d6b4e42d591eadf686.png

反射创建实例

Java 反射机制主要提供了几大功能:

在运行时判断任意一个对象所属的类。在运行时构造任意一个类的对象。在运行时判断任意一个类所具有的成员变量和方法。在运行时调用任意一个对象的方法。 动态代理(这里划重点)。

java反射的实现方式

(1)通过.class

     Class class = Apple.class;

(2)通过创建实例对象来获取类对象

 Apple apple =new Apple(); Class class = apple.getClass();

(3) 通过包名,调用class的forName方法

   Class class =  Class.forName("com.hq.Apple");

实现 Java 反射机制的类都位于 java.lang.reflect 包中,java.lang.Class 类是 Java 反射机制 API 中的核心类。

java.lang.Class 类是实现反射的关键所在,Class 类的一个实例表示 Java 的一种数据类型,包括类、接口、枚举、注解(Annotation)、数组、基本数据类型和 void。Class 没有公有的构造方法,Class 实例是由 JVM 在类加载时自动创建的。

java.lang.reflect 包提供了反射中用到类,主要的类说明如下:

  • Constructor 类:提供类的构造方法信息。
  • Field 类:提供类或接口中成员变量信息。
  • Method 类:提供类或接口成员方法信息。
  • Array 类:提供了动态创建和访问 Java 数组的方法。
  • Modifier 类:提供类和成员访问修饰符信息。

示例代码:

public class ReflectionTest02 {    public static void main(String[] args) {        try {            // 加载String类的运行时对象            Class c = Class.forName("java.lang.String");            // 获取方法集合            Method[] methods = c.getDeclaredMethods();            // 遍历方法集合            for (Method method : methods) {                // 打印权限修饰符,如public、protected、private                System.out.print(Modifier.toString(method.getModifiers()));                System.out.print(" " + method.getReturnType().getName() + " ");// 打印返回值类型名称                System.out.println(method.getName());// 打印方法名称            }        } catch (ClassNotFoundException e) {        }    }}

有的人会问怎么去访问方法,放心java作者都想好了,来看下Method 类的常用方法:

getName() :获取该方法的名称

getParameterType():按照声明顺序以 Class 数组的形式返回该方法各个参数的类型

getReturnType()以 Class 对象的形式获得该方法的返回值类型

getExceptionTypes()以 Class 数组的形式获得该方法可能抛出的异常类型

invoke(Object obj,Object...args)利用 args 参数执行指定对象 obj 中的该方法,返回值为 Object 类型

isVarArgs()查看该方法是否允许带有可变数量的参数,如果允许返回 true,否则返回

falsegetModifiers()获得可以解析出该方法所采用修饰符的整数

具体使用这里就不一一写示例代码了,上手跑下就会了。

反射带来的问题:

  • 反射包括了一些动态类型,所以JVM无法对这些代码进行优化。因此,反射操作的效率要比那些非反射操作低得多。。
  • 使用反射技术要求程序必须在一个没有安全限制的环境中运行。如果一个程序必须在有安全限制的环境中运行,如Applet,那么这就是个问题了。
  • 由于反射允许代码执行一些在正常情况下不被允许的操作(比如访问私有的属性和方法),所以使用反射可能会导致意料之外的副作用:代码有功能上的错误,降低可移植性。
  • 反射破坏了代码的封装性。

提高反射效率:

  • 尽量不要getMethods()后再遍历筛选调用方法,而直接用getMethod(methodName)。
  • 缓存需要多次动态创建一个类的实例。
  • 使用高性能的反射库。
  • 使用高版本JDK也很重要,反射性能一直在提高。

总结

上面说到了反射机制的几大功能,重点--动态代理(极其广泛),后续文章会着重说明。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值