java实例化泛型,我怎样才能在Java中实例化一个泛型类型?

I've added a human-readable configuration file to my app using java.util.Properties and am trying to add a wrapper around it to make type conversions easier. Specifically, I want the returned value to "inherit" it's type from the provided default value. Here's what I've got so far:

protected T getProperty(String key, T fallback) {

String value = properties.getProperty(key);

if (value == null) {

return fallback;

} else {

return new T(value);

}

}

The return value from getProperty("foo", true) would then be a boolean regardless of whether it was read from the properties file and similarly for strings, integers, doubles, &c. Of course, the above snippet doesn't actually compile:

PropertiesExample.java:35: unexpected type

found : type parameter T

required: class

return new T(value);

^

1 error

Am I doing this wrong, or am I simply trying to do something which can't be done?

Edit: Usage example:

// I'm trying to simplify this...

protected void func1() {

foobar = new Integer(properties.getProperty("foobar", "210"));

foobaz = new Boolean(properties.getProperty("foobaz", "true"));

}

// ...into this...

protected void func2() {

foobar = getProperty("foobar", 210);

foobaz = getProperty("foobaz", true);

}

解决方案

Due to type erasure, you can't instantiate generic objects. Normally you could keep a reference to the Class object representing that type and use it to call newInstance(). However, this only works for the default constructor. Since you want to use a constructor with parameters, you'll need to look up the Constructor object and use it for the instantiation:

protected T getProperty(String key, T fallback, Class clazz) {

String value = properties.getProperty(key);

if (value == null) {

return fallback;

} else {

//try getting Constructor

Constructor constructor;

try {

constructor = clazz.getConstructor(new Class>[] { String.class });

}

catch (NoSuchMethodException nsme) {

//handle constructor not being found

}

//try instantiating and returning

try {

return constructor.newInstance(value);

}

catch (InstantiationException ie) {

//handle InstantiationException

}

catch (IllegalAccessException iae) {

//handle IllegalAccessException

}

catch (InvocationTargetException ite) {

//handle InvocationTargetException

}

}

}

However, seeing how much trouble it is to achieve this, including the performance cost of using reflection, it's worth looking into other approaches first.

If you absolutely need to take this route, and if T is limited to a distinct set of types known at compile time, a compromise would be to keep a static Map of Constructors, which is loaded at startup - that way you don't have to dynamically look them up at every call to this method. For example a Map> or Map, Constructor>>, which is populated using a static block.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值