Java从入门到精通(实例版) 例9.11访问构造方法

  初学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();
	}
	}
}

 

大致代码就是这样了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值