• Java反射(Reflection)是一种新的操作类中成员变量、构造方法和普通方法的机制,为了实现对成员变量、构造方法和普通方法的操作,我们需要借助Java自身提供的java.lang包下的Class类和java.lang.reflect包下的反射API 。
单纯看这个概念可能比较抽象,我们从一般的情况说起:
普通的调用成员变量,构造方法、成员方法的 例子:
图中Test类里就是普通的调用成员变量,构造方法、成员方法的一种方式。而今天要学习的反射,就是调用成员变量、成员方法、构造方法的另一种方式。
要学习反射,就要先学习Class类。我们知道,类是一组对象抽取出来相同的属性和方法,而Class类相当于把不同的类中相同的属性和方法抽取出来,形成类的类。
• Class类是Java 反射机制的入口,封装了一个类或接口的运行时信息,通过调用Class类的方法可以获取这些信息。
package test;
import vo.Student;
public class Test {
public static void main(String[] args) throws ClassNotFoundException {
//方法一
Class studentClass = Student.class;
System.out.println("1、"+studentClass);
//方法二
studentClass = Class.forName("vo.Student");
System.out.println("2、"+studentClass);
//方法三
studentClass = new Student().getClass();
System.out.println("3、"+studentClass);
}
}
运行后输出;
其中的StudentClass代表的就是Student这个类。
package test;
import vo.Student;
public class Test {
public static void main(String[] args) throws ClassNotFoundException {
String [] names = {};
Class arrayClass = String[].class;
System.out.println(arrayClass);
}
}
public class Test {
public static void main(String[] args) throws ClassNotFoundException {
Class intClass = Integer.TYPE;
System.out.println("1、"+intClass);
intClass = Integer.class;
System.out.println("2、"+intClass);
}
}
运行后输出结果:
通过结果我们可以看出:
第一种方式获取到的是基本数据类型int
第二种方式获取到的是Integer这个类
public class Test {
public static void main(String[] args) throws ClassNotFoundException {
Class fatherClass = Student.class.getSuperclass();
System.out.println(fatherClass);
}
}
运行输出结果:
因为Student类的父类是Object类,所以输出为:
另一个更直观的例子:
输出结果为:
package vo;
public class Student {
public Student() {
System.out.println("无参构造方法");
}
public Student(int age) {
System.out.println("有参构造方法1");
}
private Student(String name) {
System.out.println("有参构造方法2");
}
}
Test类:
package test;
import java.lang.reflect.Constructor;
import vo.Student;
public class Test {
public static void main(String[] args) throws ClassNotFoundException {
//获取到对应的类
Class studentClass = Student.class;
//获取到一个类中所有public级别的构造方法
Constructor [] constructors = studentClass.getConstructors();
for (Constructor constructor : constructors) {
System.out.println(constructor);
}
System.out.println("-------------------------------------");
//忽略访问权限,获取到一个类中所有构造方法
constructors = studentClass.getDeclaredConstructors();
for (Constructor constructor : constructors) {
System.out.println(constructor);
}
}
}
package test;
import java.lang.reflect.Constructor;
import vo.Student;
public class Test {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException {
//获取到对应的类
Class studentClass = Student.class;
Constructor constructor0 = studentClass.getDeclaredConstructor();
System.out.println(constructor0);
System.out.println("-------------------------------");
Constructor constructor1 = studentClass.getDeclaredConstructor(Integer.TYPE);
System.out.println(constructor1);
System.out.println("*******************************");
//这个方法没有改成getDeclaredConstructor,因为无法找到第2个有参构造方法所以报错
Constructor constructor2 = studentClass.getConstructor(Integer.TYPE,String.class);
System.out.println(constructor2);
}
}
package test;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import vo.Student;
public class Test {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException {
//获取到对应的类
Class studentClass = Student.class;
//获取到一个构造方法
Constructor constructor = studentClass.getDeclaredConstructor();
//构造方法属于哪一个类
String ClassName = constructor.getDeclaringClass().getName();
System.out.println(ClassName);
//获取构造方法名
String constructorName = constructor.getName();
System.out.println(constructorName);
//获取构造方法修饰符
int result = constructor.getModifiers();
String m = Modifier.toString(result);
System.out.println(m);
}
}
如代码:
Object obj = constructor.newInstance(12,"Tom");
如上图,创建的obj相当于一个Student对象(属于上转型对象)。根据参数执行了有参构造方法2。
public class Test {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
//获取到对应的类
Class studentClass = Student.class;
//获取到构造方法
Constructor constructor = studentClass.getDeclaredConstructor(Integer.TYPE);
Constructor constructor1 = studentClass.getDeclaredConstructor(Integer.TYPE,String.class);
//调用构造方法
Object obj = constructor.newInstance(12);
//忽略访问权限
constructor1.setAccessible(true);
Object obj1 = constructor1.newInstance(12,"Tom");
}
}