Java反射(二)Constructor

Java中Constructor类表示类的构造器,得到一个Constructor对象一般要通过Class对象的getConstructor(Class<?>...)方法,通过参数列表中类的顺序和类型来决定得到的是哪个重载的构造器,

比如

Constructor constructor=String.class.getConstructor(StringBuffer.class);
		String str=(String) constructor.newInstance(stringBuffer);
就相当于调用

str=new String(stringBuffer);
无参的构造器构造对象

Constructor constructor=String.class.getConstructor();
		String str=(String) constructor.newInstance();

相当于

str=new String();

也相当于

str=String.class.newInstance();
这里要格外注意的一点——newInstance参数列表是一个Object类型的可变参数,这是从java jdk1.5开始的用法,而在这之前要传参数只能用一个Class数组,新的JDK也兼容了这种用法,正是因为这种兼容会导致一些奇怪的问题。

比如我们想得到String(byte[] bytes,String charset)这个重载的构造器时,我们可以用可变参数这么做

Constructor constructor=String.class.getConstructor(byte[].class,String.class);
		String str=(String) constructor.newInstance("data".getBytes(),"utf-8");
		System.out.println(str);
也可以用Class[]数组这么做

Class[] clses={byte[].class,String.class};
		Constructor constructor=String.class.getConstructor(clses);
		Object[] params={"data".getBytes(),"utf-8"};
		String str=(String) constructor.newInstance(params);
		System.out.println(str);
这个例子很正常,那我们看一个能引起异常的例子:

我们想用URLClassLoader(URL[] urls)这个构造器实例化一个urlClassLoader,我们这么写代码:

Constructor constructor=URLClassLoader.class.getConstructor(URL[].class);
		URL[] urls={new URL("http://www.baidu.com/"),new URL("http://www.tencent.com/")};
		URLClassLoader urlClassLoader=(URLClassLoader) constructor.newInstance(urls);
看上去没问题吧,一运行就错了,异常是

Exception in thread "main" java.lang.IllegalArgumentException: wrong number of arguments

现在我们重新审视这段代码,在第三行new Instance(urls)这里,我们以为urls这一个参数,可按jdk1.5之前的解析方法,会把这个urls拆开,拆出了两个URL对象而不是一个URL[]数组对象,这就是兼容低版本jdk带来的潜在错误,解决方法有两种:

  1. 把urls强制转换成Object,这意思就是告诉编译器,这是一个对象,不要拆开,即
    URLClassLoader urlClassLoader=(URLClassLoader) constructor.newInstance((Object)urls);

  2. 另一种方法是把urls再包装到一个Object数组中,让编译器拆开他,拆开一层后就是我们的那一个数组对象了,即
    URLClassLoader urlClassLoader=(URLClassLoader) constructor.newInstance(new Object[]{urls});








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值