Pergunta

Eu tenho o seguinte 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 gera o seguinte:

SuperClass: super
SubClass: sub
T: super

A minha pergunta é: Por que não T.getName () retornar o valor de SubClass.getName ()? Afinal, eu especificado que T == subclasse. Ou função estática chama inválido para referências genéricas?

Muito obrigado antecipadamente!

Foi útil?

Solução

Este não é apenas uma questão sobre os genéricos.

Se você diz:

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

Você também terá "super". Não há métodos estáticos "polimórficas".

No seu caso, tudo o compilador sabe sobre T é que ele estende SuperClass, por isso vai chamar SuperClass.getName().

Outras dicas

Ao contrário de modelos C ++, trabalho Java genéricos por tipo apagamento, por isso só gera uma classe para todos os valores de T, e traduz todas as referências para digitar T nesta classe para o super tipo de T, neste caso SuperClass, em seguida, utiliza expedição virtual para fornecer a variância para chamadas para métodos de objetos, e expedição estática para chamadas para métodos estáticos.

Então, quando você faz Dummy<SubClass>.print(), o compilador não faz uma substituição global de T com SubClass em Dummy. Tudo o compilador faz é verificar se os usos de T como um argumento ou tipo de retorno dos métodos de Dummy são SubClass. Não há nenhuma alteração em qualquer código dentro Dummy, de modo que o mesmo método SuperClass estática é chamado o que quer T é.

Se você quer um comportamento diferente em uma classe genérica, dependendo do tipo parametrizado, você tem passar um objeto desse tipo e usar um método virtual, ou passar na classe para o tipo ea utilização reflexão.

Quando você instanciated a classe com "nova Manequim ()" você chamou o construtor padrão que na verdade não definir nada. Quando o método de impressão foi chamado, a serra VM que o tipo de T, como declarado na declaração de classe, é SuperClass; Em seguida, chama o método estático em sua classe.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top