什么是反射
反射允许对成员变量,成员方法和构造函数的信息进行编程访问
获取class对象的三种方式
- Class.forName("全类名")
- 类名.class
- 对象.getClass();
public class Main {
public static void main(String[] args) {
/*
获取class对象的三种方式
*/
try {
Class class1 = Class.forName("com.cc.Student");
Class class2 = Student.class;
Student student = new Student();
Class class3 = student.getClass();
System.out.println(class1);
System.out.println(class2);
System.out.println(class3);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
}
反射获取构造方法
class类中用于获取构造方法的方法
- Constructor<?>[] getConstructors():返回所有公共构造方法对象的数组
- Constructor<?>[] getDeclaredConstructors():返回所有构造方法对象的数组
- Constructor<?> getConstructors(Class<?>...parameterTypes):返回单个公共构造方法对象
- Constructor<?>[] getDeclaredConstructors(Class<?>...parameterTypes):返回单个构造方法对象
Constructor类中用于创建对象的方法
- T newInstance(Objecrt... initargs):根据指定的构造方法创建对象
- setAccessible(boolean flag):设置为true,表示取消访问检查
示例:先创建一个Student类,并写上几个构造方法:
public class Student {
private int age;
private String name;
public Student() {
}
public Student(int age) {
this.age = age;
}
protected Student(String name) {
this.name = name;
}
private Student(int age,String name){
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
再编写测试类,分别获取所有的公共构造方法、所有的构造方法和单个构造方法:
public class Main {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {
Class aClass = Class.forName("com.cc.Student");
System.out.println("获取所有公共的构造方法");
Constructor[] cons = aClass.getConstructors();
for(Constructor con:cons){
System.out.println(con);
}
System.out.println("=============");
System.out.println("获取所有的构造方法");
Constructor[] cons2 = aClass.getDeclaredConstructors();
for(Constructor con:cons2){
System.out.println(con);
}
System.out.println("=============");
System.out.println("获取单个构造方法");
Constructor con1 = aClass.getDeclaredConstructor();
System.out.println(con1);
Constructor con2 = aClass.getDeclaredConstructor(String.class);
System.out.println(con2);
Constructor con3 = aClass.getDeclaredConstructor(int.class);
System.out.println(con3);
Constructor con4 = aClass.getDeclaredConstructor(int.class,String.class);
System.out.println(con4);
}
}
使用getDeclaredConstructor获取构造方法时,参数要和构造方法的参数列表保持一致
示例:使用Constructor类的对象创建对象:
con4.setAccessible(true);
Student obj = (Student) con4.newInstance(14, "obj");
System.out.println(obj);
注:newInstance的参数要和构造方法的参数保持一致。当构造方法的访问修饰符为private时,可以使用setAccessible方法表示临时取消权限校验,也叫做暴力反射。
反射获取成员变量
class类中用于获取成员变量的方法
- Field[] getFields():返回所有公共成员变量对象的数组
- Field[] getDeclaredFields():返回所有成员变量对象的数组
- Field getField(String name):返回单个公共成员变量对象
- Field getDeclaredField(String name):返回单个成员变量对象
Field类中用于创建对象的方法
- void set(Object obj,Object value):赋值
- Object get(Object obj):获取值
- getModifiers():获取权限修饰符
- getName():获取成员变量的名字
- getType():获取成员变量的数据类型
反射获取成员方法
Class类中用于获取成员方法的方法
- Method[] getMethods():返回所有公共成员方法对象的数组,包括继承的
- Method[] getDeclaredMethods():返回所有成员方法对象的数组,不包括继承的
- Method getMethod(String name,Class<?>... parameterTypes):返回单个公共成员方法对象
- Method getDeclaredMethod(String name,Class<?>... parameterTypes):返回单个成员方法对象
Method类中用于创建对象的方法
- Object invoke(Object obj,Object... args):运行方法
参数一:用obj对象调用该方法
参数二:调用方法的传递的参数
返回值:方法的返回值
示例:给Student写上几个方法:
public void use(){
System.out.println("use方法");
}
public void user(String string){
System.out.println("方法的参数是"+string);
}
public String jdk(){
return "jdk188";
}
System.out.println("获取成员方法(包括父类)");
Method[] methods = aClass.getMethods();
for(Method m:methods){
System.out.println(m);
}
System.out.println("获取成员方法(不包括父类)");
Method[] methods1 = aClass.getDeclaredMethods();
for(Method m:methods1){
System.out.println(m);
}
System.out.println("获取单个方法");
Method user = aClass.getMethod("user", String.class);
System.out.println(user);
System.out.println("获取方法的形参");
Parameter[] p = user.getParameters();
for(Parameter d :p){
System.out.println(d);
}
System.out.println("获取方法抛出的异常");
Class[] ex = user.getExceptionTypes();
for(Class e:ex){
System.out.println(e);
}
System.out.println("获取返回值");
Student s = new Student();
//由s调用该方法,传递的参数是qweasd
//有返回值时可以接收
user.invoke(s,"qweasd");