2011-07-29 32 views
10

¿Es posible importar y usar dos clases diferentes con el mismo nombre y paquete en Java?¿Es posible usar dos clases de Java con el mismo nombre y el mismo paquete?

Por ejemplo, supongamos que tengo dos clases llamadas "com.foo.Bar" que son ligeramente diferentes. Me gustaría poder usar ambas cosas, pero tengo una restricción (debido a estúpida mierda reflexiva) que me obliga a mantener los nombres y los paquetes iguales.

¿Hay alguna característica de Java que me permita importar y aislar cada una de estas clases?

Para elaborar, cambié mis esquemas avro de forma que nunca deberían haber sido cambiados (¡Uy!) Y ahora me gustaría volver atrás y cambiar los viejos archivos avro que no se pueden leer con mi nuevo esquema en archivos que mi nuevo esquema puede leer. Parece que Avro te obliga a utilizar una clase y un nombre de paquete específicos para cargar los archivos.

+0

Es un error en tiempo de compilación si el nombre de un tipo de nivel superior aparece como el nombre de cualquier otra clase de nivel superior o tipo de interfaz declarado en el mismo paquete. – roshan

Respuesta

5

No, los paquetes de Java se usan precisamente para evitar ese problema.

+1

No creo que la idea de la clase contenedora funcione. Deje que las 2 clases con nombre idéntico sean C1 y C2; y sus respectivas envolturas W1 y W2. El cargador de clases (1) cargará W1 lo que causará que (2) cargue C1. Entonces el cargador de clases (3) cargará W2. Pensará que ya cargó C2 (debido a nombres idénticos) y tu clase W2 ajustará C1. – emory

0

No hay espacios de nombres en Java, solo en C#, así que supongo que quiere decir paquetes. Solo puede haber un nombre completamente calificado por proyecto.

0

Técnicamente se puede hacer utilizando algunos trucos de bajo nivel como la reescritura del código de nivel de bytes. Por lo que yo sé los diferentes Crypter java/encriptadores trabajar así - tienen una gran cantidad de clases llamada A.class B.class C.class etc.

+0

No tiene que ser de bajo nivel o engaño. Las instancias separadas de cargador de clases es el camino a seguir. – Mishax

0

Si realmente definitivamente necesidad hacer algo como esto, puedes lograrlo usando diferentes cargadores de clases y posiblemente reflejos.

Esta no es la forma en que funciona Java y no está permitido a propósito; no deberías estar haciendo cosas estúpidas que arruinarán las cosas para ti.

6

Sí, sí. Debería implementar su propio Classloader y jugar algunos juegos para poder acceder a ambos durante el tiempo de ejecución.

Estoy seguro de que esto es posible, porque me encontré con un problema muy difícil de depurar donde alguien tenía un cargador de clases raro en su producto que estaba estropeando cargar bibliotecas y proporcionar 2 versiones diferentes del mismo archivo de 2 versiones diferentes de la biblioteca

Sin embargo, esto suena como una mala idea INCREÍBLE. Volvería y encontraría una manera diferente de arreglar su problema. Esto solo traerá dolor de corazón en el largo plazo. Diablos, probablemente ya lo sea, mientras investigas los cargadores de clases.

EDITAR: Para ser específico, no puede "importar" ambos. Pero puedes acceder a ambos en tiempo de ejecución.

+0

Creo que solo necesita tantas instancias de cargador de clases separadas (una de las cuales puede ser el cargador de clases de arranque) como quiera tener referencias a las clases del mismo nombre. En realidad, no necesita escribir su propio cargador de clases para eso. – Mishax

0

Me parece que necesita definir sus firmas de método en una interfaz llamada com.foo.Bar. A continuación, proporcione dos implementaciones concretas diferentes de la interfaz (por ejemplo, com.foo.DefaultBar y com.foo.SpecialBar). De esta manera, puede programar contra el tipo de interfaz y cambiar entre las dos implementaciones diferentes según sea necesario.

¿Puede explicar lo que quiere decir "basura reflexiva"? Eso puede proporcionar una idea de su problema exacto.

No te metas con el cargador de clase o cualquier otro truco de bajo nivel. La mejor manera de resolver estos problemas es tener un diseño claro en primer lugar que cualquiera pueda entender.

+1

Cambiamos nuestro esquema avro de forma que deberíamos tener, así que estoy tratando de escribir un trabajo hadoop para arreglar los archivos que están usando los esquemas anteriores. Avro parece forzarte a utilizar la misma clase y nombre de paquete. – guidoism

0

Como ya se ha mencionado escribir su propio cargador de clases o utilizar adicionalmente un marco OSGi como Equinox, que hace la carga de clases para usted

1

sí lo es. Requiere que haga su propio ClassLoader, aunque

¡Hice un demo de eso en github!

Cuestiones relacionadas