Pregunta

Digamos que tengo la siguiente clase:

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

¿Cómo comprobaría eso? o es la misma clase que E?

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

No puedo cambiar la firma del método de (Object o) ya que estoy anulando una superclase y no puedo elegir la firma de mi método.

También preferiría no seguir el camino de intentar una conversión y luego detectar la excepción resultante si falla.

¿Fue útil?

Solución

Una instancia de Test no tiene información de qué E está en tiempo de ejecución.Entonces, necesitas pasar un Class<E> al constructor 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;
    }
}

Si desea una relación "instancia de", utilice Class.isAssignableFrom en vez de Class comparación.Nota, E tendrá que ser de un tipo no genérico, por la misma razón Test necesita el Class objeto.

Para ver ejemplos en la API de Java, consulte java.util.Collections.checkedSet y similares.

Otros consejos

El método que siempre he usado se encuentra a continuación.Es un fastidio y un poco feo, pero no he encontrado otro mejor.Debe pasar el tipo de clase durante la construcción, ya que cuando se compilan los genéricos, la información de la clase se pierde.

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);
    }
}

Sólo pude hacerlo funcionar así:

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);  
    }
}

Estaba tratando de hacer lo mismo, y un buen truco que acabo de darme cuenta es que puedes probar una conversión y, si la conversión falla, se generará ClassCastException.Puedes captar eso y hacer lo que sea.

entonces tu método SameClassAs debería verse así:

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 bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top