网络知识 娱乐 Java中的反射如何理解——精简

Java中的反射如何理解——精简

目录

引言

反射概念 

反射获取类对象 

反射获取构造器对象 

获取构造器对象并使用

反射获取成员变量对象 

反射获取方法对象 

反射获取成员方法并使用 


 

引言

        经过前面的学习,相信大家已经能够对网络编程有了一定的了解,而我们的Java基础知识也要在本次的学习之后结束了,希望之前总结的Java知识能够对你有所帮助。本次我们学习的内容是Java中的反射,这也是一个非常重要的知识点,在这个时候大家可千万不能够放弃学习啊。而且在学习过Javase之后,才会发现这只是冰山一角,废话不多说了,我们开始今天的学习吧!

 

反射概念 

反射是指对于任何一个Class类,在"运行的时候"都可以直接得到这个类全部成分

  • 在运行时,可以直接得到这个类的构造器对象:constructor
  • 在运行时,可以直接得到这个类的成员变量对象:Field
  • 在运行时,可以直接得到这个类的成员方法对象:Method

这种运行时动态获取类信息以及动态调用类中成分的能力称为Java语言的反射机制。
反射的关键

HelloWorld.java -> javac -> HelloWorld.java

Class c = HelloWorld.java

反射获取类对象 

首先,反射的第一步是需要获取类的对象,只有获取了类的对象,才可以进一步获取其他的对象,在此共有三种方法可以获取类的对象:

1、在源代码阶段,通过Class类中的静态方法forName(全限名:包名+类名) 获取;

//Student为要获取的类对象
Class c1 = forNmae("Student");

2、在class对象阶段,通过类名.class直接获取

Class c2 = Student.class

3、在Runtime运行时阶段通过对象获取

Student student = new Student();
Class c3 = student.getClass();

 

反射获取构造器对象 

在前面获取Class类对象之后,便可以获取其类中构造器对象。

Class类中常用于获取构造器的方法

方法说明
Constructor[]getconstructors()返回所有构造器对象的数组(只能拿public的)
constructor[] getDeclaredconstructors()返回所有构造器对象的数组,存在就能拿到
Constructor getconstructor(class... parameterTypes)返回单个构造器对象(只能拿public的)
Constructor getDeclaredConstructor(class... parameterTypes)返回单个构造器对象,存在就能拿到

 

/**
1、返回所有构造器对象的数组(只能拿public的)
getconstructors()
*/
Class c1 = Student.class;
Constructor[] constructors = c1.getconstructors();
/**
2、返回所有构造器对象的数组,存在就能拿到
getDeclaredconstructors()
*/
Class c2 = Student.class;
Constructor[] constructors = c2.getDeclaredconstructors();
/**
3、返回单个构造器对象(只能拿public的)
getconstructor(根据参数个数获取构造器,若无参,则获取无参构造器)
*/
Class c3 = Student.class;
Constructor constructor = c3.getconstructor();
/**
4、返回单个构造器对象,存在就能拿到
getDeclaredconstructor(规则同上)
*/
Class c4 = Student.class;
Constructor constructor = c4.getDeclaredconstructor(String.class,int.class);

获取构造器对象并使用

 获取构造器的作用是初始化一个对象返回

方法说明
T newInstance(Object ...inittargs)根据指定的构造器创建对象
public void setAccessible(boolean flag)设置为true,表示取消访问检查,进行暴力反射
//1、获取单个构造器
Class c = Student.class;
Constructor constructor = c4.getDeclaredconstructor();
//2、调用方法创建对象
Student s = (Student)constructor.newInstance();

在运行代码过后发现并不能创建对象,会直接报错,这是什么原因呢?这是因为获取的构造器是私有的,不能用来直接创建,因此需要用到另一个方法进行暴力反射。在第三行加一行代码

constructor.setAccessible(true);

 

反射获取成员变量对象 

反射的第一步是先得到类对象,然后从类对象中获取类的成分对象

Class类中用于获取成员变量的方法

方法说明
Field[ ]getFields()返回所有成员变量对象的数组〈只能拿public的)
Field[ ]getDeclaredFields()返回所有成员变量对象的数组,存在就能拿到
Field getField(String name)返回单个成员变量对象(只能拿public的)
Field getDeclaredField(String name)返回单个成员变量对象,存在就能拿到

 

/**
1、返回所有成员变量对象的数组〈只能拿public的)
getFields()
*/
Class c = Student.class;
Field[] fields = c.getFields();
/**
2、返回单个成员变量对象(只能拿public的)
getDeclaredField()
*/
Class c = Student.class;
Field field = c.getDeclaredField("name");

Field的方法:给成员变量赋值和取值

方法说明
void set(Object obj,Object value)给对象定义某个成员变量数据
Object  get(Object obj)获取对象成员变量的值
public void setAccessible(boolean flag)设置为true,表示取消访问检查,进行暴力反射
Class getType()获取属性的类型,返回class对象
String getName()获取属性的名称
//1、获取Student对象类
Class c = Student.class;
//2、通过对象类获取name成员变量
Field name = c.getDeclaredField("name");
//3、定义Student类,并为其成员变量name赋值
Student s = new Student();
name.set(s,"石原里美");//s.setName("石原里美")

在运行的过程之中,我们同样会遇到和之前一样的错误,不能对私有成员变量赋值,因此还需要对其进行暴力反射,需要在第二步之后添加一行代码name.setAccessible(true);

 

反射获取方法对象 

反射的第一步先得到类对象,然后从类对象中获取类的方法对象

Class类中用于获取成员方法的方法 

方法说明
Method[ ] getNethods()返回所有成员方法对象的数组(只能拿public的)
Method[ ] getDeclaredMethods()返回所有成员方法对象的数组,存在就能拿到
Method getMethod(String name,class... parameterTypes)返回单个成员方法对象(只能拿public的)
Method getDeclaredMethod(String name,Class... parameterTypes)返回单个成员方法对象,存在就能拿到
//1、获取类对象中所有方法
Class c = Student.class;
Method[] methods = c.getDeclaredMethods();
//2、根据参数获取单个方法
Class c = Student.class;
Method m1 = c.getDeclaredMethod("study");//无参数方法
Method m2 = c.getDeclaredMethod("study",String.class);//若存在方法重载,则需要根据参数区分

反射获取成员方法并使用 

Method类中用于触发执行的方法

方法说明
object invoke(object obj, object. . . args)
 

运行方法:

参数一:用obj对象调用该方法
参数二:调用方法的传递的参数(如果没有就不写)

返回值:方法的返回值(如果没有就不写)

 

Class c = new Student();
Method method = c.getDeclaredMethod("study");
Object result = method.invoke(c);

注意:若没有返回值,则直接返回null,另外若是私有方法则需要对其进行暴力反射。若有参数,则在对象之后传输。

创作不易,给个三连