pregunta de la entrevista complicado de los genéricos, comodines y delimitadas getClass ()

Código completo:

¿Cuál es el principio general de "compatibilidad de tipo de parámetro" (sea lo que podemos llamar)?

Class<Base> cls1 = new Derived().getClass();            // ERR

Class<? extends Base> cls2 = new Derived().getClass();  // OK

Class<? super Base> cl3 = new Derived().getClass();      // ERR     


Class<Base> cls4 = new Base().getClass();               // ERR      

Class<? extends Base> cls5 = new Base().getClass();     // OK

Class<? super Base> cls6 = new Base().getClass();       // ERR

Mi respuesta:

Class<Base> cls1LHS en espera exactamente Class<Base> en RHS => Class<? extends Derived>es el error.

Class<? extends Base> cls2según PECS significa que todo lo que recibimos de CLS2 (por iterador o (imaginar es que existe) métodos "get") es la base (por lo que podemos llamar a los métodos de base en lo que tenemos). Class<? extends Derived>es Base en cualquier caso (ya sea derivadas o sus subclases). Por lo tanto, compila.

Class<? super Base> cls3según PECS medios que siempre se puede añadir a la base por CLS3 (imaginar es que existe) método "add / put" - por lo que la colección contiene la base o su superclase. Class<? extends Derived>nunca puede ser la base => Error.


Yo entiendo que los new Derived().getClass()retornos Class<? extends Derived>, igualmente new Base().getClass()rendimientos Class<? extends Base>.

Entiendo que List<? extends String> lst = new ArrayList<String>();está bien y por qué.

Entiendo matriz de covarianza y tipos de retorno covariantes .

Sin embargo, el anterior conjunto de problemas de prueba me gana - No puedo formular reglas que mi razonamiento se guiará por.

PS PECS respuestas no me ayudan a causa principalmente ven el problema en términos de "puedo añadir o poner o ambos en una colección / objeto". El foco de mi pregunta es sobre la compatibilidad de las referencias.

Andy Turner:

Dada una expresión de tipo T, expression.getClass()los rendimientos Class<? extends T>, porque expressiones o bien un To una subclase de T. (En sentido estricto, es un Class<? extends |T|>, donde ||denota el borrado; pero eso es un detalle innecesario en el contexto de esta pregunta, donde ninguno de los valores de Tson genéricos).

Teniendo en cuenta este hecho, expression.getClass()no es ni Class<T>ni Class<? super T>, de la misma manera que una List<? extends Number>no es un List<Number>o una List<? super Number>.

No importa si somethinges new SpecificSomething(): que no es una Class<SpecificSomething>, porque el hecho de que es una nueva instancia (y que está garantizado que ser exactamente una SpecificSomething) no se tiene en cuenta: new SpecificSomething()es una expresión de tipo SpecificSomething, por lo que getClass()devuelve una Class<? extends SpecificSomething>.

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=315724&siteId=1
Recomendado
Clasificación