Pergunta

Digamos que eu tenha a seguinte classe:

public class Test<E> {
    public boolean sameClassAs(Object o) {
        // TODO help!
    }
}

Como eu verificaria isso o é a mesma classe que E?

Test<String> test = new Test<String>();
test.sameClassAs("a string"); // returns true;
test.sameClassAs(4); // returns false;

Não consigo alterar a assinatura do método de (Object o) já que estou substituindo uma superclasse e não consigo escolher a assinatura do meu método.

Eu também preferiria não tentar uma conversão e, em seguida, capturar a exceção resultante se ela falhar.

Foi útil?

Solução

Uma instância de Test não tem informações sobre o que E está em tempo de execução.Então, você precisa passar por um Class<E> para o construtor de Test.

public class Test<E> {
    private final Class<E> clazz;
    public Test(Class<E> clazz) {
        if (clazz == null) {
            throw new NullPointerException();
        }
        this.clazz = clazz;
    }
    // To make things easier on clients:
    public static <T> Test<T> create(Class<T> clazz) {
        return new Test<T>(clazz);
    }
    public boolean sameClassAs(Object o) {
        return o != null && o.getClass() == clazz;
    }
}

Se você quiser um relacionamento "instanceof", use Class.isAssignableFrom ao invés de Class comparação.Observação, E precisará ser um tipo não genérico, pelo mesmo motivo Test precisa do Class objeto.

Para obter exemplos na API Java, consulte java.util.Collections.checkedSet e semelhantes.

Outras dicas

O método que sempre usei está abaixo.É uma dor e um pouco feio, mas não encontrei um melhor.Você tem que passar o tipo de classe na construção, pois quando os genéricos são compilados, as informações da classe são perdidas.

public class Test<E> {
    private Class<E> clazz;
    public Test(Class<E> clazz) {
       this.clazz = clazz;
    }
    public boolean sameClassAs(Object o) {
        return this.clazz.isInstance(o);
    }
}

Eu só poderia fazer funcionar assim:

public class Test<E> {  

    private E e;  

    public void setE(E e) {  
        this.e = e;  
    }

    public boolean sameClassAs(Object o) {  

        return (o.getClass().equals(e.getClass()));  
    }

    public boolean sameClassAs2(Object o) {  
        return e.getClass().isInstance(o);  
    }
}

Eu estava apenas tentando fazer a mesma coisa, e um truque interessante que acabei de perceber é que você pode tentar uma conversão e, se a conversão falhar, ClassCastException será lançada.Você pode pegar isso e fazer o que for.

então seu método sameClassAs deve ser parecido com:

public boolean sameClassAs(Object o) {
    boolean same = false;
    try {
        E t = (E)o;
        same = true;
    } catch (ClassCastException e) {
        // same is false, nothing else to do
    } finally {
        return same;
    }
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top