Eu tenho dois pacotes no meu projeto: odp.proj
e odp.proj.test
. Existem certos métodos que eu quero que sejam visíveis apenas para as classes nesses dois pacotes. Como posso fazer isso?
EDIT: Se não houver um conceito de subpacote em Java, existe alguma maneira de contornar isso? Eu tenho certos métodos que quero que estejam disponíveis apenas para testadores e outros membros desse pacote. Devo apenas jogar tudo no mesmo pacote? Usar reflexão extensa?
java
package
visibility
encapsulation
Nick Heiner
fonte
fonte
Respostas:
Você não pode. Em Java não existe o conceito de um subpacote, então
odp.proj
eodp.proj.test
são pacotes completamente distintas.fonte
Os nomes dos seus pacotes sugerem que o aplicativo aqui é para teste de unidade. O padrão típico usado é colocar as classes que você deseja testar e o código do teste de unidade no mesmo pacote (no seu caso
odp.proj
), mas em diferentes árvores de origem. Então você colocaria suas aulassrc/odp/proj
e seu código de testetest/odp/proj
.Java possui o modificador de acesso "package", que é o modificador de acesso padrão quando nenhum é especificado (por exemplo, você não especifica public, private ou protected). Com o modificador de acesso "package", apenas as classes
odp.proj
terão acesso aos métodos. Mas lembre-se de que, em Java, não é possível confiar nos modificadores de acesso para impor regras de acesso, porque, com reflexão, qualquer acesso é possível. Modificadores de acesso são meramente sugestivos (a menos que um gerenciador de segurança restritivo esteja presente).fonte
Essa não é uma relação especial entre
odp.proj
eodp.proj.test
- eles são nomeados como aparentemente relacionados.Se o pacote odp.proj.test estiver simplesmente fornecendo testes, você poderá usar o mesmo nome de pacote (
odp.proj
). IDEs como Eclipse e Netbeans criarão pastas separadas (src/main/java/odp/proj
esrc/test/java/odp/proj
) com o mesmo nome de pacote, mas com semântica JUnit.Observe que esses IDEs irão gerar testes para métodos
odp.proj
e criar a pasta apropriada para os métodos de teste que não existem.fonte
Quando faço isso no IntelliJ, minha árvore de fontes fica assim:
fonte
Provavelmente depende um pouco de seus motivos para não exibi-los, mas se o único motivo é que você não deseja poluir a interface pública com as coisas destinadas apenas a testes (ou alguma outra coisa interna), eu colocaria os métodos em um interface pública separada e faça com que os consumidores dos métodos "ocultos" usem essa interface. Não impedirá que outras pessoas usem a interface, mas não vejo razão para que você deva.
Para testes de unidade e, se for possível sem reescrever o lote, siga as sugestões para usar o mesmo pacote.
fonte
Como outros explicaram, não existe um "subpacote" em Java: todos os pacotes são isolados e não herdam nada de seus pais.
Uma maneira fácil de acessar os membros da classe protegidos de outro pacote é estender a classe e substituir os membros.
Por exemplo, para acessar
ClassInA
no pacotea.b
:faça uma classe nesse pacote que substitua os métodos necessários em
ClassInA
:Isso permite que você use a classe de substituição no lugar da classe no outro pacote:
Observe que isso funciona apenas para membros protegidos, que são visíveis para estender classes (herança), e não para membros do pacote privado que são visíveis apenas para sub / estender classes dentro do mesmo pacote. Espero que isso ajude alguém!
fonte
A maioria das respostas aqui afirmou que não existe um subpacote em Java, mas isso não é estritamente preciso. Esse termo está presente na Especificação da Linguagem Java já em Java 6 e provavelmente mais atrás (não parece haver uma versão acessível do JLS para versões anteriores do Java). O idioma em torno dos subpacotes não mudou muito no JLS desde o Java 6.
Java 13 JLS :
O conceito de subpacote é relevante, pois reforça as restrições de nomenclatura entre pacotes e classes / interfaces:
No entanto, essa restrição de nomenclatura é o único significado concedido aos subpacotes pelo idioma:
Nesse contexto, podemos responder à pergunta em si. Como não há explicitamente nenhum relacionamento de acesso especial entre um pacote e seu subpacote, ou entre dois subpacotes diferentes de um pacote pai, não há como, no idioma, tornar um método visível para dois pacotes diferentes da maneira solicitada. Esta é uma decisão de projeto intencional documentada.
O método pode ser tornado público e todos os pacotes (incluindo
odp.proj
eodp.proj.test
) poderão acessar os métodos fornecidos, ou o método pode tornar o pacote privado (a visibilidade padrão) e todo o código que precisa acessá-lo diretamente deve incluir o mesmo (sub) pacote que o métodoDito isto, uma prática muito padrão em Java é colocar o código de teste no mesmo pacote que o código-fonte, mas em um local diferente no sistema de arquivos. Por exemplo, na ferramenta de criação do Maven , a convenção seria colocar esses arquivos de origem e teste em
src/main/java/odp/proj
esrc/test/java/odp/proj
, respectivamente. Quando a ferramenta de construção compila isso, os dois conjuntos de arquivos acabam noodp.proj
pacote, mas apenas ossrc
arquivos são incluídos no artefato de produção; os arquivos de teste são usados apenas no momento da construção para verificar os arquivos de produção. Com essa configuração, o código de teste pode acessar livremente qualquer pacote de código privado ou protegido do código que está testando, pois eles estarão no mesmo pacote.No caso em que você deseja compartilhar o código entre subpacotes ou pacotes irmãos que não é o caso de teste / produção, uma solução que já vi algumas bibliotecas usar é colocar esse código compartilhado como público, mas documentar que ele se destina à biblioteca interna usarem apenas.
fonte
Sem colocar o modificador de acesso na frente do método, você diz que é pacote privado.
Veja o exemplo a seguir.
fonte
Com a classe PackageVisibleHelper e mantenha-a privada antes do congelamento de PackageVisibleHelperFactory, podemos chamar o método launchA (by PackageVisibleHelper) em qualquer lugar :)
fonte