In Neal Gafter's "super type token" pattern (http://gafter.blogspot.com/2006/12/super-type-tokens.html), an anonymous object was used to pass in the parameterized type :
class ReferenceType<T>{}
/* anonymous subclass of "ReferenceType" */
ReferenceType<List<Integer>> referenceType = new ReferenceType<List<Integer>>(){
};
Type superClass = b.getClass().getGenericSuperclass();
System.out.println("super type : " + superClass);
Type genericType = ((ParameterizedType)superClass).getActualTypeArguments()[0];
System.out.println("actual parameterized type : " + genericType);
Then result is :
super type : com.superluli.test.ReferenceType<java.util.List<java.lang.Integer>>
actual parameterized type : java.util.List<java.lang.Integer>
My question is, what the magic does the anonymous object "referenceType" do to make it work? If I define a explicit subclass of "ReferenceType" and use it instead of the anonymous style, it doesn't as expected.
class ReferenceType<T>{}
class ReferenceTypeSub<T> extends ReferenceType<T>{}
/* explicitly(or, named) defined subclass of "ReferenceType" */
ReferenceType<List<Integer>> b = new ReferenceTypeSub<List<Integer>>();
Type superClass = b.getClass().getGenericSuperclass();
System.out.println("super type : " + superClass);
Type genericType = ((ParameterizedType)superClass).getActualTypeArguments()[0];
System.out.println("actual parameterized type : " + genericType);
The result is :
super type : com.superluli.test.ReferenceType<T>
actual parameterized type : T
Anonymous classes enable you to make your code more concise. They enable you to declare and instantiate a class at the same time. They are like local classes except that they do not have a name. Use them if you need to use a local class only once.
In Java, a class can contain another class known as nested class. It's possible to create a nested class without giving any name. A nested class that doesn't have any name is known as an anonymous class. An anonymous class must be defined inside another class. Hence, it is also known as an anonymous inner class.
A local inner class consists of a class declared within a method, whereas an anonymous class is declared when an instance is created. So the anonymous class is created on the fly or during program execution.
Anonymous object in Java means creating an object without any reference variable. Generally, when creating an object in Java, you need to assign a name to the object. But the anonymous object in Java allows you to create an object without any name assigned to that object.
This
ReferenceType<List<Integer>> referenceType = new ReferenceType<List<Integer>>(){
is equivalent to
public class AnonymousReferenceType extends ReferenceType<List<Integer>> {}
...
ReferenceType<List<Integer>> referenceType = new AnonymousReferenceType();
The hack works around Class#getGenericSuperclass()
which states
Returns the
Type
representing the direct superclass of the entity (class, interface, primitive type or void) represented by this Class. If the superclass is a parameterized type, theType
object returned must accurately reflect the actual type parameters used in the source code. The parameterized type representing the superclass is created if it had not been created before. See the declaration ofParameterizedType
for the semantics of the creation process for parameterized types. If thisClass
represents either the Object class, an interface, a primitive type, orvoid
, thennull
is returned. If this object represents an array class then theClass
object representing theObject
class is returned.
In other words, the superclass of AnonymousReferenceType
is a ParameterizedType
representing ReferenceType<List<Integer>>
. This ParameterizedType
has an actual type argument and that is a List<Integer>
which is what appears in the source code.
In your second example, which is not the same as your first,
class ReferenceType<T>{}
class ReferenceTypeSub<T> extends ReferenceType<T>{}
the super class (super type) of ReferenceTypeSub
is a ReferenceType<T>
which is a ParameterizedType
where the actual type argument is a TypeVariable
named T
, which is what appears in the source code.
To answer your question, you don't need an anonymous class. You just need a sub class which declares the type argument you want to use.
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