通过反射实现一个类实例化对象
假设我们有一个 Person类
属性 : private level、public name、public age
方法 : private show(String msg) 、public show2()
构造器: 各种public的以及一个 private 带一个 String name参数的
得到这个类
Class clazz = Person.class;
使用公共的构造器、属性、方法
newInstance(): 调用此方法可以创建对应的运行时类的对象
公共构造器
// 通过反射,创建Person类的对象
Constructor cons = clazz.getConstructor(int.class, String.class); // 得到这个构造器
Object obj = cons.newInstance(70, "70"); // 构造器的参数赋值
Person p = (Person)obj; // 得到了一个实例对象
System.out.println(p.toString());
公共属性
// 通过反射,调用对象指定的属性
Field age = clazz.getDeclaredField("name"); // 得到这个类的属性
age.set(p, "hahahah"); // 指明那个实例对象以及修改的值
System.out.println(p.name); // 输出查看
System.out.println(p.toString());
公共的方法
// 调用方法
Method show = clazz.getDeclaredMethod("show2"); // 得到这个类的方法
show.invoke(p); // 实例话对象调用
使用私有的构造器、属性、方法
私有的构造器、属性、方法比公共的多一个步骤就是 xxx.setAccessible(true);
私有的构造器
// 调用私有的构造器
Constructor cons1 = clazz.getDeclaredConstructor(String.class); // 得到这个类的私有构造器
cons1.setAccessible(true); // 应该是设置可以进行使用(私有的设置)
Person p1 = (Person) cons1.newInstance("小小怪"); // 构造传值
System.out.println(p1);
私有的属性
Field level = clazz.getDeclaredField("level"); // 得到这个类的私有属性
level.setAccessible(true); // 调用私有属性必须要设置
level.set(p1, 7854); // 为这个私有属性赋值
System.out.println(p1);
私有的方法
Method method1 = clazz.getDeclaredMethod("show", String.class); // 得到这个类的私有方法
method1.setAccessible(true);
method1.invoke(p1, "小小怪下士");
获取 class的实例的方式
具体代码如下
@Test
public void getclassTest() throws ClassNotFoundException {
// 方式1 通过运行时,类的属性 .class
Class clazz = Person.class;
System.out.println(clazz);
// 方式2 通过运行时,类的对象调用 getClass()
Person p = new Person();
System.out.println(p.getClass());
// 方式3 通过Class的静态方法 forName(String classPath)
Class clazz1 = Class.forName("jzq.com.demo01.Person");
System.out.println(clazz);
// 方式4 通过类的加载器(就是运行的类) ClassLoader
ClassLoader classLoader = getclassTest.class.getClassLoader();
Class clazz2 = classLoader.loadClass("jzq.com.demo01.Person");
System.out.println(clazz2);
// 判断是否一样
System.out.println(clazz == clazz1); // true
System.out.println(clazz1 == clazz2); // true
System.out.println(clazz2 == p.getClass()); // true
}
动态生产类的实例
package jzq.com.demo01;
import org.junit.Test;
import java.util.Random;
public class dtx {
@Test
public void Test01() {
for (int i = 0; i < 100; i++) {
int num = new Random().nextInt(2);
String classPath = "";
switch (num) {
case 0:
classPath = "jzq.com.demo01.Person1";
break;
case 1:
classPath = "jzq.com.demo01.Anim";
break;
}
try {
Object obj = getInstance1(classPath);
System.out.println(obj);
}catch (Exception e) {
e.printStackTrace();
}
}
}
public static Object getInstance1(String classPath) throws Exception {
Class clazz = Class.forName(classPath); // 动态获取类
return clazz.newInstance();
}
public Object getInstance2(Class classT) throws Exception {
Class clazz = classT; // 动态获取类
return clazz.newInstance();
}
}
class Person1 {
String name;
public Person1() {}
public Person1(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person1{" +
"name='" + name + '\'' +
'}';
}
}
class Anim {
int age;
public Anim() {}
public Anim(int age) {
this.age = age;
}
@Override
public String toString() {
return "Anim{" +
"age=" + age +
'}';
}
}