I understand generics when it comes to collections. But what does it mean in the case of the Class<T>
class? When you instantiate a Class
object, there's only one object. So why the T
parameter? What is it specifying? And why is it necessary (if it is)?
相关问题
- Delete Messages from a Topic in Apache Kafka
- Jackson Deserialization not calling deserialize on
- How to maintain order of key-value in DataFrame sa
- StackExchange API - Deserialize Date in JSON Respo
- Difference between Types.INTEGER and Types.NULL in
The answer by dasblinkenlight already demonstrated one of the main uses of this parameter. There is one more aspect I consider relevant: using that parameter, you can restrict the kind of class you want to pass at a given location. So e.g.
means that
cls
may be any class implementing theNumber
interface. This can help catching certain errors at compile time, and makes class argument requirements more explicit.Perhaps a comparison to the case without generics is in order
As you can see, not having
T
as an argument would require a number of explicit casts, as the corresponding methods would have to returnObject
instead ofT
. IfFoo
itself is a generic type argument, then all those casts would be unchecked, resulting in a sequence of compiler warnings. You can suppress them, but the core issue remains: the compiler cannot check the validity of these casts unless you properly use the type argument.In Java there's a single metaclass:
Class
. Its instances (only one per type exists) are used to represent classes and interfaces, therefore theT
inClass<T>
refers to the type of the class or interface that the current instance ofClass
represents.Type parameter
<T>
has been added tojava.lang.Class
to enable one specific idiom1 - use ofClass
objects as type-safe object factories. Essentially, the addition of<T>
lets you instantiate classes in a type-safe manner, like this:Type parameter
<T>
represents the class itself, enabling you to avoid unpleasant effects of type erasure by storingClass<T>
in a generic class or passing it in as a parameter to a generic method. Note thatT
by itself would not be sufficient to complete this task2: the type ofT
is erased, so it becomesjava.lang.Object
under the hood.Here is a classic example where
<T>
parameter of the class becomes important. In the example below, Java compiler is able to ensure type safety, letting you produce a typed collection from a SQL string and an instance ofClass<T>
. Note that the class is used as a factory, and that its type safety can be verified at compile time:Since Java erases the type parameter, making it a
java.lang.Object
or a class specified as the generic's upper bound, it is important to have access to theClass<T>
object inside theselect
method. SincenewInstance
returns an object of type<T>
, the compiler can perform type checking, eliminating a cast.1
SUNOracle has published a good article explaining all this.2 This is different from implementations of generics without type erasure, such as one in .NET.
3 Java Generics tutorial by Oracle.
The use of generics in the Class type is top define the type of class. If I have ' Class obj' my object obj can holds only children of Charsequence. This is an optional argument. I'm often put an '?' to avoid warnings from the Eclipse IDE if I don't need an specific type of class.