Genéricos de Java: Tipo genérico definido como solo tipo de devolución

Estoy buscando un código GXT para GWT y me encontré con este uso de generics que no puedo encontrar otro ejemplo en los tutoriales de Java. El nombre de clase es com.extjs.gxt.ui.client.data.BaseModelData si desea ver todo el código. Estas son las partes importantes:

 private RpcMap map; public  X get(String property) { if (allowNestedValues && NestedModelUtil.isNestedProperty(property)) { return (X)NestedModelUtil.getNestedValue(this, property); } return map == null ? null : (X) map.get(property); } 

X se define en ningún otro lugar de la clase ni en ningún otro lugar de la jerarquía, y cuando pulso “ir a statement” en eclipse, va a la en la firma del método público.

Intenté llamar a este método con los dos ejemplos siguientes para ver qué sucede:

 public Date getExpiredate() { return get("expiredate"); } public String getSubject() { return get("subject"); } 

Comstackn y no muestran errores o advertencias. Pensaría que al menos tendría que hacer un reparto para que esto funcione.

¿Significa esto que los generics permiten un valor de retorno mágico que puede ser cualquier cosa y que explotará en el tiempo de ejecución? Esto parece contrario a lo que se supone que deben hacer los generics. ¿Puede alguien explicarme esto y posiblemente darme un enlace a alguna documentación que lo explique un poco mejor? He revisado el PDF de Sun de 23 páginas sobre generics y cada ejemplo de valor de retorno se define a nivel de clase o en uno de los parámetros ingresados.

El método devuelve un tipo de lo que usted espera que sea ( está definido en el método y no tiene límites).

Esto es muy, muy peligroso ya que no se prevé que el tipo de retorno realmente coincida con el valor devuelto.

La única ventaja que esto tiene es que no tiene que emitir el valor de retorno de dichos métodos de búsqueda generics que pueden devolver cualquier tipo.

Yo diría: use tales constructos con cuidado, porque pierde casi todo tipo de seguridad y gana solo que no tiene que escribir un reparto explícito en cada llamada para get() .

Y sí, esto es magia negra que explota en el tiempo de ejecución y rompe la idea de qué generics deberían lograr.

El tipo está declarado en el método. Eso es que ” ” significa. El tipo tiene un ámbito de solo el método y es relevante para una llamada en particular. El motivo por el que comstack el código de prueba es que el comstackdor intenta determinar el tipo y se quejará solo si no puede. Hay casos en los que tienes que ser explícito.

Por ejemplo, la statement para Collections.emptySet() es

 public static final  Set emptySet() 

En este caso, el comstackdor puede adivinar:

 Set s = Collections.emptySet(); 

Pero si no puede, debe escribir:

 Collections.emptySet(); 

Solo estaba tratando de descubrir lo mismo con una clase GXT. Específicamente, estaba tratando de llamar a un método con la firma de:

 class Model { public  X get(String property) { ... } } 

Para llamar al método anterior desde su código y hacer que emita X en una cadena, hago lo siguiente:

 public String myMethod(Data data) { Model model = new Model(data); return model.get("status"); } 

El código anterior llamará al método get y le dirá que el tipo que devuelve X debe devolverse como una cadena.

En el caso donde el método está en la misma clase que usted, he encontrado que tengo que llamarlo con un “esto”. Por ejemplo:

 this.get("status"); 

Como otros han dicho, esto es bastante descuidado y peligroso por parte del equipo de GXT.

BaseModelData aumenta las advertencias no verificadas una vez comstackdas, porque no es seguro. Usado de esta manera, su código lanzará una ClassCastException en tiempo de ejecución, aunque no tenga ninguna advertencia.

 public String getExpireDate() { return get("expiredate"); } 

Nota interesante, de RpcMap (GXT API 1.2)

encabezado de get:

 public java.lang.Object get(java.lang.Object key) 

Tener un parámetro genérico de allí que se haya desinstalado tiene el mismo efecto, excepto que no tiene que decir “Objeto” por todos lados. Estoy de acuerdo con el otro afiche, esto es descuidado y un poco peligroso.

Sí, esto es peligroso. Normalmente, protegerías este código así:

  getProperty(String name, Class clazz) { X foo = (X) whatever(name); assert clazz.isAssignableFrom(foo); return foo; } String getString(String name) { return getProperty(name, String.class); } int getInt(String name) { return getProperty(name, Integer.class); }