如何在Java中实例化泛型?
我使用java.util.Properties
,在我的应用程序中添加了易于阅读的配置文件,并试图在该文件周围添加包装器,以简化类型转换。具体来说,我希望返回的值从提供的默认值开始“继承”它的类型。到目前为止,这是我得到的:
protected <T> T getProperty(String key, T fallback) { String value = properties.getProperty(key);
if (value == null) {
return fallback;
} else {
return new T(value);
}
}
(完整示例来源。)
getProperty("foo",
true)不管是否从属性文件中读取返回值,from的返回值都是一个布尔值,对于字符串,整数,双精度数和&c而言,返回值都类似。当然,上面的代码片段实际上并没有编译:
PropertiesExample.java:35: unexpected typefound : type parameter T
required: class
return new T(value);
^
1 error
我做错了吗,还是我只是试图做一些无法完成的事情?
用法示例:
// 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);
}
回答:
由于类型擦除,您无法实例化通用对象。通常,您可以保留对Class
表示该类型的对象的引用,并使用它来调用newInstance()
。但是,这仅适用于默认构造函数。由于要使用带参数的构造函数,因此需要查找Constructor
对象并将其用于实例化:
protected <T> T getProperty(String key, T fallback, Class<T> clazz) { String value = properties.getProperty(key);
if (value == null) {
return fallback;
} else {
//try getting Constructor
Constructor<T> 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
}
}
}
但是,看到实现此目标有多大麻烦,包括使用反射的性能成本,值得首先研究其他方法。
如果您绝对需要采用这种方法,并且T
仅限于编译时已知的一组不同类型,则可以选择保留s 的静态Map
值Constructor
,该静态值在启动时加载-
这样,您就不必动态在每次调用此方法时查找它们。例如,使用静态块填充的Map<String,
Constructor<?>>or 。Map<Class<?>,
Constructor<?>>
以上是 如何在Java中实例化泛型? 的全部内容, 来源链接: utcz.com/qa/410281.html