¿Cómo acceder a las clases de Java en el paquete predeterminado?


98

Ahora estoy trabajando junto con otros en un proyecto de Grails. Tengo que escribir algunas clases de Java. Pero necesito acceso a un objeto de búsqueda creado con groovy. Parece que este objeto debe colocarse en el paquete predeterminado.

Mi pregunta es: ¿Hay alguna forma de acceder a este objeto en el paquete predeterminado desde una clase Java en un paquete con nombre?

Respuestas:


129

No puede usar clases en el paquete predeterminado de un paquete con nombre.
( Técnicamente , puede, como se muestra en la respuesta de Sharique Abdullah a través de la API de reflexión, pero las clases del espacio de nombres sin nombre no están dentro del alcance de una declaración de importación )

Antes de J2SE 1.4, podía importar clases desde el paquete predeterminado usando una sintaxis como esta:

import Unfinished;

Eso ya no está permitido . Entonces, para acceder a una clase de paquete predeterminada desde dentro de una clase empaquetada, es necesario mover la clase de paquete predeterminada a un paquete propio.

Si tiene acceso a la fuente generada por groovy, es necesario un procesamiento posterior para mover el archivo a un paquete dedicado y agregar esta directiva de "paquete" al principio.


Actualización 2014: el error 6975015 , para JDK7 y JDK8, describe una prohibición aún más estricta contra la importación de paquetes sin nombre.

El TypeNamedebe ser el nombre canónico de un tipo de clase, tipo de interfaz, tipo de enumeración, o tipo de anotación.
El tipo debe ser un miembro de un paquete con nombre o un miembro de un tipo cuyo tipo más externo que lo encierra léxicamente es un miembro de un paquete con nombre , o se producirá un error en tiempo de compilación .


Andreas señala en los comentarios :

"¿Por qué [el paquete predeterminado] está ahí en primer lugar? ¿Error de diseño?"

No, es deliberado.
JLS 7.4.2. Paquetes sin nombre dice: "La plataforma Java SE proporciona paquetes sin nombre principalmente para su conveniencia cuando se desarrollan aplicaciones pequeñas o temporales o cuando recién se inicia el desarrollo".


7
Como ya les he explicado a otras personas, el paquete predeterminado es un ciudadano de segunda clase en el mundo Java. Simplemente no hagas eso. :-)
Chris Jester-Young

1
Parece que tengo que aprender Groovy (en un proyecto con mucho tiempo limitado) o código en el paquete predeterminado. :-(
Mnementh

11
@ ChrisJester-Young, si es así, ¿por qué está ahí en primer lugar? error de diseño?
Pacerier

¿Por qué fue desaprobado?
Suzan Cioc

@SuzanCioc quiere decir: "¿por qué después de J2SE1.4, ya no puede acceder al paquete predeterminado?"
VonC

61

De hecho, puedes.

Usando la API de reflexiones puedes acceder a cualquier clase hasta ahora. Al menos pude :)

Class fooClass = Class.forName("FooBar");
Method fooMethod = fooClass.getMethod("fooMethod", String.class);

String fooReturned = (String)fooMethod.invoke(fooClass.newInstance(), "I did it");

Para Scala, el siguiente código funciona:val bar = "hi"; val fooClass = Class.forName("FooClass"); val fooMethod = fooClass.getMethod("foo", classOf[Array[String]]); val fooReturned = fooMethod.invoke(fooClass.newInstance(), Array(bar));
Jus12

2
Gran respuesta, +1. Sin embargo, dado que la pregunta era genial, puede usar la escritura de pato (como la cinta adhesiva, supongo) ...Class.forName("FooBar").newInstance().fooMethod("I did it")
Bill K

7

Use jarjar para volver a empaquetar el archivo jar con la siguiente regla:

rule * <target package name>.@1

Todas las clases en el paquete predeterminado del archivo jar de origen se moverán al paquete de destino, por lo que podrán acceder.


4
una demostración de cómo usar jarjar sería genial
BiGGZ

@BiGGZ: Vea el archivo README.md en el repositorio jarjar github para ver cómo usar jarjar con ant, gradle o la línea de comandos.
Lucidiot

3

Puede usar paquetes en el Groovycódigo y todo funcionará bien.

Puede significar una reorganización menor del código grails-appy un poco de dolor al principio, pero en un proyecto de griales grande, simplemente tiene sentido organizar las cosas en paquetes. Usamos la convención de nomenclatura de paquetes estándar de Java com.foo.<app>.<package>.

Tener todo en el paquete predeterminado se convierte en un obstáculo para la integración, como está descubriendo.

Los controladores parecen ser el único artefacto (o artefacto) de Grails que se resiste a ser incluido en un paquete Java. Probablemente todavía no he descubierto el Conventionpara eso. ;-)


0

solo para completar la idea:

Desde el interior del paquete predeterminado puede acceder a los objetos que residen en paquetes con nombre.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.