Pregunta

Tengo el siguiente código:

class SuperClass {
    public static String getName() { return "super"; }
}

class SubClass extends SuperClass {
    public static String getName() { return "sub"; }
}

public class Dummy<T extends SuperClass> {
    public void print() {
        System.out.println("SuperClass: " + SuperClass.getName());
        System.out.println("SubClass: " + SubClass.getName());
        System.out.println("T: " + T.getName());
    }
    public static void main(String[] args) {
        new Dummy<SubClass>().print();
    }
}

Este código genera la siguiente:

SuperClass: super
SubClass: sub
T: super

Mi pregunta es: ¿Por qué no T.getName () devuelve el valor de SubClass.getName ()? Después de todo, he especificado que T == subclase. O son función estática llama no válido para las referencias genéricas?

Muchas gracias de antemano!

¿Fue útil?

Solución

Esto no es sólo una cuestión acerca de los genéricos.

Si usted dice:

SuperClass obj = new SubClass();
System.out.println(obj.getName());

También obtendrá "super". No hay métodos estáticos "polimórficos".

En su caso, todo el compilador sabe de T es que se extienda SuperClass, por lo que llamará SuperClass.getName().

Otros consejos

A diferencia de las plantillas de C ++, Java genéricos de trabajo por tipo de borrado, por lo que sólo genera una clase para todos los valores de T, y traduce todas las referencias al tipo SuperClass en esta clase al tipo súper de Dummy<SubClass>.print(), en SubClass este caso, a continuación, utiliza despacho virtual para proporcionar la varianza para las llamadas a métodos de objetos, y despacho estática a las llamadas a métodos estáticos.

Así que cuando lo hace Dummy, el compilador no hace reemplazar un mundial de <=> con <=> en <=>. Todo el compilador hace es comprobar que los usos de <=> como un argumento o escribe el regreso en los métodos de <=> son <=>. No hay cambio a cualquier código dentro <=>, por lo que el mismo método estático <=> se llama a lo <=> es.

Si desea un comportamiento diferente en una clase genérica dependiendo del tipo parametrizado, hay que pasar un objeto de ese tipo y utilizar un método virtual, o pasar en la clase para el tipo y uso reflexión.

Cuando instanciado la clase con "nueva simulada ()" que llamó el constructor por defecto que en realidad no establece nada. Cuando el método de impresión fue llamado, la máquina virtual vio que el tipo de T, como se declara en la declaración de clase, es SuperClass; A continuación, llama al método estático en esta clase.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top