En Java, puede definir varias clases de nivel superior en un solo archivo, siempre que, como máximo, una de ellas sea pública (consulte JLS §7.6 ). Ver abajo por ejemplo.
¿Hay un nombre para esta técnica ordenada (análogo a
inner
,nested
,anonymous
)?El JLS dice que el sistema puede imponer la restricción de que estas clases secundarias no pueden ser
referred to by code in other compilation units of the package
, por ejemplo, no pueden tratarse como paquetes privados. ¿Es eso realmente algo que cambia entre las implementaciones de Java?
por ejemplo, PublicClass.java:
package com.example.multiple;
public class PublicClass {
PrivateImpl impl = new PrivateImpl();
}
class PrivateImpl {
int implementationData;
}
Respuestas:
Mi nombre sugerido para esta técnica (incluidas múltiples clases de nivel superior en un solo archivo fuente) sería "desastre". En serio, no creo que sea una buena idea, en su lugar usaría un tipo anidado en esta situación. Entonces todavía es fácil predecir en qué archivo fuente está. Sin embargo, no creo que haya un término oficial para este enfoque.
En cuanto a si esto realmente cambia entre implementaciones, lo dudo mucho, pero si evita hacerlo, en primer lugar, nunca tendrá que preocuparse :)
fuente
public int[] foo(int x)[] { return new int[5][5]; }
tan bien, aunque sea válido).javac no prohíbe esto activamente, pero tiene una limitación que significa que nunca querrá referirse a una clase de nivel superior de otro archivo a menos que tenga el mismo nombre que el archivo en el que se encuentra.
Supongamos que tiene dos archivos, Foo.java y Bar.java.
Foo.java contiene:
Bar.java contiene:
Digamos también que todas las clases están en el mismo paquete (y los archivos están en el mismo directorio).
¿Qué sucede si Foo.java se refiere a Baz pero no a Bar e intentamos compilar Foo.java? La compilación falla con un error como este:
Esto tiene sentido si lo piensas. Si Foo.java se refiere a Baz, pero no hay Baz.java (o Baz.class), ¿cómo puede saber javac en qué archivo fuente buscar?
Si, en cambio, le dice a javac que compile Foo.java y Bar.java al mismo tiempo, o incluso si previamente compiló Bar.java (dejando la clase Baz.class donde javac puede encontrarlo), entonces este error desaparece. Sin embargo, esto hace que su proceso de construcción se sienta muy poco confiable y poco fiable.
Debido a que la limitación real, que es más como "no se refiere a una clase de nivel superior de otro archivo a menos que tenga el mismo nombre que el archivo en el que se encuentra o que también se refiera a una clase que está en ese mismo archivo que se llama lo mismo que el archivo "es un poco difícil de seguir, la gente suele seguir la convención mucho más directa (aunque más estricta) de simplemente poner una clase de nivel superior en cada archivo. Esto también es mejor si alguna vez cambia de opinión acerca de si una clase debe ser pública o no.
A veces hay una buena razón por la cual todos hacen algo de una manera particular.
fuente
Creo que simplemente llamas
PrivateImpl
lo que es: anon-public top-level class
. También puedes declararnon-public top-level interfaces
también.por ejemplo, en otra parte de SO: clase de nivel superior no pública versus clase anidada estática
En cuanto a los cambios en el comportamiento entre versiones, hubo una discusión sobre algo que "funcionó perfectamente" en 1.2.2. pero dejó de funcionar en 1.4 en el foro de sun: Compilador de Java: no se pueden declarar clases de nivel superior no públicas en un archivo .
fuente
non-public top level class
ser la única clase en un archivo, por lo que no aborda la multiplicidad.secondary top level types
.Puedes tener tantas clases como desees así
fuente
Demostración de archivo único de varias clases.
No conozco ninguno que no tenga esa restricción: todos los compiladores basados en archivos no le permitirán referirse a las clases de código fuente en archivos que no tienen el mismo nombre que la clase. (si compila un archivo de varias clases y coloca las clases en la ruta de clase, cualquier compilador las encontrará)
fuente
Según Effective Java 2nd edition (Item 13):
La clase anidada puede ser estática o no estática en función de si la clase miembro necesita acceso a la instancia de cierre (Elemento 22).
fuente
Sí, puede, con miembros públicos estáticos en una clase pública externa, así:
y otro archivo que hace referencia a lo anterior:
ponlos en la misma carpeta. Compilar con:
y correr con:
fuente
Solo para su información, si está utilizando Java 11+, hay una excepción a esta regla: si ejecuta su archivo java directamente ( sin compilación ). En este modo, no hay restricción en una sola clase pública por archivo. Sin embargo, la clase con el
main
método debe ser la primera en el archivo.fuente
No. No puedes. Pero es muy posible en Scala:
fuente