Como acessar as classes java no pacote padrão?

98

Estou trabalhando agora junto com outros em um projeto grails. Eu tenho que escrever algumas classes Java. Mas eu preciso acessar um objeto pesquisável criado com o groovy. Parece que este objeto deve ser colocado no pacote padrão.

Minha pergunta é: Existe uma maneira de acessar este objeto no pacote padrão de uma classe Java em um pacote nomeado?

Mnementh
fonte

Respostas:

129

Você não pode usar classes no pacote padrão de um pacote nomeado.
( Tecnicamente, você pode, conforme mostrado na resposta de Sharique Abdullah por meio da API de reflexão, mas as classes do namespace não nomeado não estão no escopo em uma declaração de importação )

Antes do J2SE 1.4, você podia importar classes do pacote padrão usando uma sintaxe como esta:

import Unfinished;

Isso não é mais permitido . Portanto, para acessar uma classe de pacote padrão de dentro de uma classe em pacote, é necessário mover a classe de pacote padrão para um pacote próprio.

Se você tiver acesso à fonte gerada pelo groovy, algum pós-processamento é necessário para mover o arquivo para um pacote dedicado e adicionar esta diretiva "pacote" em seu início.


Atualização de 2014: bug 6975015 , para JDK7 e JDK8, descreve uma proibição ainda mais rígida contra importação de pacote sem nome.

A TypeNamedeve ser o nome canônico de um tipo de classe, tipo de interface, tipo de enum, ou tipo de anotação.
O tipo deve ser um membro de um pacote nomeado ou um membro de um tipo cujo tipo mais externo lexicalmente envolvente é um membro de um pacote nomeado , ou ocorrerá um erro em tempo de compilação .


Andreas aponta nos comentários :

"por que [o pacote padrão] está lá em primeiro lugar? erro de design?"

Não, é deliberado.
JLS 7.4.2. Pacotes sem nome diz: "Pacotes sem nome são fornecidos pela plataforma Java SE principalmente por conveniência ao desenvolver aplicativos pequenos ou temporários ou apenas quando o desenvolvimento está começando".

VonC
fonte
7
Como já expliquei a outras pessoas antes, o pacote padrão é um cidadão de segunda classe no mundo Java. Apenas não faça isso. :-)
Chris Jester-Young
1
Parece que tenho que aprender Groovy (em um projeto com muito tempo limitado) ou código no pacote padrão. :-(
Mnementh
11
@ ChrisJester-Young se sim, por que está lá em primeiro lugar? erro de design?
Pacerier,
Por que foi suspenso?
Suzan Cioc
@SuzanCioc, você quer dizer: "por que depois de J2SE1.4, você não consegue mais acessar o pacote padrão?"
VonC de
61

Na verdade, você pode.

Usando a API de reflexões você pode acessar qualquer classe até agora. Pelo menos consegui :)

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

String fooReturned = (String)fooMethod.invoke(fooClass.newInstance(), "I did it");
Holger
fonte
Para Scala, o seguinte 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
Ótima resposta, +1. Como a pergunta era legal, no entanto, você pode usar a digitação de pato (como fita adesiva, eu acho) ...Class.forName("FooBar").newInstance().fooMethod("I did it")
Bill K
7

Use jarjar para recompactar o arquivo jar com a seguinte regra:

rule * <target package name>.@1

Todas as classes no pacote padrão do arquivo jar de origem serão movidas para o pacote de destino, portanto, podem acessar.

Sean
fonte
4
uma demonstração de como usar o jarjar seria ótimo
BiGGZ
@BiGGZ: Consulte o arquivo README.md no repositório github jarjar para ver como usar o jarjar com o ant, gradle ou a linha de comando.
Lucidiot
3

Você pode usar pacotes no Groovycódigo e as coisas funcionarão muito bem.

Pode significar uma pequena reorganização do código grails-appe um pouco mais difícil no início, mas em um grande projeto grails, faz sentido organizar as coisas em pacotes. Usamos a convenção de nomenclatura de pacote padrão Java com.foo.<app>.<package>.

Ter tudo no pacote padrão se torna um obstáculo à integração, como você está descobrindo.

Os controladores parecem ser o único artefato Grails (ou artefato) que resiste a ser colocado em um pacote Java. Provavelmente ainda não descobri o Conventionque fazer. ;-)

Ken Gentil
fonte
0

só para completar a ideia:

De dentro do pacote padrão, você pode acessar objetos residentes em pacotes nomeados.

Duracell De Monaco
fonte