Averiguar si una clase declara explícitamente la implementación de una interfaz particular

Selaron:

Para la interfaz dada IfAcon la clase de Asu aplicación y la clase Bque se extiende A, me gustaría para determinar cuál de las dos clases Ay Bdeclara explícitamente que implementa la interfaz IfA.

Obviamente IfA.class.isAssignableFrom(A.class), y IfA.class.isAssignableFrom(B.class)son a la vez true. Tenía la esperanza de un método como

B.class.declaresInterface(IfA.class) -> false

A.class.declaresInterface(IfA.class) -> true

Pero algo así no existe, ¿verdad?


Antecedentes: de alguna variable Class<? extends IfA> x; sin saber si es A, B o alguna otra clase C que se extenderá A o B ... Me gustaría buscar la clase alta más estupenda que implementa la interfaz. Actualmente estoy implicando una búsqueda un poco feo para esto:

public class SomeTest {

    @org.junit.Test
    public void testIt() {
        assertTrue(IfA.class.isAssignableFrom(A.class));
        assertTrue(IfA.class.isAssignableFrom(B.class));

        Class<? extends IfA> b = B.class;

        Class<?> result = b;

        // somewhat ugly search: from B.class find A.class
        while (IfA.class.isAssignableFrom(result.getSuperclass())) {
            result = result.getSuperclass();
        }

        Object s = result.getSuperclass();

        assertSame(A.class, result);
        assertFalse(IfA.class.isAssignableFrom(result.getSuperclass()));
    }

    interface IfA {
    };

    class A implements IfA {
    };

    class B extends A {
    };
}

¿Hay una manera más explícita de la detección de la interfaz, lo que hace la búsqueda más fácil de entender?

Thomas:

Que yo sepa no hay ningún declaresInterface(...)método en la misma a pesar de que podría haber una biblioteca que proporciona un JDK.

La Classclase en sí proporciona el método una llamada getInterfaces()que según el JavaDoc:

Devuelve los interfaces implementadas directamente por la clase o interfaz que representa este objeto.

Por lo tanto una implementación para boolean declaresInterface(Class<?> clazz, Class<?> interface )debe ser bastante sencillo (aunque el rendimiento puede ser mejorado utilizando algún almacenamiento en caché):

boolean declaresInterface(Class<?> clazz, Class<?> iface) {
  //note: you should add some checks, e.g. for null and correct types
  return Arrays.stream( clazz.getInterfaces() )
               .anyMatch( iface::equals );
}

pruebas:

//true because Integer implements Comparable<Integer>
declaresInterface( Integer.class, Comparable.class ); 

//false, because Integer extends Number and Number implements Serializable
declaresInterface( Integer.class, Serializable.class ); 

Supongo que te gusta

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