采取以下措施:
public Class<List<String>> getObjectType() {
// what can I return here?
}
我可以从这个满足泛型和编译的方法返回什么类文字表达式? List.class
将无法编译,List.<String>class
也不会编译。
如果您想知道“为什么”,我正在编写Spring FactoryBean<List<String>>
的实现,这需要我实现Class<List<String>> getObjectType()
。但是,这是不是一个Spring问题。
编辑:SpringSource的权力听到了我的哀悼,因此Spring 3.0.1的返回类型getObjectType()
已更改为Class<?>
,这可以很好地避免这个问题。
答案 0 :(得分:42)
您可以随时投射到您需要的内容,例如
return (Class<List<String>>) new ArrayList<String>().getClass();
或
return (Class<List<String>>) Collections.<String>emptyList().getClass();
但我认为那不是你追求的。它有效,有警告,但它并不完全“漂亮”。
我刚发现了这个
为什么没有通配符参数化类型的类文字?
因为通配符参数化类型没有确切的运行时类型表示。
因此,施法可能是唯一的方法。
答案 1 :(得分:15)
你永远不应该使用构造Class<List<String>>
。它是荒谬的,应该用Java产生警告(但不是)。类实例始终代表原始类型,因此您可以拥有Class<List>
;而已。如果你想要某些东西来表示像List<String>
这样的具体泛型类型,你需要一个像Guice一样的“超类型令牌”:
http://google-guice.googlecode.com/git/javadoc/com/google/inject/TypeLiteral.html
答案 2 :(得分:7)
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);
}
答案 3 :(得分:6)
在springframework.org上找到了this link,提供了一些见解。
E.g。
List<String> myList = new ArrayList<String>();
return (Class<List<String>>)myList.getClass();
答案 4 :(得分:5)
您可以像这样实现该方法:
public Class<List<String>> getObjectType() {
return (Class<List<String>>) ((Class)List.class);
}
答案 5 :(得分:2)
答案 6 :(得分:1)
我不确定这是否可行,因为任何类文字都将编译为Class.forName(...)
,因为这在运行时发生,所以没有遗留任何通用信息。
答案 7 :(得分:0)
我不确定,但我提出的以下问题可能与您有关...
答案 8 :(得分:0)
这个怎么样:
public class TestMain {
public static void main(String[] args) throws Exception {
Type type = TestMain.class.getMethod("dummy").getGenericReturnType();
System.out.println("type = " + type);
}
public List<Integer> dummy() {return null;}
}
打印:
type = java.util.List<java.lang.Integer>
答案 9 :(得分:0)
以下方法存在问题:
> public Class<List<String>> getModelType() {
> return (Class<List<String>>) new ArrayList<String>().getClass();
> }
e.g。如果你想测试一个对象是否说类型
org.eclipse.emf.common.util.BasicEList<String>
的类型为
List<String>
基于前面提到的getModelType()方法的结果,例如:
BasicEList<String> fromObject = ...;
if (getModelType().isAssignableFrom(fromObject.getClass())) {
transferFromModelToUi(getModelType().cast(fromObject));
}
它将导致false,而它应该为true,因为两个对象都实现了接口List(因为getModelType()返回List类型的Class对象而不是ArrayList)。
这是一种对我有用的方法(有点麻烦,但在上面的例子中导致正确的结果,可以移动到静态初始化器):
public Class<List<String>> getModelType() {
Class<?> arrayListClass = new ArrayList<String>().getClass();
Class<?>[] interfaces = arrayListClass.getInterfaces();
int index = 0;
for (int i = 0; i < interfaces.length; i++) {
if (interfaces[i].equals(List.class)) {
index = i;
break;
}
}
return (Class<List<String>>) interfaces[index];
}