【JavaSe】高级特性篇(四) Java高级特性反射机制

JavaSe·高级特性篇(四) Java高级特性反射机制


1. Java Reflection 概述

Reflection(反射)是被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方法。

加载完类之后,在堆内存的方法区中就产生了一个Class类型的对象(一个类只有一个Class对象),这个对象就包含了完整的类的结构信息。我们可以通过这个对象看到类的结构。这个对象就像一面镜子,透过这个镜子看到类的结构,所以,我们形象的称之为:反射。
在这里插入图片描述

2. 动态语言 VS 静态语言

1、动态语言
是一类在运行时可以改变其结构的语言:例如新的函数、对象、甚至代码可以被引进,已有的函数可以被删除或是其他结构上的变化。通俗点说就是在运行时代码可以根据某些条件改变自身结构。
主要动态语言:Object-C、C#、JavaScript、PHP、Python、Erlang

2、静态语言
与动态语言相对应的,运行时结构不可变的语言就是静态语言。如Java、C、C++

Java不是动态语言,但Java可以称之为“准动态语言”。即Java有一定的动态性,我们可以利用反射机制、字节码操作获得类似动态语言的特性。Java的动态性让编程的时候更加灵活!

3. Java反射机制概述

3.1 反射机制提供的功能:

  • 在运行时判断任意一个对象所属的类
  • 在运行时构造任意一个类的对象
  • 在运行时判断任意一个类所具有的成员变量和方法
  • 在运行时获取泛型信息
  • 在运行时调用任意一个对象的成员变量和方法
  • 在运行时处理注解
  • 生成动态代理

3.2 反射相关的主要API

  • java.lang.Class:代表一个类
  • java.lang.reflect.Method:代表类的方法
  • java.lang.reflect.Field:代表类的成员变量
  • java.lang.reflect.Constructor:代表类的构造器
  • … …

3.3 反射的好处

  1. 可以在程序运行过程中,操作这些对象。
  2. 可以解耦,提高程序的可扩展性。

4. Class类

Class类用于表示.class文件,是所有加载进内存的字节码对象的父类。所以可以通过Class得到运行时的类

4.1 获取 Class 类的实例

1)前提:若已知具体的类,通过类的class属性获取,该方法最为安全可靠,程序性能最高

  • 实例:Class clazz = String.class;

2)前提:已知某个类的实例,调用该实例的getClass()方法获取Class对象

  • 实例:Class clazz = “aaa”.getClass();

3)前提:已知一个类的全类名,且该类在类路径下,可通过Class类的静态方法forName()获取,可能抛出ClassNotFoundException

  • 实例:Class clazz = Class.forName(“java.lang.String”);

4)类加载器
ClassLoader cl = this.getClass().getClassLoader();
Class clazz4 = cl.loadClass(“类的全类名”);

public static void main(String...args)throws Exception{ 
	String str = "aaa"; 
	Class cls1 = String.class; 
	Class cls2 = str.getClass(); 
	Class cls3 = Class.forName("java.lang.String"); 
	System.out.println(cls1 == cls2);//true 
	System.out.println(cls2 == cls3);//true 
} 

字节码文件是唯一的,所以无论怎么获取,都是同一份字节码文件

5. 通过反射创建对象

  1. 调用Class对象的newInstance()方法
    用该方法能创建对象,但有以下两个要求:
    1)类必须有一个无参数的构造器。
    2)类的构造器的访问权限需要足够

  2. 使用构造器对象创建
    步骤:
    1)通过Class类的getDeclaredConstructor(Class … parameterTypes)取得本类的指定形参类型的构造器
    2)向构造器的形参中传递一个对象数组进去,里面包含了构造器中所需的各个参数。
    3)通过Constructor得newInstance实例化对象。

//1.根据全类名获取对应的Class对象
String name = “entity.Person";
Class clazz = Class.forName(name);
//2.调用指定参数结构的构造器,生成Constructor的实例
Constructor con = clazz.getConstructor(String.class,Integer.class);
//3.通过Constructor的实例创建对应类的对象,并初始化类属性
Person p2 = (Person) con.newInstance("Peter",20);
System.out.println(p2);

6. 通过反射获取运行时类的完整结构

Field、Method、Constructor、Superclass、Interface、Annotation

6.1 反射获取实现的所有接口

public Class<?>[] getInterfaces()

确定此对象所表示的类或接口实现的接口

6.2 反射获取所继承的父类

public Class<? Super T> getSuperclass()

返回表示此 Class 所表示的实体(类、接口、基本类型)的父类的Class。

6.3 反射获取全部的构造器

public Constructor<T>[] getConstructors()

返回此 Class 对象所表示的类的所有public构造方法。

public Constructor<T>[] getDeclaredConstructors()

返回此 Class 对象表示的类声明的所有构造方法。

  • Constructor类中:
    • 取得修饰符: public int getModifiers();
    • 取得方法名称: public String getName();
    • 取得参数的类型:public Class<?>[] getParameterTypes();

6.4 反射获取全部的方法

public Method[] getDeclaredMethods()

返回此Class对象所表示的类或接口的全部方法

