反射是用来处理“元数据”的。
比如说某类有一个字段,叫做name,它用来保存对象的姓名值;
反射技术是来操作name这个字段本身的,是对字段、方法、构造器的封装。
Field
Method
Constructor
以上的三个反射类或相关类都在java.lang.reflect包中。
在java源代码中,只有java.lang包中的类会自动导入进来,并不包括子包。
就是说如果需要使用子包中类时,必须使用import导入到代码中。
通过类名或类实例可以得到类综合信息的封装体,这个封装也是以对象的方式提供的,称为Class。这个Class对象封装了该类的所有“元数据”信息。
如何得到这个封装体?
1、 通过类名
2、 通过类对象,调用Object中提供的getClass()方法
使用Class<T>或Class<?>的场合?
1、 如果类名已知,使用Class<T>;
2、 如果类名未知,使用Class<?>
获取类全名:
getName()
获取简单类名:
getSimpleName()
一个类的元数据封装体就一个,属于单例类;
不论这个对象是用什么方式得到的。
获取字段的方法:
getField(String name)
getFields()
以上两个方法受到的访问修饰级别的限制;而常用的是下面的方法:
getDeclaredField(String name)
getDeclareFields()
使用以上两个声明字段的访问,标志着通过反射技术,可以直接访问类中的私有成员。
与Field有关的方法:
字段的两种功能:赋值和获取
正常赋值方式:Student s = new Student();s.setName(“zhangsan”);
以上的赋值中,s是实例,setName是方法,”zhangsan”是赋的数据。
现在有了Field对象,可以通过反射赋值和获取值;
File类
set(Object obj,Object value)
获取字段值的方法:
get(Object obj)
Field,Method,Constrator三个类有一个共同的父类AccessibleObject;
在父类中提供了两个增强访问权限(即可以访问私有成员)的方法,
setAccessible(boolean flag)
Constructor类:
getDeclaredConstructor()
通过构造器元数据对象获取类对象;
newInstance()
Method类:
Class类的一个非常有用的方法:
forName(String)方法:
forName(String className)
方法的作用是通过类全名来得到一个类对象!
总结一下,获取类的实例共有哪些方法?
1、 直接调用构造器,使用new运算符构造对象,这也是最常用的方法;
2、 通过调用类的静态工厂方法获取类的实例;
3、 通过类全名
4、 通过构造器Constructor的newInstance()方法
getModifiers()
反射技术中的访问修饰级别问题:
该类负责将整数表示的访问修饰级别转换为熟悉的访问修饰的关键字级别。
该方法负责将整数变为字符串
toString(int mod)