public class ReflectTest {
private String name;
private String type;
// Constructors
public ReflectTest (){
System.out.println("Constructor ReflectTest () is invoking");
}
//私有构造器
private ReflectTest (String name){
this.name = name;
System.out.println("Constructor ReflectTest(String name) is invoking.");
}
//get and set method
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
private void say(String str) {
System.out.println("hello "+str);
}
}
在没有对象实例的时候,主要有两种办法。
//获得类类型的两种方式
Class cls1 = ReflectTest .class;
Class cls2 = Class.forName("demo.ReflectTest ");
注意第二种方式中,forName中的参数一定是完整的类名(包名+类名),并且这个方法需要捕获异常。现在得到cls1就可以创建一个ReflectTest类的实例了,利用Class的newInstance方法相当于调用类的默认的构造器Object o = cls1.newInstance(); //创建一个实例
Object o = cls1.newInstance(); //创建一个实例
//Object o1 = new Role(); //与上面的方法等价
这样就创建了一个对象,缺点是我们只能利用默认构造函数,因为Class的newInstance是不接受参数的,后面会讲到可接受参数的newInstance,第二,如果类的构造函数是private的,比如Class,我们仍旧不能实例化其对象。
获取构造器的方法有4个
- public Constructor<?>[] getConstructors() 返回类中所有的public构造器集合,默认构造器的下标为0
- public Constructor<T> getConstructor(Class<?>... parameterTypes) 返回指定public构造器,参数为构造器参数类型集合
- public Constructor<?>[] getDeclaredConstructors() 返回类中所有的构造器,包括私有
- public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) 返回任意指定的构造器
解释一下:第一个是获得一个指定的方法,我们指定了参数是一个String类型,第二段我们获得了所有的构造方法集合,并选取了其中一个创建了新的对象。注意这里Constructor的newInstance方法就可以设置参数了,与文章前面的同样的方法形成了对比。
- /**
- * 获取构造方法Constructor
- * getConstructor() only for public
- * getDeclaredConstructor() global access all
- *
- * */
- //指定参数列表获取特定的方法
- Constructor con = cls1.getDeclaredConstructor(new Class[]{String.class});
- con.setAccessible(true); //设置可访问的权限
- Object obj = con.newInstance(new Object[]{"liyang"});
- System.out.println(obj); //打印一下这个对象的信息
- //获取所有的构造方法集合
- Constructor con1[] = cls1.getDeclaredConstructors();
- con1[1].setAccessible(true);
- Object obj1 = con1[1].newInstance(new Object[]{"tom"});
- System.out.println(obj1);
注意,以上的四个方法全部需要抛出异常,当我们获得私有的方法的时候,要用setAccessible设置一下可访问的权限,例子中没有演示获取共有方法,那个比较简单,就不做介绍了,其实掌握了上面两个,其他就好理解了。