Respuestas:
La visibilidad predeterminada se conoce como "paquete-privado" (aunque no se puede usar explícitamente), lo que significa que se podrá acceder al campo desde el interior del mismo paquete al que pertenece la clase.
Sin embargo, como señaló mdma, no es cierto para los miembros de la interfaz, para los cuales el valor predeterminado es "público".
El especificador predeterminado depende del contexto.
Para clases y declaraciones de interfaz, el paquete predeterminado es privado. Esto cae entre protegido y privado, permitiendo solo el acceso de clases en el mismo paquete. (protected es así, pero también permite el acceso a subclases fuera del paquete).
class MyClass // package private
{
int field; // package private field
void calc() { // package private method
}
}
Para los miembros de la interfaz (campos y métodos), el acceso predeterminado es público. Pero tenga en cuenta que la declaración de la interfaz en sí misma tiene como valor predeterminado el paquete privado.
interface MyInterface // package private
{
int field1; // static final public
void method1(); // public abstract
}
Si entonces tenemos la declaración
public interface MyInterface2 extends MyInterface
{
}
Las clases que usan MyInterface2 pueden ver field1 y method1 desde la superinterfaz, porque son públicas, aunque no pueden ver la declaración de MyInterface en sí.
/* pp */
) es solo un nombre conveniente para el acceso predeterminado . No es el nombre de JLS.
Si no se proporciona un especificador de acceso, es acceso a nivel de paquete (no hay un especificador explícito para esto) para clases y miembros de clase. Los métodos de interfaz son implícitamente públicos.
La visibilidad predeterminada (sin palabra clave) es paquete, lo que significa que estará disponible para todas las clases ubicadas en el mismo paquete.
Una nota al margen interesante es que protected no limita la visibilidad a las subclases sino también a las otras clases en el mismo paquete
Depende de lo que sea.
Los tipos de nivel superior (es decir, clases, enumeraciones, interfaces y tipos de anotaciones no declarados dentro de otro tipo) son paquetes privados de forma predeterminada. ( JLS §6.6.1 )
En las clases, todos los miembros (es decir, campos, métodos y declaraciones de tipos anidados) y constructores son paquetes privados de forma predeterminada. ( JLS §6.6.1 )
En las enumeraciones, los constructores son privados de forma predeterminada. De hecho, los constructores de enumeración deben ser privados, y es un error especificarlos como públicos o protegidos. Las constantes de enumeración son siempre públicas y no permiten ningún especificador de acceso. Otros miembros de enumeraciones son paquetes privados de forma predeterminada. ( JLS §8.9 )
En interfaces y tipos de anotaciones, todos los miembros (nuevamente, eso significa campos, métodos y declaraciones de tipos anidados) son públicos por defecto. De hecho, los miembros de las interfaces y los tipos de anotaciones deben ser públicos y es un error especificarlos como privados o protegidos. ( JLS §9.3 a 9.5 )
Las clases locales son clases con nombre declaradas dentro de un método, constructor o bloque inicializador. Tienen un alcance en el bloque {
.. }
en el que se declaran y no permiten ningún especificador de acceso. ( JLS §14.3 ) Con la reflexión, puede crear instancias de clases locales desde otros lugares, y son paquetes privados , aunque no estoy seguro de si ese detalle está en JLS.
Las clases anónimas son clases personalizadas creadas con las new
que se especifica un cuerpo de clase directamente en la expresión. ( JLS §15.9.5 ) Su sintaxis no permite ningún especificador de acceso. Con la reflexión, puede crear instancias de clases anónimas desde otros lugares, y tanto ellas como sus constructores generados son paquetes privados , aunque no estoy seguro de si ese detalle está en el JLS.
Los bloques de inicializador estático y de instancia no tienen especificadores de acceso a nivel de idioma ( JLS §8.6 y 8.7 ), pero los bloques de inicializador estático se implementan como un método denominado <clinit>
( JVMS §2.9 ), por lo que el método debe, internamente, tener algún especificador de acceso. Examiné clases compiladas por javac y por el compilador de Eclipse usando un editor hexadecimal y descubrí que ambos generan el método como paquete privado . Sin embargo, no puede llamar <clinit>()
dentro del idioma porque los caracteres <
y >
no son válidos en el nombre de un método, y los métodos de reflexión están programados para negar su existencia, por lo que efectivamente su especificador de acceso es sin acceso . El método solo puede ser llamado por la máquina virtual, durante la inicialización de la clase.Los bloques inicializadores de instancias no se compilan como métodos separados; su código se copia en cada constructor, por lo que no se puede acceder a ellos individualmente, incluso por reflexión.
default es una palabra clave que se utiliza como modificador de acceso para métodos y variables.
El uso de este modificador de acceso hará que su clase, variable, método o constructor sea accesible desde su propia clase o paquete, y también se establecerá si no hay ningún modificador de acceso presente.
Access Levels
Modifier Class Package Subclass EveryWhere
public Y Y Y Y
protected Y Y Y N
default Y Y N N
private Y N N N
si usa un valor predeterminado en una interfaz, podrá implementar un método como este ejemplo
public interface Computer {
default void Start() {
throw new UnsupportedOperationException("Error");
}
}
Sin embargo, solo funcionará desde la versión 8 de Java
Consulte aquí para obtener más detalles. El valor predeterminado no es privado / público / protegido, sino una especificación de acceso completamente diferente. No se usa mucho y prefiero ser mucho más específico en mis definiciones de acceso.
Aquí hay una cita sobre la visibilidad a nivel de paquete de una entrevista con James Gosling, el creador de Java:
Bill Venners : Java tiene cuatro niveles de acceso. El valor predeterminado es paquete. Siempre me he preguntado si hacer que el acceso al paquete sea predeterminado era conveniente porque las tres palabras clave que la gente de C ++ ya conocía eran privadas, protegidas y públicas. O si tenía alguna razón en particular por la que pensaba que el acceso al paquete debería ser el predeterminado.
James Gosling : Un paquete es generalmente un conjunto de cosas que se escriben juntas. De manera genérica, podría haber hecho una de dos cosas. Una era obligarte a poner siempre una palabra clave que te diera el dominio. O podría haber tenido un valor predeterminado. Y luego la pregunta es, ¿qué hace un valor predeterminado razonable? Y suelo apostar por lo menos peligroso.
Así que public hubiera sido algo realmente malo hacer el valor predeterminado. Privado probablemente hubiera sido algo malo establecer un valor predeterminado, aunque solo sea porque la gente en realidad no escribe métodos privados con tanta frecuencia. Y lo mismo con protegido. Y al mirar un montón de código que tenía, decidí que lo más común que era razonablemente seguro estaba en el paquete. Y C ++ no tenía una palabra clave para eso, porque no tenían una noción de paquetes.
Pero me gustó más que la noción de amigos, porque con los amigos tienes que enumerar quiénes son todos tus amigos, por lo que si agregas una nueva clase a un paquete, generalmente terminas teniendo que ir a todos los clases en ese paquete y actualizar a sus amigos, lo que siempre me pareció un completo dolor de cabeza.
Pero la lista de amigos en sí misma causa una especie de problema de versiones. Y entonces existía esta noción de una clase amigable. Y lo bueno es que lo estaba convirtiendo en el predeterminado: resolveré el problema, entonces, ¿cuál debería ser la palabra clave?
Durante un tiempo hubo una palabra clave amigable. Pero debido a que todos los demás comienzan con "P", fue "amistoso" con un "PH". Pero eso solo estuvo allí tal vez por un día.
Actualizar el uso de palabras clave de Java 8default
: como muchos otros han notado La visibilidad predeterminada (sin palabra clave)
el campo será accesible desde dentro del mismo paquete al que pertenece la clase.
No debe confundirse con la nueva característica de Java 8 ( métodos predeterminados ) que permite que una interfaz proporcione una implementación cuando está etiquetada con la default
palabra clave.
Hay un modificador de acceso llamado "predeterminado" en JAVA, que permite la creación de instancia directa de esa entidad solo dentro de ese paquete.
Aquí hay un enlace útil:
En primer lugar, déjeme decir una cosa: no existe un término como "Especificador de acceso" en Java. Deberíamos llamar a todo como "Modificadores". Como sabemos que final, estático, sincronizado, volátil ... se llaman modificadores, incluso Público, privado, protegido, predeterminado, abstracto también deben llamarse como modificadores. El valor predeterminado es un modificador en el que la existencia física no existe pero no se coloca ningún modificador, entonces debe tratarse como modificadores predeterminados.
Para justificar esto, tome un ejemplo:
public class Simple{
public static void main(String args[]){
System.out.println("Hello Java");
}
}
La salida será: Hello Java
Ahora cambie de público a privado y vea qué error del compilador obtiene: Dice "El modificador privado no está permitido aquí". La conclusión es que alguien puede estar equivocado o algún tutorial puede estar equivocado, pero el compilador no puede estar equivocado. Entonces, podemos decir que no hay un especificador de acceso a términos en Java, todo son modificadores.