通过反射创建类实例
通常有2种方式,使用Class类的newInstance方法,或使用Constructor类的newInstance方法。
但是,Class类的newInstance方法通常只能适用于无参构造器的类。Constructor类的newInstance方法既可用于无参构造器,也可用于有参构造器.
推荐使用后者
直接看示例。
demo.java
demo类:一个显式的无参构造器, 2个含参的构造器, public、protected、private级别的方法各一个, 另一个public级别的重载
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| package javaClassExercise.newObjectStyle;
public class demo { private demo() { System.out.println("demo's constructor is called."); }
private demo(int a, int b) { System.out.println(a+b); }
private demo(String s, Integer i) { System.out.println(s + i); }
public void printSth() { System.out.println("demo Class printSth..."); }
public void printSth(String s) { System.out.println(s); }
private void printa() { System.out.println("private method called"); }
protected void printa(Integer a) { System.out.println(a); } }
|
demoTest.java
将Class.NewInstance() 和 Constructor.newInstance() 两种创建新实例的方式进行了简单的“面向过程式”的封装[之所以说是面向过程,是因为这2个简单封装的方法,严格来讲未达到是封装的标准,里面很多参数都是写的固定的!!!]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
| package javaClassExercise.newObjectStyle;
import java.lang.reflect.Constructor;
public class demoTest {
public static void main(String[] args) { demoTest demoTest = new demoTest(); System.out.println("通过Class.NewInstance()调用私有构造函数:"); demoTest.newInstanceByClassNewInstance();
System.out.println("通过Constructor.NewInstance()调用私有构造函数:"); demoTest.newInstanceByConstructorNewInstance();
}
public void newInstanceByClassNewInstance() { try { demo demo = (demo)Class.forName("javaClassExercise.newObjectStyle.demo").newInstance(); }catch (Exception e) { System.out.println("通过Class.NewInstance()调用私有构造函数【失败】"); } }
public void newInstanceByConstructorNewInstance() { try {
Class c = Class.forName("javaClassExercise.newObjectStyle.demo");
Constructor c0 = c.getDeclaredConstructor(); c0.setAccessible(true);
demo demo0 = (demo)c0.newInstance(); demo0.printSth("lomo");
demo0.printa(6666);
Constructor c1 = c.getDeclaredConstructor(new Class[] {int.class, int.class}); c1.setAccessible(true); demo demo1 = (demo)c1.newInstance(new Object[]{4,5}); demo1.printSth();
}catch (Exception e) { System.out.println("通过Constructor.NewInstance()调用私有构造函数【失败】"); } } }
|
运行输出结果:
1 2 3 4 5 6 7 8
| 通过Class.NewInstance()调用私有构造函数: 通过Class.NewInstance()调用私有构造函数【失败】 通过Constructor.NewInstance()调用私有构造函数: demo's constructor is called. lomo 6666 9 demo Class printSth...
|
通过Class.newInstance()
方式创建新实例失败,因为demo类构造函数为私有,如果demo类无显式声明的构造函数,或显式声明无参构造器,则可以使用这种方式创建新实例。
修改demo类的无参构造器为public,就可以在demoTest中通过上述方式创建新实例。
1 2 3
| public demo() { System.out.println("demo's constructor is called."); }
|
1 2 3
| 通过Class.NewInstance()调用私有构造函数: demo's constructor is called.
|
通过Constructor.newInstance()
方式创建新实例,无论demo类的构造器是否private、无论是否有误参数 都可以。
反射机制的使用:工厂模式中,Factory类中使用反射机制,添加新类时,就不需要需改工厂类。
关于setAccessible, 点此查看