I am puzzled by generics. You can declare a field like:
Class<Collection<String>> clazz = ...
It seems logical that you could assign this field with:
Class<Collection<String>> clazz = Collection<String>.class;
However, this generates an error:
Syntax error on token ">", void expected after this token
So it looks like the .class
operator does not work with generics. So I tried:
class A<S> { } class B extends A<String> { } Class<A<String>> c = B.class;
Also does not work, generates:
Type mismatch: cannot convert from
Class<Test.StringCollection> to Class<Collection<String>>
Now, I really fail to see why this should not work. I know generic types are not reified, but in both cases it seems to be fully type safe without having access to runtime generic types. Anybody an idea?
public class Collections extends Object. This class consists exclusively of static methods that operate on or return collections. It contains polymorphic algorithms that operate on collections, "wrappers", which return a new collection backed by a specified collection, and a few other odds and ends.
The Collections API also provides reusable functionality with a core set of algorithms that operate on List collections. Furthermore, the polymorphic nature of these algorithms enables their operation on a variety of classes that implement a common interface.
What Does Class Mean? A class — in the context of Java — is a template used to create objects and to define object data types and methods. Classes are categories, and objects are items within each category. All class objects should have the basic class properties.
Answer: The list is an interface in Java that extends from the Collection interface. The classes ArrayList, LinkedList, Stack, and Vector implement the list interface.
Generics are invariant.
Object o = "someString"; // FINE! Class<Object> klazz = String.class; // DOESN'T COMPILE! // cannot convert from Class<String> to Class<Object>
Depending on what it is that you need, you may be able to use wildcards.
Class<? extends Number> klazz = Integer.class; // FINE!
Or perhaps you need something like this:
Class<List<String>> klazz = (Class<List<String>>) new ArrayList<String>().getClass(); // WARNING! Type safety: Unchecked cast from // Class<capture#1-of ? extends ArrayList> to Class<List<String>>
As for the non-reified at run-time case, you seem to have a good grasp, but here's a quote anyway, from the Java Tutorials on Generics, The Fine Print: A Generic Class is Shared by All Its Invocations:
What does the following code fragment print?
List <String> l1 = new ArrayList<String>(); List<Integer> l2 = new ArrayList<Integer>(); System.out.println(l1.getClass() == l2.getClass());
You might be tempted to say
false
, but you'd be wrong. It printstrue
, because all instances of a generic class have the same run-time class, regardless of their actual type parameters.
That is, there's no such thing as List<String>.class
or List<Integer>.class
; there's only List.class
.
This is also reflected in the JLS 15.8.2 Class Literals
A class literal is an expression consisting of the name of a class, interface, array, or primitive type, or the pseudo-type void, followed by a
.
and the tokenclass
.
Note the omission of any allowance for generic type parameters/arguments. Furthermore,
It is a compile time error if any of the following occur:
- The named type is a type variable or a parameterized type, or an array whose element type is a type variable or parameterized type.
That is, this also doesn't compile:
void <T> test() { Class<?> klazz = T.class; // DOESN'T COMPILE! // Illegal class literal for the type parameter T }
Basically you can't use generics with class literals, because it just doesn't make sense: they're non-reified.
I agree with the other answers, and would like to explain one point further:
Class objects represent classes that are loaded into the JVM memory. Each class object is actually an in-memory instance of a .class
file. Java generics are not separate classes. They are just a part of the compile-time type-checking mechanism. Therefore, they have no run-time representation in a class object.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With