美文网首页
Java反射

Java反射

作者: _小浣熊_ | 来源:发表于2020-11-27 20:20 被阅读0次

介绍

在运行状态中动态获取和调用对象方法的方式被称为反射。java.lang.Class是反射能够实现的基础,每一种类都会被初始化一个Class类型的实例对象,且类的实例共享这个Class类型的实例对象。

java.lang.reflect是实现反射功能的工具包,reflect通过操作类及类实例来实现反射相关功能。类成员抽象为java.lang.reflect.Member接口,类成员主要包括构造函数、变量、方法,在反射工具包中分别对应java.lang.reflect.Constructor类,java.lang.reflect.Field类, java.lang.reflect.Method类,这三个类均实现java.lang.reflect.Member接口。

Java在运行时会进行访问权限检查,private修饰的变量和方法不能直接访问,java.lang.reflect.AccessibleObject提供修改访问权限的功能,通过AccessibleObject.setAccessible可以实现private成员的访问,FieldMethodConstructor也都继承AccessibleObject类。

下面就来讲一讲具体用法。

Class对象

获取class对象有多种方式,这里只介绍常用的方式。

通过对象实例获取Class对象

Class cls = myClassInstance.getClass

通过类的类型获取Class对象

Class cls = MyClass.class

通过类的全限定名获取Class对象

Class c = Class.forName("java.lang.String");

Field类

通过Field可以访问对象的类变量,包括变量的类型、修饰符、注解、变量名、变量值、修改变量值等,Class提供了4种方式获取指定类的Field。

获取指定的变量,包括private修饰的变量

myClassInstance.getClass().getDeclaredField(String name)

获取指定的变量,只支持public修饰的变量

myClassInstance.getClass().getField(String name)

获取所有声明的变量,包括所有private修饰的变量

myClassInstance.getClass().getDeclaredFields()

获取所有public修饰的变量

myClassInstance.getClass().getFields()

Method类

Class提供了4种方式获取指定类的Method。

根据方法名获取指定的方法,name为方法名,parameterTypes为方法的参数类型。如果参数是范型,则当作Object来处理,传入Object.class

myClassInstance.getClass().getDeclaredMethod(String name, Class<?>... parameterTypes)

根据方法名获取指定的public方法

myClassInstance.getClass().getMethod(String name, Class<?>... parameterTypes)

获取所有声明的方法,包括private修饰的方法

myClassInstance.getClass().getDeclaredMethods()

获取所有public修饰的方法

myClassInstance.getClass().getMethods()
通过反射调用方法

反射通过Method的invoke()方法来调用目标方法,第一个参数为需要调用的目标类对象,如果方法为static的,则该参数为null。后面的参数均为目标方法的参数值,顺序与目标方法声明中的参数顺序一致。另外如果方法是private的,可以使用method.setAccessible(true)方法绕过权限检查。

 Object myBean = applicationContext.getBean(beanName);
 Method beanMethod = myBean.getClass().getMethod("run", MyReq.class);

 MyReq myReq = new MyReq();
 MyResp mtResp = (MyResp) beanMethod.invoke(myBean, myReq);

被调用的方法体内所抛出的异常在反射中都会以InvocationTargetException抛出。换句话说,当抛出InvocationTargetException异常时,说明反射调用行为是正确的。

反射的优劣

反射能够在运行时动态获取类的实例,大大提高系统的灵活性和扩展性。但正是因为在运行时动态生成,会导致效率上要比非反射操作低的多,所以存在一定的性能损耗,另外反射在调用方法时可以忽略权限检查,获取类的私有方法和属性,会破坏类的封装性,导致安全问题。所以如果能用常规的方式实现,不需要动态创建一个对象时,不推荐使用反射。

相关文章

  • 博客地址

    java注解-01、java注解-02、Git面试资源java反射-01、java反射-02、java反射-03为...

  • Java反射机制入门

    Java反射机制入门 一、什么是反射 JAVA反射机制(The JAVA reflection mechanism...

  • Java基础之反射

    Java基础之—反射(非常重要)Java中反射机制详解Java进阶之reflection(反射机制)——反射概念与...

  • 反射之一

    总结内容源自一下文章粗浅看java反射机制反射机制应用实践谈谈java反射机制Java Reflection(反射...

  • 反射之二

    总结内容源自一下文章粗浅看java反射机制反射机制应用实践谈谈java反射机制Java Reflection(反射...

  • Java基础之反射

    Java基础之反射 反射基本介绍 反射的使用通过反射调用属性和方法通过反射获取配置文件 反射基本介绍 Java反射...

  • Java 反射机制

    Java 反射机制 什么是反射 Java 反射是Java语言的一个很重要的特征,它使得Java具体了“动态性”。 ...

  • 一探究竟:Java反射效率低的原因到底在哪?

    预备知识 了解 Java 反射基本用法 看完本文可以达到什么程度 了解 Java 反射原理及 Java 反射效率低...

  • 面试官说:大家都说 Java 反射效率低,你知道原因在哪里么

    预备知识 了解 Java 反射基本用法 看完本文可以达到什么程度 了解 Java 反射原理及 Java 反射效率低...

  • Java面试题之JavaSE高级

    一、Java中的反射 1.说说你对Java中反射的理解 java中的反射首先是能够获取到Java...

网友评论

      本文标题:Java反射

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