一、反射自述
我的名字叫做---反射机制 我在运行状态中,可以对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能是我特有的也是我的工作。被程序员们称为java语言的反射机制。简单点说就是作为反射你java的编译相关的这些条条框框约束不到我,你一个程序编译完了已经在运行了我照样可以创建对象,获取属性,调用方法,而且不受访问修饰符的限制。我就是这么牛。
java反射的工作能力介绍
我可以在运行时判断任意一个对象所属的类;
我可以在运行时构造任意一个类的对象;
我可以在运行时判断任意一个类所具有的成员变量和方法;
我可以在运行时调用任意一个对象的方法;
我还可以生成动态代理。(Proxy)
java反射的应运场景
简单举几个例子比如说我们开发的时候用到的开发工具Eclipse,为什么eclipse能给你类型的上下文关键字提示,当你输入一个对象,会有一个列表列出所有的对象的方法,这个就是靠的反射。再比如说简单工厂模式,只需要定义一个这样的类,你想要什么对象你直接传类名就ok啦。
public Object getAnimal(String className) throws Exception{
Class<?> cls = Class.forName(className);
Object obj = cls.newInstance();
return obj;
}
反射基本演示获取类:
三种获取方式如下
package wyd.reflect;
/**
* @author create by wyd
* @description 反射演示类
* @date 2018-09-15:18
*/
public class ReflectTest {
public static void main(String args[]){
//3种获取类的方式
//第一种方法:forName
try {
Class<?> class1 = Class.forName("wyd.reflect.Student");
System.out.println( class1 );
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
//第二种方法:class
Class<?> class2 = Student.class;
//第三种方法:getClass
Student stu = new Student();
Class<?> class3 = stu.getClass();
System.out.println( class2 );
System.out.println( class3 );
}
}
结果:
反射获取方法:
try {
Class<?> class1 = Class.forName("wyd.reflect.Student");
System.out.println( class1 );
//获取所有方法
Method [] methods = class1.getMethods();
for(Method mth:methods){
System.out.println(mth);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
结果:
反射获取所有属性:
声明一下getDeclaredFields()和getFields()的区别
getDeclaredFields()获得某个类的所有申明的字段,即包括public、private和proteced,但是不包括父类的申明字段。
getFields()获得某个类的所有的公共(public)的字段,包括父类。
try {
//获取所有属性
Field [] fields = class1.getDeclaredFields();
for (Field fiel:fields) {
System.out.println(fiel);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
结果:
使用反射调用newInstance创建对象
try {
Class<?> class1 = Class.forName("wyd.reflect.Student");
//创建实例化:相当于 new 了一个对象
Object object = class1.newInstance() ;
//向下转型
Student stu = (Student) object ;
stu.setName("每天学java");
System.out.println(stu.getName());
}catch (ClassNotFoundException e) {
e.printStackTrace();
}catch (InstantiationException e){
e.printStackTrace();
}catch (IllegalAccessException e){
e.printStackTrace();
}
结果:
使用getDeclaredMethod("方法名",类型)的时候,int和Integer是严格区分的,两个不能混淆,不然会报错。
//获取int类型和Integer类型的参数方法
Method getintmethod = class1.getDeclaredMethod("setId", int.class);
Method getintmethod = class1.getDeclaredMethod("setAge", Integer.class);
使用构造函数创建对象
//使用构造函数创建对象
Constructor<?> constructor = class1.getDeclaredConstructor( int.class , String.class ) ;
System.out.println(constructor.newInstance(22,"tm"));
总结:
Class类提供了4个public修饰的方法,用于获取某个类的构造方法。
Constructor getConstructor(Class[] params)
根据构造函数的参数,返回一个具体的具有public属性的构造函数Constructor getConstructors()
返回所有具有public属性的构造函数数组
Constructor getDeclaredConstructor(Class[] params)
根据构造函数的参数,返回一个具体的构造函数(不分public和非public属性)
Constructor getDeclaredConstructors()
返回该类中所有的构造函数数组(不分public和非public属性)
4种获取成员方法的方法
Method getMethod(String name, Class[] params)
根据方法名和参数,返回一个具体的具有public属性的方法
Method[] getMethods()
返回所有具有public属性的方法数组
Method getDeclaredMethod(String name, Class[] params)
根据方法名和参数,返回一个具体的方法(不分public和非public属性)
Method[] getDeclaredMethods()
返回该类中的所有的方法数组(不分public和非public属性)
4种获取成员属性的方法
Field getField(String name)
根据变量名,返回一个具体的具有public属性的成员变量
Field[] getFields()
返回具有public属性的成员变量的数组
Field getDeclaredField(String name)
根据变量名,返回一个成员变量(不分public和非public属性)
Field[] getDelcaredField()
返回所有成员变量组成的数组(不分public和非public属性)