如何创建已知类型的类文字:Class <List <String >>

ska*_*man 58 java generics jls

请考虑以下事项:

public Class<List<String>> getObjectType() {
    // what can I return here?
}
Run Code Online (Sandbox Code Playgroud)

我可以从这个满足泛型和编译的方法返回什么类文字表达式?List.class不会编译,也不会编译List.<String>class.

如果你想知道"为什么",我正在写一个Spring的实现FactoryBean<List<String>>,这需要我实现Class<List<String>> getObjectType().但是,这不是一个Spring问题.

编辑: SpringSource的权力听到了我的哀悼,因此Spring 3.0.1将返回类型getObjectType()改为Class<?>,这样可以很好地避免问题.

Boz*_*zho 46

你可以随时投射到你需要的东西,就像这样

return (Class<List<String>>) new ArrayList<String>().getClass();
Run Code Online (Sandbox Code Playgroud)

要么

return (Class<List<String>>) Collections.<String>emptyList().getClass();
Run Code Online (Sandbox Code Playgroud)

但我认为这不是你追求的.它有效,有警告,但它并不完全"漂亮".

我刚发现了这个

为什么通配符参数化类型没有类文字?

因为通配符参数化类型没有确切的运行时类型表示.

所以铸造可能是唯一的出路.

  • http://www.angelikalanger.com/GenericsFAQ/FAQSections/ParameterizedTypes.html (4认同)

Kev*_*ion 15

你永远不应该使用这个结构Class<List<String>>.它是荒谬的,应该用Java产生警告(但不是).类实例总是代表原始类型,所以你可以拥有Class<List>; 而已.如果你想要某些东西来代表一个具体的通用类型List<String>,你需要像Guice一样使用的"超类型代币":

http://google-guice.googlecode.com/git/javadoc/com/google/inject/TypeLiteral.html


fin*_*nnw 7

a的存在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);
}
Run Code Online (Sandbox Code Playgroud)


JRL*_*JRL 6

在springframework.org上找到了这个链接,提供了一些见解.

例如

List<String> myList = new ArrayList<String>();
return (Class<List<String>>)myList.getClass();
Run Code Online (Sandbox Code Playgroud)


Sae*_*fam 5

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

public Class<List<String>> getObjectType() {
    return (Class<List<String>>) ((Class)List.class);
}
Run Code Online (Sandbox Code Playgroud)

  • 我喜欢这种方式,因为您不需要创建新实例。 (3认同)
  • 外部铸件是不必要的。你可以这样写:`return (Class)List.class;`,我发现这样更容易阅读。 (2认同)