1.11 如何创建已知类型的类文字:Class <List <String >>? | Java Debug 笔记

906 阅读1分钟

本文正在参加「Java主题月 - Java Debug笔记活动」,详情查看 活动链接

Debug 笔记 如何创建已知类型的类文字Class <List >

提问

采取以下措施:

public Class<List<String>> getObjectType() {
    // what can I return here?
}

我可以从该方法返回满足通用性和编译性的类文字表达式吗?

List.class不会编译,也不会List.<String>class

如果您想知道“为什么”,那我在写Spring的实现FactoryBean<List<String>>

这需要我实现 Class<List<String>> getObjectType()

但是,这不是Spring问题。

Spring 3.0.1的返回类型getObjectType()将更改为Class<?>,这可以避免问题。

回答一

您可以随时根据自己的需要进行投射,就像这样

return (Class<List<String>>) new ArrayList<String>().getClass(); 或者 return (Class<List<String>>) Collections.<String>emptyList().getClass();

但是我认为那不是你所追求的。很好,它带有警告,但并不完全是“美丽”的。

我刚发现这个。

为什么通配符参数化类型没有类文字? 因为通配符参数化类型没有确切的运行时类型表示形式。

回答二

您永远不要使用该构造Class<List<String>>。这是荒谬的,应该在Java中产生警告(但不会)。

类实例始终代表原始类型,因此您可以拥有Class<List>; 就是这样。

如果您想用某种东西来表示一个标准化的泛型类型List<String>

则需要一个像Guice使用的“超级类型标记”:

google-guice.googlecode.com/git/javadoc…

回答三

Class<List<String>>本质上是危险的。原因如下:

// This statement generates a warning - for a reason...
Class<List<String>> unsafeListClass = (Class<List<String>>) (Class<?>) List.class;

List<Integer> integerList = new ArrayList<Integer>(); // Ok
integerList.add(42); // Ok

System.out.println(unsafeListClass.isInstance(integerList)); // Prints "true".
List<String> stringList =
   unsafeListClass.cast(integerList); // Succeeds, with no warning!
stringList.add("Hello, World!"); // Also succeeds with no warning

for (int x: integerList) {
    // Compiles without warning, but throws ClassCastException at runtime
    System.out.println(100-x);
}

回答四

您可以像这样实现该方法:

public Class<List<String>> getObjectType() {
    return (Class<List<String>>) ((Class)List.class);
}

文章翻译自Stack Overflow :stackoverflow.com/questions/2…