Em Java, você pode definir várias classes de nível superior em um único arquivo, desde que no máximo uma delas seja pública (consulte JLS §7.6 ). Veja abaixo, por exemplo.
Existe um nome arrumado para esta técnica (análogo a
inner
,nested
,anonymous
)?O JLS diz que o sistema pode impor a restrição de que essas classes secundárias não podem ser
referred to by code in other compilation units of the package
, por exemplo, elas não podem ser tratadas como privadas de pacotes. Isso é realmente algo que muda entre implementações Java?
por exemplo, PublicClass.java:
package com.example.multiple;
public class PublicClass {
PrivateImpl impl = new PrivateImpl();
}
class PrivateImpl {
int implementationData;
}
Respostas:
Meu nome sugerido para esta técnica (incluindo várias classes de nível superior em um único arquivo de origem) seria "bagunça". Sério, não acho que seja uma boa ideia - eu usaria um tipo aninhado nessa situação. Ainda é fácil prever em qual arquivo fonte ele está. Não acredito que exista um termo oficial para essa abordagem.
Quanto a saber se isso realmente muda entre implementações - duvido muito, mas se você evitar fazê-lo em primeiro lugar, nunca precisará se preocupar :)
fonte
public int[] foo(int x)[] { return new int[5][5]; }
bem, mesmo que isso é válido.)O javac não proíbe isso ativamente, mas tem uma limitação que praticamente significa que você nunca desejaria consultar uma classe de nível superior de outro arquivo, a menos que tenha o mesmo nome do arquivo em que está.
Suponha que você tenha dois arquivos, Foo.java e Bar.java.
Foo.java contém:
Bar.java contém:
Digamos também que todas as classes estão no mesmo pacote (e os arquivos estão no mesmo diretório).
O que acontece se Foo.java se referir a Baz, mas não Bar, e tentarmos compilar Foo.java? A compilação falha com um erro como este:
Isso faz sentido se você pensar sobre isso. Se Foo.java se referir ao Baz, mas não houver Baz.java (ou Baz.class), como o javac pode saber em qual arquivo de origem procurar?
Se você instruir o javac a compilar Foo.java e Bar.java ao mesmo tempo, ou mesmo se você tiver compilado o Bar.java anteriormente (deixando a classe Baz.classe onde o javac pode encontrá-lo), esse erro desaparecerá. Isso faz com que seu processo de construção pareça muito pouco confiável e esquisito.
Como a limitação real, que é mais parecida com "não se refere a uma classe de nível superior de outro arquivo, a menos que tenha o mesmo nome do arquivo em que está ou você também esteja se referindo a uma classe que está no mesmo arquivo que é nomeado a mesma coisa que o arquivo "é meio difícil de seguir, as pessoas geralmente seguem a convenção muito mais direta (embora mais rigorosa) de apenas colocar uma classe de nível superior em cada arquivo. Isso também é melhor se você mudar de idéia sobre se uma classe deve ser pública ou não.
Às vezes, há realmente uma boa razão pela qual todo mundo faz algo de uma maneira específica.
fonte
Eu acredito que você simplesmente chama
PrivateImpl
o que é: anon-public top-level class
. Você também pode declararnon-public top-level interfaces
também.por exemplo, em outro lugar no SO: classe não pública de nível superior versus classe aninhada estática
Quanto às mudanças de comportamento entre as versões, houve essa discussão sobre algo que "funcionou perfeitamente" no 1.2.2. mas parou de funcionar no 1.4 no fórum da sun: Java Compiler - incapaz de declarar classes de nível superior não públicas em um arquivo .
fonte
non-public top level class
a única classe em um arquivo, para que não lide com a multiplicidade.secondary top level types
.Você pode ter quantas aulas quiser dessa maneira
fonte
Demonstração de arquivo único de várias classes.
Não conheço nenhum que não tenha essa restrição - todos os compiladores baseados em arquivos não permitirão que você se refira às classes de código-fonte em arquivos que não tenham o mesmo nome que a classe. (se você compilar um arquivo com várias classes e colocar as classes no caminho da classe, qualquer compilador as encontrará)
fonte
De acordo com a Effective Java 2nd edition (Item 13):
A classe aninhada pode ser estática ou não estática, com base no fato de a classe membro precisar acessar a instância anexa (Item 22).
fonte
Sim, você pode, com membros estáticos públicos em uma classe pública externa, assim:
e outro arquivo que faz referência ao acima:
coloque-os na mesma pasta. Ajuntar com:
e corra com:
fonte
Apenas para sua informação, se você estiver usando o Java 11+, há uma exceção a esta regra: se você executar o seu arquivo java diretamente ( sem compilação ). Nesse modo, não há restrições para uma única classe pública por arquivo. No entanto, a classe com o
main
método deve ser a primeira no arquivo.fonte
Não. Você não pode. Mas é muito possível em Scala:
fonte