TypeReference usage clarification (#25719)
This change makes TypeReference usage a little bit easier
- Marking it abstract make it so that usages cannot "forget" subclassing (or omitting the { } part). Previously the error message would be confusing as the supertype would be Object.
- Removing the instanceof check and relying on exception since instantiating TypeReference without a type parameter (new TypeReference() ) *is* exceptional as it goes against the intention of this class altogether.
- Added some clarification to the javadoc regarding intended usage, and a link to prior art for further reading.
This commit is contained in:
parent
3692e122ff
commit
cc0665cb6f
|
|
@ -3,36 +3,48 @@
|
|||
|
||||
package com.microsoft.signalr;
|
||||
|
||||
import java.lang.ClassCastException;
|
||||
import java.lang.reflect.Type;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
|
||||
|
||||
/**
|
||||
* A utility for getting a Java Type from a literal Class.
|
||||
* A utility for getting a Java Type from a literal generic Class.
|
||||
*/
|
||||
public class TypeReference<T> {
|
||||
public abstract class TypeReference<T> {
|
||||
|
||||
private final Type type;
|
||||
|
||||
/**
|
||||
* Creates a new instance of {@link TypeReference}.
|
||||
*
|
||||
* To get the Type of Class Foo, use the following syntax:
|
||||
* This class implements Super Type Tokens (Gafter's Gadget) as a way to get a reference to generic types in
|
||||
* spite of type erasure since, sadly, {@code Foo<Bar>.class} is not valid Java.
|
||||
*
|
||||
* To get the Type of Class {@code Foo<Bar>}, use the following syntax:
|
||||
* <pre>{@code
|
||||
* Type fooType = (new TypeReference<Foo>() { }).getType();
|
||||
* Type fooBarType = (new TypeReference<Foo<Bar>>() { }).getType();
|
||||
* }</pre>
|
||||
*
|
||||
* To get the Type of class Foo, use a regular Type Token:
|
||||
* <pre>{@code
|
||||
* Type fooType = Foo.class;
|
||||
* }</pre>
|
||||
*
|
||||
* @see <a href="http://gafter.blogspot.com/2006/12/super-type-tokens.html">Super Type Tokens</a>
|
||||
*/
|
||||
public TypeReference() {
|
||||
Type superclass = getClass().getGenericSuperclass();
|
||||
if (superclass instanceof Class) {
|
||||
throw new RuntimeException("Missing type parameter.");
|
||||
try {
|
||||
this.type = ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
|
||||
} catch (ClassCastException ex) {
|
||||
throw new RuntimeException("TypeReference must be instantiated with a type parameter such as (new TypeReference<Foo<Bar>>() {}).");
|
||||
}
|
||||
this.type = ((ParameterizedType) superclass).getActualTypeArguments()[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the referenced type.
|
||||
* @return The Type encapsulated by this TypeReference
|
||||
*/
|
||||
*/
|
||||
public Type getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue