Java 反射实例化对象
1、通过反射实例化对象
- 首先要获取目标类的class对象,可以通过以下三种方法
/*
* 获取class对象的三种方法`在这里插入代码片`
* */
//1.通过 类名.class
Class personClass1 = Person.class;
//2.通过实例化对象的getClass()方法
Person p = new Person();
Class personClass2 = p.getClass();
//3.通过类的路径名path(path是完整的包名加类名),调用Class.forName(path)方法
Class personClass3 = Class.forName("com.example.demo.reflection.Person");
- 通过目标的class对象来实例化目标对象
/*
* 通过class对象反射出类的实例化对象
* */
//1.直接调用class对象的newInstance(),调用了空构造函数实例化对象
Person person1 = (Person) personClass3.newInstance();
//2.调用class对象的getConstructor(),返回空构造器对象
Constructor constructor1 = personClass3.getConstructor();
Person person2 = (Person) constructor1.newInstance();
//3.调用class对象的getConstructor(),返回带参构造器对象,
//其实String.class等表示对应构造函数的参数类型,为了根据参数找到构造函数的重构方法
Constructor constructor2 = personClass3.getConstructor(String.class, int.class, String.class);
Person person3 = (Person) constructor2.newInstance("Frank", 15, "male");
//4.调用class对象的getDeclaredConstructor(),返回带参构造器对象
Constructor declaredConstructor = personClass3.getDeclaredConstructor(String.class, int.class, String.class);
declaredConstructor.setAccessible(true);
Person person4 = (Person) declaredConstructor.newInstance("Nancy", 25, "female");
2、getConstructors和getDeclaredConstructors的区别
getConstructors包含Person类的公有构造方法,而getDeclaredConstructors则包含Person类的所有构造方法
System.out.println(Arrays.toString(personClass3.getConstructors()));
System.out.println(Arrays.toString(personClass3.getDeclaredConstructors()));
--------------------------------------------------------------------------------------
[public com.example.demo.reflection.Person()]
[public com.example.demo.reflection.Person(), private com.example.demo.reflection.Person(java.lang.String,int,java.lang.String)]
3、getFields和getDeclaredFields的区别
getFields包含Person和其从父类继承来的所有public修饰的属性,而getDeclaredFields只包含Person类的所有的属性
System.out.println(Arrays.toString(personClass3.getFields()));
System.out.println(Arrays.toString(personClass3.getDeclaredFields()));
--------------------------------------------------------------------------------------
[public java.lang.String com.example.demo.reflection.Student.job]
[private java.lang.String com.example.demo.reflection.Person.name, private int com.example.demo.reflection.Person.age, private java.lang.String com.example.demo.reflection.Person.sex]
所以推荐使用下述方法反射实例化对象,此时可以调用Person类的非public修饰的构造方法
再通过setAccessible(true)来跳过权限检测,也可以通过setAccessible(true)来提高反射的性能
Constructor declaredConstructor = personClass3.getDeclaredConstructor(String.class, int.class, String.class);
declaredConstructor.setAccessible(true);
Person person4 = (Person) declaredConstructor.newInstance("Nancy", 25, "female");
上文中使用过的完整测试代码
public class demo01 {
public static void main(String[] args) throws Exception {
/*
* 获取class对象的三种方法
* */
//1.通过 类名.class
Class personClass1 = Person.class;
//2.通过实例化对象的getClass()方法
Person p = new Person();
Class personClass2 = p.getClass();
//3.通过类的路径名path(path是完整的包名加类名),调用Class.forName(path)方法
Class personClass3 = Class.forName("com.example.demo.reflection.Person");
/*
* 通过class对象反射出类的实例化对象
* */
//1.直接调用class对象的newInstance(),调用了空构造函数实例化对象
Person person1 = (Person) personClass3.newInstance();
//2.调用class对象的getConstructor(),返回空构造器对象
Constructor constructor1 = personClass3.getConstructor();
Person person2 = (Person) constructor1.newInstance();
//3.调用class对象的getConstructor(),返回带参构造器对象,
//其实String.class等表示对应构造函数的参数类型,为了根据参数找到构造函数的重构方法
//使用时应对应参数的public修饰的构造方法
//Constructor constructor2 = personClass3.getConstructor(String.class, int.class, String.class);
//Person person3 = (Person) constructor2.newInstance("Frank", 15, "male");
//4.调用class对象的getDeclaredConstructor(),返回带参构造器对象
Constructor declaredConstructor = personClass3.getDeclaredConstructor(String.class, int.class, String.class);
declaredConstructor.setAccessible(true);
Person person4 = (Person) declaredConstructor.newInstance("Nancy", 25, "female");
System.out.println(Arrays.toString(personClass3.getConstructors()));
System.out.println(Arrays.toString(personClass3.getDeclaredConstructors()));
System.out.println(Arrays.toString(personClass3.getFields()));
System.out.println(Arrays.toString(personClass3.getDeclaredFields()));
System.out.println(person4);
}
}
class Person extends Student {
private String name;
private int age;
private String sex;
public Person() {
}
private Person(String name, int age, String sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", sex='" + sex + '\'' +
'}';
}
}
class Student {
public String job;
private String bilibili;
public void method() {}
}