2009-07-06 13 views
17

Duplicar posible:
How do you find all subclasses of a given class in Java?¿Es posible obtener todas las subclases de una clase?

Hola,

me gustaría obtener una lista de clases que implementan una interfaz en Java en tiempo de ejecución para que pueda hacer un servicio de búsqueda sin tener para codificarlo con fuerza ¿Hay una forma simple de hacer esto? Temo que no.

+1

En C# puede hacer esto iterando a través de la definición de cada clase en un ensamblaje, y probando cada una de estas clases para ver si implementa esa interfaz. – ChrisW

+3

Lamentablemente, la pregunta no es sobre C#. – Tom

+1

¿Duplicado? '¿Cómo se encuentran todas las subclases de una clase determinada en Java?', Http://stackoverflow.com/questions/492184/how-do-you-find-all-subclasses-of-a-given-class-in- java – Jonik

Respuesta

24

La respuesta corta es no.

La respuesta larga es que las subclases pueden aparecer de muchas maneras, lo que básicamente hace que sea imposible encontrarlas categóricamente.

No puede hacerlo en tiempo de ejecución pero no puede encontrar las clases hasta que se carguen y ¿cómo sabe que están cargadas? Podrías escanear cada archivo JAR y de clase, pero eso no es definitivo. Además, hay cosas como cargadores de clases de URL.

Las clases internas (estáticas y no estáticas) son otro caso a considerar. Las clases internas con nombre son más fáciles de encontrar. Las clases internas anónimas son potencialmente mucho más difíciles de encontrar.

También debe tener en cuenta que si una clase tiene subclases, se pueden crear nuevas subclases en un momento posterior.

-2

Si solo carga las clases desde el disco o desde las URL, puede escanear el classpath y buscar las subclases "manualmente".

0

Estoy tratando de razonar a través de la respuesta aquí, así que probablemente estoy equivocado. No tendría sentido que una clase tenga información sobre sus descendientes o subclases porque en cualquier momento alguien puede crear una nueva subclase de su clase. Entonces tendría que recompilar su clase para incluir esta nueva información todo el tiempo. Esto no tiene sentido para el código extensible. Es más probable que una clase contenga información sobre sus antepasados. Entonces, la única solución que puedo ver es que iteres sobre cada clase en tu espacio problemático y revises, pero es más que probable que sea una solución horrible para ti.

1

Siempre puedo crear una nueva subclase para cualquier clase no final, agregar la subclase a la ruta de clase y anular tu intento. Subclases es una proposición abierta.

Lo mejor que puedes hacer es decir que para una ruta de clase determinada, sabes cuáles son las subclases, y para hacer eso, tendrías que escanear cada clase en el classpath.

1

Es bastante simple usando la reflexión. Lea este artículo de JavaWorld

http://www.javaworld.com/javaworld/javatips/jw-javatip113.html

+0

Leí mal la pregunta, el artículo anterior es solo para encontrar subclases que implementan una interfaz dada –

+0

Este código solo escanea un paquete particular Pero las subclases podrían existir en cualquier paquete. En el artículo dice "estamos interesados ​​en todas las clases que implementan una interfaz determinada. No hay información disponible a través de Java Reflection". –

1

La única manera de que sería capaz de hacerlo es caminar por la jerarquía de paquetes para los paquetes disponibles en la ruta de clase comprobando cada clase a través de la reflexión (y eso va a chupar porque' ll cargará efectivamente cada clase, a menos que restrinja su búsqueda a ciertos paquetes).

El problema con este tipo de comportamiento auto-mágico es que resulta difícil cuantificar la aplicación sin ejecutarla, lo que es un dolor de cabeza de mantenimiento. Siempre preferiría ir a la ruta de inyección (a-la Spring) pasando instancias a través de algún tipo de configuración.

0

¿Desea enumerar las clases que implementan una interfaz particular o enumeran las clases que derivan de alguna clase base? Estos son dos temas diferentes. Por lo que sé, sería difícil de implementar ya que las nuevas implementaciones se pueden crear/instalar en una PC en cualquier momento en el futuro. Parece que está intentando crear un método de fábrica para crear una instancia en particular y no desea codificar el nombre de la clase en el código. Generalmente, el uso de un archivo de configuración que enumera todas las clases que implementan la interfaz es el camino a seguir (o se puede usar una base de datos). A medida que las nuevas clases implementan la interfaz, las agrega al archivo de configuración y la fábrica debe elegir el nuevo nombre de clase.

5

debe usar Java ServiceLoader que es una clase incorporada. Es capaz de iterar en tiempo de ejecución sobre todas las implementaciones de servicio (interfaz) conocidas.

Si por algún motivo no lo desea, puede usar ClassLoader.getSystemResources() para iterar sobre todos los recursos; p.ej. si tiene 6 veces la interfaz file/META-INF/com.s obtendrá 6 iteraciones.

Cuestiones relacionadas