写Method方法后,再来搞定反射构造方法,当然可能要被很多正规出书的人嗤之以鼻,但是这一切都不重要,重要的是,对于一个初学者,以本人自己学习的过程,颠倒的来写,会让人更容易接受一些.
同样的,给出Constructor类的几个API :
newInstance(Object... initargs) throws InstantiationException,
| 初始化一个类实例的时候调用,参数和实际构造方法里面参数个数和参数类型保持一致的传递. |
Int getParameterCount() | 偶尔可以用这个方法查一下当前构造方面是带了几个参数的. |
http://docs.oracle.com/javase/7/docs/api/java/lang/reflect/Constructor.html |
好了,其实API还要好几个,有需要的读者,可以参考下面的链接,查看.
下面,继续做程序,做测试,看看上面的如何使用.
<1> : 新建一个java工程,目录树如下 :
<2> : 新建一个被测试的类FlexClass.java,如下 :
/**
*
*/
package com.oneplus.flex;
/**
* @author zhibao.liu
* @date 2015-11-18
* @company : oneplus.Inc
*/
public class FlexClass {
private int days;
private String name;
private char a;
private int month;
private int year;
private String msg;
public FlexClass() {
msg = "here is zhibao.liu in oneplus.Inc!";
}
public FlexClass(char a, String name, int days) {
this.a = a;
this.name = name;
this.days = days;
}
public FlexClass(int year) {
this.year = year;
}
public FlexClass(int month, String name) {
this.month = month;
this.name = name;
}
public FlexClass(String msg) {
this.msg = msg;
}
private int Add(){
return month+year;
}
private void showName(){
System.out.println("Name : "+name);
}
private void showMsg(){
System.out.println("message : "+msg);
}
}
我在上面写了5个不同的构造方法,现在你先看看通过反射列举所有的构造和及其参数个数,在主类中增加代码如下 :
private static void OneplusConstructorFlex(String packagename){
try {
Class clazz=Class.forName(packagename);
try {
Object obj=clazz.newInstance();
Constructor[] constructs=clazz.getDeclaredConstructors();
for(int i=0;i<constructs.length;i++){
System.out.println("Constructor "+i+" parameter count : "+constructs[i].getParameterCount());
}
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
得到的结果如下:
下面来看一看具体使用,在主类中再增加一个方法:
private static void OneplusUsingConstructorFlex(String packagename){
try {
Class clazz=Class.forName(packagename);
try {
Constructor constructor=clazz.getDeclaredConstructor(new Class[]{int.class,String.class});
try {
Object obj=constructor.newInstance(new Object[]{12,"I am zhibao.liu !!!"});
Method method=clazz.getDeclaredMethod("showName", new Class[]{});
method.setAccessible(true);
method.invoke(obj, new Object[]{});
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
程序大概讲解 :
<1> :Constructor constructor=clazz.getDeclaredConstructor(new Class[]{int.class,String.class});
这一步很显然制定了,获取带两个参数的构造方法,其中构造方法第一个参数是int型,第二个位String型,这样一步就确定了获取制定的构造方法进行实例化.
<2> : Object obj=constructor.newInstance(new Object[]{12,"I am zhibao.liu !!!"});
根据上面制定的构造方法,进行实例化的时候传入指定数据类型的参数值.
<3> : 经过上面两部,就完全确定了反射出来的类使用的是哪一个构造方法实例化出来的.
<4> : 然后:
Method method=clazz.getDeclaredMethod("showName", new Class[]{});
method.setAccessible(true);
method.invoke(obj, new Object[]{});
通过这一段来验证构造时传入的参数是否存在有效了,继续反射一个方法出来(这就是为什么先讲如何反射方法的原因),然后看看下面的结果:
正是前面构造的时候传入的.
从上面,我们以此类推,掌握其他的构造方式的使用.