2012-06-29 21 views
10

De efectiva de Java Segunda edición, artículo 28: "No utilice los tipos de comodines como tipo de retorno En lugar de proporcionar una flexibilidad adicional para los usuarios ya que obligaría a ellos. para usar tipos de comodines en el código del cliente ".¿Por qué TypeToken de guayaba <T> .getRawType() devuelven Clase <? super T> en lugar de clase <T>

public final Class<? super T> getRawType() 

Me acaban de llegar a enfrentarse con comodines genéricos para entender la última advertencia fundido sin control que tengo en un trozo de código que estoy escribiendo y yo no entiendo por qué getRawType() devuelve un tipo de comodín.

class Base<T>{} 
class Child<T> extends Base<T>{} 

public <C> void test (TypeToken<? extends Base<C>> token) { 
    Class<? extends Base<C>> rawType = (Class<? extends Base<C>>) token.getRawType(); 
} 

que tienen que desechar token.getRawType(), ya que devuelve un

Class<? super ? extends Base<C>> 

Respuesta

7

¿Qué pasa si tiene un TypeToken<ArrayList<String>> y desea obtener Class<ArrayList> (que es el tipo sin procesar). Si devolviera Class<T>, devolvería Class<ArrayList<String>> que no es Class<ArrayList> que desee.

+0

Gracias @newacct, esta es la cosa No entendí, pero tiene sentido que ArrayList extienda ArrayList. La clase es descriptiva de lo que está devolviendo aunque, en lo que respecta al código del cliente, también puede devolver la clase , ya que siempre tendrá que emitirla. – MikeB

0

Si el tipo genérico de "señal" es un tipo de clase (es decir, si S en

TypeToken<S> 

es una clase java.lang.reflect.Type), luego TypeToken.getRawType() devolverá el tipo sin formato asociado a S. Será un objeto de Clase, principal de S.

Ver el código fuente de TypeToken.

En algunos casos (como tener múltiples límites), la estrategia implementada no va a funcionar y tener un tipo de prima está bien: el tipo de prima será Object.class

Véase, por ejemplo MoreTypes:

public static Class<?> getRawType(Type type) { 
... 
} else if (type instanceof TypeVariable) { 
    // we could use the variable's bounds, but that'll won't work if there are multiple. 
    // having a raw type that's more general than necessary is okay 
    return Object.class; 

} else { 
... 
} 
+0

He leído la fuente pero todavía no puedo encontrar una situación en la que se devuelve un padre de S. Intenté 'new TypeToken () {}. GetRawType()' pero eso devuelve una clase de WildcardType, no cualquier padre – MikeB

+1

Tenga en cuenta que su enlace 'TypeToken' apunta a la versión gson. Aquí está la versión de Guava: http://code.google.com/p/guava-libraries/source/browse/guava/src/com/google/common/reflect/TypeToken.java –

Cuestiones relacionadas