我刚学会了这种精美的语法
Collections.<String>emptyList()
Run Code Online (Sandbox Code Playgroud)
得到一个空List
的元素,这些元素应该是类型的String
.Java的源代码如下:
public static final List EMPTY_LIST = new EmptyList<Object>();
:
public static final <T> List<T> emptyList() {
return (List<T>) EMPTY_LIST;
}
Run Code Online (Sandbox Code Playgroud)
现在,如果我以这种方式编写一个方法,其中泛型类型没有出现在参数列表中,那么我有什么方法可以访问成为的实际类T
?
我说,到目前为止,我的代码处理方法本来就是这样
private <T> T get(String key, Class<T> clazz) {
// here I can do whatever I want with clazz, e.g.:
return clazz.cast(value);
}
Run Code Online (Sandbox Code Playgroud)
如果我删除了clazz
参数,我将无法做到cast()
.显然我能做到
return (T) value;
Run Code Online (Sandbox Code Playgroud)
但这给了我通常的警告Type safety: Unchecked cast from Object to T
.好的,@SuppressWarnings("unchecked")
在这里有所帮助,但实际上我想用该方法的预期返回类型做一些事情.如果我添加一个局部变量
T retValue;
Run Code Online (Sandbox Code Playgroud)
我必须用一些东西初始化它,null
但没有帮助.在我分配之后
@SuppressWarnings("unchecked")
T retValue = (T) value;
Run Code Online (Sandbox Code Playgroud)
我可以做,例如
retValue.getClass().getName()
Run Code Online (Sandbox Code Playgroud)
但如果演员表失败,我最终没有T
再次提供相关信息.
由于Java(或至少我的Java 6)在运行时不再具有通用信息,因此我目前无法想到这样做的方法.有办法吗?或者我必须坚持我的"旧"方法吗?
请注意,我列出的示例非常简单,没有多大意义.我想在这里做更复杂的事情,但这超出了范围.
如果您希望在运行时使用泛型类型,则需要将其作为字段使用,或者为特定的类型组合创建类型的子类.
例如
List<String> list = new ArrayList<String>() {}; // creates a generic sub-type
final Class type = (Class) ((ParameterizedType) list.getClass()
.getGenericSuperclass()).getActualTypeArguments()[0];
System.out.println(type);
Run Code Online (Sandbox Code Playgroud)
版画
class java.lang.String
Run Code Online (Sandbox Code Playgroud)