dimanche 20 avril 2014

Java - puis-je obtenir Clazz.class sur un type générique ? -Débordement de pile


I am trying to invoke EasyMock.isA(Class<T>) on a List<MyType>. Is there a way to do it without warnings?


I've tried the following:


isA(List<MyType>.class);  // doesn't compile
isA(List.<MyType>class); // syntax error on tokens (MyType), misplaced construct
isA(List.class); // This gives a warning: Type safety: The expression of type List needs unchecked conversion to conform to List<MyType>

EDIT:


Jakub HR gave the correct answer. However, for my particular situation where I require this for EasyMock, I can simply use


EasyMock.<List<MyType>>anyObject()



From Effective Java:



There are two minor exceptions to the rule that you should not use raw types in new code, both of which stem from the fact that generic type information is erased at runtime. You must use raw types in class literals. The specification does not permit the use of parameterized types (though it does permit array types and primitive types). In other words, List.class, String[].class, and int.class are all legal, but List<String>.class and List<?>.class are not.





You can get it as below:


Class<T> persistentClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];



Due to type parameters erasure in JVM, you cannot check it (unless you use a custom generic List class which also stores inside an actual Class<?> object of corresponding type (which will have to be provided manually))
This is because at run time there is no way to know generic type parameters — List<String>, List<MyType>, etc. all "get erased" to List<Object> (or just List — no difference) at run time. Maybe you also want to read a more deep example out of the web



I am trying to invoke EasyMock.isA(Class<T>) on a List<MyType>. Is there a way to do it without warnings?


I've tried the following:


isA(List<MyType>.class);  // doesn't compile
isA(List.<MyType>class); // syntax error on tokens (MyType), misplaced construct
isA(List.class); // This gives a warning: Type safety: The expression of type List needs unchecked conversion to conform to List<MyType>

EDIT:


Jakub HR gave the correct answer. However, for my particular situation where I require this for EasyMock, I can simply use


EasyMock.<List<MyType>>anyObject()


From Effective Java:



There are two minor exceptions to the rule that you should not use raw types in new code, both of which stem from the fact that generic type information is erased at runtime. You must use raw types in class literals. The specification does not permit the use of parameterized types (though it does permit array types and primitive types). In other words, List.class, String[].class, and int.class are all legal, but List<String>.class and List<?>.class are not.




You can get it as below:


Class<T> persistentClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];


Due to type parameters erasure in JVM, you cannot check it (unless you use a custom generic List class which also stores inside an actual Class<?> object of corresponding type (which will have to be provided manually))
This is because at run time there is no way to know generic type parameters — List<String>, List<MyType>, etc. all "get erased" to List<Object> (or just List — no difference) at run time. Maybe you also want to read a more deep example out of the web


0 commentaires:

Enregistrer un commentaire