Возьмите следующее:
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<?>
, который аккуратно избегает проблемы.
Ты всегда можешь бросить на то, что тебе нужно, как это
return (Class<List<String>>) new ArrayList<String>().getClass();
или
return (Class<List<String>>) Collections.<String>emptyList().getClass();
Но я предполагаю, что это не то, что тебе нужно. Ну, это работает, с предупреждением, но это не совсем "красиво".
Я только что нашел это
Почему нет буквального класса для параметризованных типов wildcard?
Потому что параметризованный тип wildcard не имеет точного представления типа исполнения.
Так что кастинг может быть единственным способом.
] Вы никогда не должны использовать конструкцию []Class
]. Она бессмысленна и должна выдавать предупреждение на Java (но не выдает). Экземпляры классов всегда представляют собой необработанные типы, поэтому вы можете иметь [>[
]Class
]; вот и все. Если вы хотите, чтобы что-то представляло повторяющийся общий тип, например [[
]List
], вам понадобится "токен супертипа", подобный тому, что использует Guice: [
][]http://google-guice.googlecode.com/git/javadoc/com/google/inject/TypeLiteral.html[][
]] Посмотрите эту дискуссию на форумах SUN:[
] [][]http://forums.sun.com/thread.jspa?threadID=5253007[][
] []И ссылку на пост в блоге, в котором описывается работа с использованием "токенов супер-типа":[
] [][]http://gafter.blogspot. com/2006/12/super-type-tokens.html[][
]Я не уверен, возможно ли это вообще, так как любой литерал класса будет скомпилирован в Class.forName(...)
и так как это происходит во время выполнения, то никакой общей информации не осталось.
Я не уверен, но следующий вопрос, который я задал, может иметь отношение к вам...
Найдена эта ссылка на springframework.org, которая дает некоторое представление.
Например
List<String> myList = new ArrayList<String>();
return (Class<List<String>>)myList.getClass();
Существование Class
по своей сути опасно. вот почему:>
// 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);
}