Java高级进阶-反射

2017-10-09  本文已影响0人  无止无尽

前言

反射是高级框架的基础,是进阶必备知识点之一,今天就来总结一下反射前前后后相关的知识点。

1.反射机制介绍

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

简单的说就是,一个类有多个组成部分,例如:成员变量,方法,构造方法等。反射就是加载类,并解剖出类的各个组成部分。

2.反射作用

反射可以让我们在运行时获取类的属性,方法,构造方法、父类、接口等信息,通过反射还可以让我们在运行期实例化对象、调用方法、及时方法或属性是私有的也可以通过反射的形式调用。

3.创建和使用

3.1  获取class字节码对象

1.使用Class类的forName(String clazzName)静态方法。该方法需要传入字符串参数,该字符串参数的值是某个类的全限定名(必须添加完整包名)。

2.调用某个类的class属性来获取该类对应的Class对象。

3.调用某个对象的getClass()方法。该方法是java.lang.Object类中的一个方法。


方法1:Class clazz = Class.forName("com.reflect.Student");

方法2Class clazz1 = Student.class;

方法3:Student student = new Student();Class clazz2 = student.getClass();


3.2.获取class对象的属性、构造方法、普通方法

3.2.1  获取class对象的属性


Field[] allFields = clazz.getDeclaredFields();//获取class对象的所有属性

Field[] publicFields = clazz.getFields();//获取class对象的public属性

Field ageField = clazz.getDeclaredField("name");//获取class指定属性

Field desField = clazz.getField("age");//获取class指定的public属性


3.2.2  获取class对象的构造方法


Constructor[] allConstructors = clazz.getDeclaredConstructors();

//获取class对象的所有声明构造函数

Constructor[] publicConstructors = clazz.getConstructors();

//获取class对象public构造函数

Constructor constructor = clazz.getDeclaredConstructor(String.class);

//获取指定声明构造函数

Constructor publicConstructor = clazz.getConstructor(String.class);

//获取指定声明的public构造函数


3.2.3  获取class对象的普通方法


Method[] methods = clazz.getDeclaredMethods();//获取class对象的所有声明方法

Method[] allMethods = clazz.getMethods();//获取class对象的所有public方法 包括父类的方法

Method method = clazz.getMethod("info", String.class);//返回次Class对象对应类的、带指定形参列表的public方法

Method declaredMethod = class1.getDeclaredMethod("info", String.class);//返回次Class对象对应类的、带指定形参列表的方法


3.2.4  获取class对象的信息


boolean isPrimitive = class1.isPrimitive();//判断是否是基础类型

boolean isArray = class1.isArray();//判断是否是集合类

boolean isAnnotation = class1.isAnnotation();//判断是否是注解类

boolean isInterface = class1.isInterface();//判断是否是接口类

boolean isEnum = class1.isEnum();//判断是否是枚举类

boolean isAnonymousClass = class1.isAnonymousClass();//判断是否是匿名内部类

boolean isAnnotationPresent = class1.isAnnotationPresent(Deprecated.class);//判断是否被某个注解类修饰

String className = class1.getName();//获取class名字 包含包名路径

Package aPackage = class1.getPackage();//获取class的包信息

String simpleName = class1.getSimpleName();//获取class类名

int modifiers = class1.getModifiers();//获取class访问权限

Class[] declaredClasses = class1.getDeclaredClasses();//内部类

Class declaringClass = class1.getDeclaringClass();//外部类


3.3  使用class对象

3.3.1  实例操作class对象方法

1.首先根据获取的class对象获取对应的Method方法集合或者获取指定方法

2.通过method方法对象调用invoke(Object obj,Object...params)方法来进行对对象进行修改赋值操作等等。第一个参数是传入的class对象,第二个是对应方法的参数列表。


// 生成新的对象:用newInstance()方法

Object obj = class1.newInstance();

//首先需要获得与该方法对应的Method对象

Method method = clazz.getDeclaredMethod("setAge", int.class);

//调用指定的函数并传递参数

method.invoke(obj, 28);


3.3.2  实例化操作class对象属性

1.通过Class对象的getFields()方法或者getField()方法获得指定方法,返回Field数组或对象。

2.Field提供了两组方法来读取或设置成员变量的值:

getXXX(Object obj):获取obj对象的该成员变量的值。此处的XXX对应8种基本类型。如果该成员变量的类型是引用类型,则取消get后面的XXX。

setXXX(Object obj,XXX val):将obj对象的该成员变量设置成val值。


//生成新的对象:用newInstance()方法

Object obj = class1.newInstance();

//获取age成员变量

Field field = class1.getField("age");

//将obj对象的age的值设置为10

field.setInt(obj, 10);

//获取obj对象的age的值

field.getInt(obj);


3.4  访问权限

在操作class对象方法时,会遇到无法访问的问题,这是因为,方法的访问权限为private,这时我们需要主动将访问权限修改,通过调用method对象的setAccessible(true)可以解决问题。

总结

反射机制是框架的支撑,在Java中有一套获取所有类字节码对象的API,而这正好为我们间接的操作对象提供了方便,同时反射降低了类与类的依赖性,不需要导包,即可创建对象。

参考:

http://www.jianshu.com/p/779b3e27b26d

http://www.jianshu.com/p/f67182a482eb

上一篇 下一篇

猜你喜欢

热点阅读