初学java,看的是java从入门到精通(实例版),实例版的实例比第三版多,感觉内容也更丰富,推荐收藏。
自己看到第九章,9.3.1中的第一个实例,访问构造方法。自己照着代码写了一下,但是运行不起来,下面就来分析下。
第一个MoreConstructor类没有什么问题,主要关注AssessConstructor类。刚开始看它的例子有点不知道它说的什么意思,编写一个测试类AssessConstructor,但是代码里不是完整的。要先创建一个AssessConstructor类,然后将书上的代码包含在一个 main 函数里,这样在myeclipse(本人用的)才能跑起来。
第一个错误就是在第一句,书上代码这样写的
/*Constructor[] declaredConstructors = exampleC.getDeclaredConstructors();*/
这个exampleC是什么鬼不知道。应该改成这样写:
/*Constructor<?>[] declaredConstructors = MoreConstructor.class.getDeclaredConstructors();*/
<?>加不加都没事,不加上会有一个警示的小叹号,无伤大雅。
接下来的代码照抄就行,但是程序执行起来会无限循环这一句:
/*在创建对象时抛出异常,下面执行setAccessible()方法*/
说明程序一直处于while循环中并没有出来。可以新建一个flage变量控制
boolean isFalge = false;
while(example2 && !isFlage)//循环条件
最后在catch中加上一句 isFlage = true;
这样一来就不会进入死循环中,但是运行起来还是效果不对
/*
查看是否允许带有可变数量的参数:true
该构造方法的入口参数类型依次为:
class [Ljava.lang.String;
该构造方法可能抛出的异常类型为:
class java.lang.NumberFormatException
在创建对象时抛出异常,下面执行setAccessible()方法
Exception in thread "main" java.lang.NullPointerException
at ninthChapter.AccessConstructor.main(AccessConstructor.java:49)
*/
参照书上的运行结果是,看出它直接进入第三个构造函数了,但是example2并没有被赋值,是空的。
上网查了一下,原因是通过反射器获得的构造器并不是以书写顺序排序的,应该根据构造器的参数类型来判断是哪个构造器。
看来是顺序问题,所以我将try中的判断条件调整了一下,第一个if的判断条件改为
if(i==2)
其余不变,这样就会首先进入到else中,example2会通过第三个构造函数赋值,然后是第二个,最后才是第一个空的构造函数赋值,这样就避免了第一次example2就为空的情况。程序也可以运行了。
代码如下:
package ninthChapter;
import java.lang.reflect.*;
public class AccessConstructor {
public static void main(String[] args){
//获得所有构造方法
Constructor<?>[] declaredConstructors = MoreConstructor.class.getDeclaredConstructors();
for(int i=0; i < declaredConstructors.length; i++){
Constructor<?> constructor = declaredConstructors[i];//遍历构造方法
System.out.println("查看是否允许带有可变数量的参数:"+constructor.isVarArgs());
System.out.println("该构造方法的入口参数类型依次为:");
@SuppressWarnings("rawtypes")
Class[]parameterTypes = constructor.getParameterTypes(); //获得所有参数类型
for(int j=0; j < parameterTypes.length; j++){
System.out.println(""+ parameterTypes[j]);
}
System.out.println("该构造方法可能抛出的异常类型为:");
//获得所有可能抛出的异常信息类型
@SuppressWarnings("rawtypes")
Class[]exceptionTypes = constructor.getExceptionTypes();
for(int j=0; j < exceptionTypes.length; j++){
System.out.println(""+ exceptionTypes[j]);
}
MoreConstructor example2 = null;
boolean isFlage = false;//加入一个循环标志
while(example2 ==null && !isFlage){
//如果该成员变量的访问权限为private,则抛出异常,即不允许访问
isFlage = false;
//System.out.println("@@@@@@"+ i);
try{
if(i==2){//修改判断条件顺序
example2=(MoreConstructor)constructor.newInstance();
}
else if(i==1){
example2=(MoreConstructor)constructor.newInstance("7",5);
}
else{
Object[]parameters = new Object[]{new String[]{"100","200","300"}};
example2=(MoreConstructor)constructor.newInstance(parameters);
}
}catch(Exception e){
isFlage = true; //赋值为ture
System.out.println("在创建对象时抛出异常,下面执行setAccessible()方法");
constructor.setAccessible(true);//设置为允许访问
}
}
example2.print();
//System.out.println();
}
}
}
大致代码就是这样了。