public Method[] getMethods()

返回此Class对象所表示的类或接口的public的方法

  • Method类中:
    • public Class<?> getReturnType()取得全部的返回值
    • public Class<?>[] getParameterTypes()取得全部的参数
    • public int getModifiers()取得修饰符
    • public Class<?>[] getExceptionTypes()取得异常信息

6.5 反射获取全部的Field

public Field[] getFields()

返回此Class对象所表示的类或接口的public的Field。

public Field[] getDeclaredFields()

返回此Class对象所表示的类或接口的全部Field。

  • Field方法中:
    • public int getModifiers() 以整数形式返回此Field的修饰符
    • public Class<?> getType() 得到Field的属性类型
    • public String getName() 返回Field的名称。

6.6 反射获取Annotation

getAnnotation(Class<T> annotationClass)
getDeclaredAnnotations()

6.7 反射获取泛型相关

Type getGenericSuperclass()

获取父类泛型类型

泛型类型:ParameterizedType
获取实际的泛型类型参数数组:getActualTypeArguments()

6.8 反射获取类所在的包

Package getPackage() 

7. 通过反射调用运行时类的指定结构

7.1 反射调用指定方法

通过反射,调用类中的方法,通过Method类完成。

  1. 通过Class类的getMethod(String name,Class…parameterTypes)方法取得一个Method对象,并设置此方法操作时所需要的参数类型。
  2. 之后使用Object invoke(Object obj, Object[] args)进行调用,并向方法中传递要设置的obj对象的参数信息。
Object invoke(Object obj, Object … args)

1.Object 对应原方法的返回值,若原方法无返回值,此时返回null
2.若原方法若为静态方法,此时形参Object obj可为null
3.若原方法形参列表为空,则Object[] args为null
4.若原方法声明为private,则需要在调用此invoke()方法前,显式调用方法对象的setAccessible(true)方法,将可访问private的方法。

7.2 反射调用指定属性

在反射机制中,可以直接通过Field类操作类中的属性,通过Field类提供的set()和
get()方法就可以完成设置和取得属性内容的操作

  • public Field getField(String name) 返回此Class对象表示的类或接口的指定的public的Field
  • public Field getDeclaredField(String name)返回此Class对象表示的类或接口的指定的Field

在Field中:

  • public Object get(Object obj) 取得指定对象obj上此Field的属性内容
  • public void set(Object obj,Object value) 设置指定对象obj上此Field的属性内容

8 暴力反射

8.1 概述

反射机制中,默认开启访问安全检查,不能通过反射访问私有的 Method,Filed和Constructor对象,若想要访问,就得关闭访问安全检查,也就是暴力反射

8.2 关闭访问安全检查

  • Method和Field、Constructor对象都有setAccessible()方法。
    • setAccessible启动和禁用访问安全检查的开关。

8.3 暴力反射的作用

  1. 提高反射的效率。如果代码中必须用反射,而该句代码需要频繁的被调用,那么请设置为true。
  2. 使得原本无法访问的私有成员也可以访问
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【完整课程列表】 资源汇总下载地址:https://download.csdn.net/download/qq_27595745/55418618 Java SE编程入门教程 collection与collections(共7页).pptx Java SE编程入门教程 java GC(共6页).pptx Java SE编程入门教程 java instanceof(共3页).pptx Java SE编程入门教程 java IO(共28页).pptx Java SE编程入门教程 java Math(共11页).pptx Java SE编程入门教程 java object(共9页).pptx Java SE编程入门教程 java static final(共24页).pptx Java SE编程入门教程 java this和super(共10页).pptx Java SE编程入门教程 java 常用API(共22页).pptx Java SE编程入门教程 javaGUI编程快速入门(1)(共82页).pptx Java SE编程入门教程 java包装器(共9页).pptx Java SE编程入门教程 java反射机制(共16页).pptx Java SE编程入门教程 java泛型(共11页).pptx Java SE编程入门教程 java封装继承多态(共56页).pptx Java SE编程入门教程 java集合(共38页).pptx Java SE编程入门教程 java接口(共21页).pptx Java SE编程入门教程 java类和对象方法以及包的使用(共56页).pptx Java SE编程入门教程 java类和对象方法以及包的使用(共62页).pptx Java SE编程入门教程 java判断循环(共79页).ppt Java SE编程入门教程 java入门以及变量debug(共63页).pptx Java SE编程入门教程 java设计模式(共17页).pptx Java SE编程入门教程 java数组(共33页).pptx Java SE编程入门教程 java网络编程(共29页).pptx Java SE编程入门教程 java线程(共61页).pptx Java SE编程入门教程 java序列化(共14页).pptx Java SE编程入门教程 java异常(共57页).pptx Java SE编程入门教程 java正则(共8页).pptx Java SE编程入门教程 properties(共3页).pptx Java SE编程入门教程 String字符串(共27页).pptx Java 位运算.docx java正则表达式例子大全 共10页.doc JAVA正则表达式实例教程 共17页.docx JAVA正则表达式实例教程 共17页.pdf 递归算法.docx 堆和栈.wps

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值