定义

Java语言中一种动态(运行时)访问、检测、修改它本身的能力。

作用

动态的获取类的完整结构信息,调用对象的方法。

适用地方

Java中的两种类型:编译时类型/运行时类型。

// Person为p的编译时类型,Student为p的运行时类型
Person p = new Student();

在一些极端的情况下,外部传入一个对象时,该对象的编译时类型是object,但程序又需要调用该类的

运行时类型的方法。解决这个问题我们在编程时有两种方法解决。

1.我们知道传入的是类的运行时类型,就可以使用instanceof进行判断,再强制类型转换,就可以使用

这个类的方法和变量。

2.我们不知道传入的对象的类型,也不了解该类的方法和属性,程序只能靠运行时信息来发现对象和类,

这时候我们就必须使用反射。

实现手段

反射主要通过Java的java.lang.Class类来完成。

作用

1.存放着对应类型的运行时信息。

Java运行时虚拟机为所有的类型维护一个java.lang.Class对象,该对象保存着该对象的运行时信息。

泛型的的class为Class

2:每个类型的Class对象只有一个,也就是说地址只有一个。

反射的步骤

1.获取目标对象的class,一般使用Class.forName(String clazzName);

2.通过class对象分别获得该类型的,构造函数,属性,方法。

3.通过获得的属性和方法,进行进一步操作。

反射类

反射的完成依赖了Java提供的反射类,Class,Constructor(构造器),Field(属性), Method(方法)。

Java获取Class的三种方式

1.使用Class的forName(String clazzName)方法,传入字符串,传入为类的全限定名。

2.调用某个类的class属性,

3.调用getClass方法获得。

大部分情况下我们都是通过第二,三种方式获得class对象,在反射中,我们都用的是第一种方法,该方法会

报出ClassNotFoundException异常。

//通过getClass()方法获得
Boolean tian = true;
Class> clazz = tian.getClass();
System.out.println(clazz); //输出结果为:java.lang.Boolean
//通过class方法获得。
Class> clazz = Boolean.class;
System.out.println(clazz); //输出结果为:java.lang.Boolean
//通过Class.forName(String clazzName)获得
Class> clazz = Class.forName("java.lang.Boolean");
System.out.println(clazz); //输出结果为:java.lang.Boolean
//class类的其他用法
getSupperClass();//获取父类class
String getName(); //获取类的完整类名
//快速创建一个类的实例。调用默认构造器,若没有则报异常
Object newInstance();
通过class对象获得Constructor,Field,Method对象
/**
* Constructor(类构造器的获取)
* 带“declared”的方法可以获取包括继承,public不包括private的构造函数
* 不带的无法获取继承,可以获取public,protected,private和默认包访问的构造函数。
*/
//获取所有的构造函数(公共/继承)
Constructor>[] getConstructors();
//指定参数获取类的特定构造函数(传入构造函数的参数类型)
Constructor getConstructors(Class>... parameterTypes)
//获取指定的构造函数不包括继承
Constructor getDeclaredConstructor(Class>... parameterTypes);
//获取所有的构造函数不包括继承的
Constructor> getDeclaredConstructor();
/**
* 获取类属性
*/
//获取指定属性,传入属性名(公共和继承)
Field getField(String name);
//获取所有属性(公共和继承)
Field[] getFields();
//获取指定的属性(不包括继承)
Field getDeclaredField(String name);
//获取所有属性(不包括继承)
Field[] getDeclaredFields();
/**
* 获取类的方法
*/
//获取指定的方法(公共/继承),传入方法名,方法参数
Method getMethod(String name, Class>... parameterTypes);
//获取所有的指定方法(公共、继承)
Method getMethods();
//获取指定的方法(不包括继承)
Method getDeclaredMethod(String name, Class>... parameterTypes);
//获取所有的方法(不包括继承)
Method[] getDeclaredMethods();
通过获取的各个类信息进行进一步操作。
/**
* 通过Constructor类对象获取构造函数信息
*/
String getName();//获取构造器名
Class getDeclaringClass();//获取一个用于描述类中定义的构造函数的class对象。
int getModifiers(); //返回int, 获取构造函数的修饰符等级。
Class[] getExceptionTypes();//获取描述方法抛出的异常类型的Class对象数组。
Class[] getParameterTypes();//获取描述参数类型的Class对象数组。
constructor.newInstance(Class>... parameterTypes);//通过获取的构造函数类,通过指定
参数类调用该来的指定构造函数,创建该类型的实例对象。
/**
* 通过Field类对象获取构造函数信息
*/
String getName(); //获取属性名
Class getDeclaringClass(); //获取Class对象,一般为声明该属性的类的类型class
Class getType(); //获取属性类型的Class对象。
int getModifiers(); //返回int, 获取构造函数的修饰符等级。
Object get(Object obj);//返回该类型的对象上该属性的值。
void set(Object obj,Object Value);//为该类型Class的对象的指定对象,的指定属性赋值。
/**
* 通过Method类对象获取构造函数信息
*/
String getName();//获取方法名
Class getDeclaringClass(); //获取Class对象,一般为声明该方法的类的类型class
int getModifiers(); //返回int, 获取构造函数的修饰符等级。
Class[] getExceptionTypes();//获取描述方法抛出的异常类型的Class对象数组。
Class[] getParameterTypes();//获取描述参数类型的Class对象数组。
Object invoke(Object obj,Class>... parameterTypes);//通过反射结合类的实例对象调用函数。

注意

Java反射默认受限于Java的访问控制。如:无法访问private私有的方法和字段,Java的安全机制不允许查看

这些对象的直接值,若强制读取则抛出异常。