Modificadores de Java

El lenguaje Java proporciona muchos modificadores, que se dividen principalmente en las siguientes dos categorías:

  • Modificadores de acceso
  • Modificadores de no acceso

Los modificadores se utilizan para definir clases, métodos o variables, y generalmente se colocan al comienzo de la declaración. Lo ilustramos mediante el siguiente ejemplo:

public class ClassName { // ... } private boolean myFlag; static final double weeks = 9.5; protected static final int BOXWIDTH = 42; public static void main(String[] arguments) { //Cuerpo del método }

Modificadores de control de acceso

En Java, se pueden usar modificadores de control de acceso para proteger el acceso a clases, variables, métodos y constructores. Java admite 4 tipos diferentes de niveles de acceso.

  • default(es decir, por defecto, sin escribir nada): visible dentro del mismo paquete, sin usar ningún modificador. Se aplica a: clases, interfaces, variables y métodos.

  • private: visible dentro de la misma clase. Se aplica a: variables y métodos.Nota: no se puede usar para modificar clases (clases externas).

  • public: visible para todas las clases. Se aplica a: clases, interfaces, variables y métodos.

  • protected: visible para las clases del mismo paquete y para todas las subclases. Se aplica a: variables y métodos.Nota: no se puede usar para modificar clases (clases externas).。

Podemos ilustrar los niveles de acceso mediante la siguiente tabla:

Control de acceso
Modificador Clase actual Mismo paquete Subclases (mismo paquete) Subclases (paquete diferente) Otros paquetes
public Y Y Y Y Y
protected Y Y Y Y/N(Descripción) N
default Y Y Y N N
private Y N N N N

Modificador de acceso por defecto - sin usar ninguna palabra clave

Si no se especifica ningún modificador de acceso en la definición de una clase, variable, método o constructor, entonces estos tendrán el modificador de acceso por defecto.

El nivel de acceso del modificador de acceso por defecto es a nivel de paquete (package-level), es decir, solo puede ser accedido por otras clases del mismo paquete.

Como se muestra en el siguiente ejemplo, la declaración de variables y métodos puede no usar ningún modificador.

Ejemplo

// MyClass.java class MyClass { //Modificador de acceso por defecto int x = 10; //Modificador de acceso por defecto void display() { //Modificador de acceso por defecto System.out.println("Value of x is: " + x); } } // MyOtherClass.java class MyOtherClass { public static void main(String[] args) { MyClass obj = new MyClass(); obj.display(); //Accediendo a la variable y al método con modificador de acceso por defecto en MyClass } }

En el ejemplo anterior, la clase MyClass y su variable miembro x y el método display() se definen todos con el modificador de acceso por defecto. La clase MyOtherClass está en el mismo paquete, por lo que puede acceder a la clase MyClass y a sus variables y métodos miembro.

Modificador de acceso privado - private

El modificador de acceso privado es el nivel de acceso más estricto, por lo que los métodos, variables y constructores declarados como privateprivatesolo pueden ser accedidos por la clase a la que pertenecen, y las clases e interfaces no pueden declararse como private.private。

Las variables declaradas como de tipo de acceso privado solo pueden ser accedidas desde fuera de la clase mediante los métodos getter públicos de la clase.

El uso del modificador de acceso Private sirve principalmente para ocultar los detalles de implementación de la clase y proteger los datos de la clase.

La siguiente clase utiliza el modificador de acceso privado:

public class Logger { private String format; public String getFormat() { return this.format; } public void setFormat(String format) { this.format = format; } }

En el ejemplo, la variable format en la clase Logger es una variable privada, por lo que otras clases no pueden obtener ni establecer directamente el valor de esa variable. Para permitir que otras clases puedan operar con esa variable, se definieron dos métodos public: getFormat() (devuelve el valor de format) y setFormat(String) (establece el valor de format).

Modificador de acceso público - public

Las clases, métodos, constructores e interfaces declarados como public pueden ser accedidos por cualquier otra clase.

Si varias clases public que se acceden entre sí están en paquetes diferentes, entonces es necesario importar el paquete de la clase public correspondiente. Debido a la herencia de clases, todos los métodos y variables públicos de una clase pueden ser heredados por sus subclases.

Las siguientes funciones utilizan control de acceso público:

public static void main(String[] arguments) { // ... }

El método main() de un programa Java debe declararse como público; de lo contrario, el intérprete de Java no podrá ejecutar la clase.

Modificador de acceso protegido - protected

protected debe analizarse y explicarse desde los siguientes dos puntos:

  • Subclase y clase base en el mismo paquete: las variables, métodos y constructores declarados como protected pueden ser accedidos por cualquier otra clase del mismo paquete;

  • Subclase y clase base no están en el mismo paquete: entonces, en la subclase, una instancia de la subclase puede acceder a los métodos protected que ha heredado de la clase base, pero no puede acceder a los métodos protected de una instancia de la clase base.

protected puede modificar miembros de datos, constructores y métodos miembro,no puede modificar clases (excepto las clases internas).。

Las interfaces y sus variables miembro y métodos miembro no pueden declararse como protected. Puedes ver la demostración en la siguiente figura:

Las subclases pueden acceder a los métodos y variables declarados con el modificador protected, de esta manera se evita que clases no relacionadas usen estos métodos y variables.

La siguiente clase padre utiliza el modificador de acceso protected, y la subclase sobrescribe el método openSpeaker() de la clase padre.

class AudioPlayer { protected boolean openSpeaker(Speaker sp) { //Detalles de implementación } } class StreamingAudioPlayer extends AudioPlayer { protected boolean openSpeaker(Speaker sp) { //Detalles de implementación } }

Si el método openSpeaker() se declara como private, entonces, excepto AudioPlayer, ninguna otra clase podrá acceder a ese método.

Si openSpeaker() se declara como public, entonces todas las clases podrán acceder a ese método.

Si solo queremos que el método sea visible para las subclases de la clase a la que pertenece, entonces lo declaramos como protected.

protected es uno de los modificadores de acceso a miembros de clase en Java más difíciles de entender. Para obtener más detalles, consultaExplicación detallada de la palabra clave protected en Java。

Control de acceso y herencia

Ten en cuenta las siguientes reglas de herencia de métodos:

  • Los métodos declarados como public en la clase padre también deben ser public en la subclase.

  • Los métodos declarados como protected en la clase padre deben declararse en la subclase como protected o public; no pueden declararse como private.

  • Los métodos declarados como private en la clase padre no pueden ser heredados por la subclase.


Modificadores de no acceso

Para implementar algunas otras funcionalidades, Java también proporciona muchos modificadores de no acceso.

El modificador static se utiliza para modificar métodos de clase y variables de clase.

El modificador final se utiliza para modificar clases, métodos y variables. Las clases modificadas con final no pueden ser heredadas; los métodos modificados no pueden ser redefinidos por la subclase; y las variables modificadas son constantes e inmutables.

El modificador abstract se utiliza para crear clases abstractas y métodos abstractos.

Los modificadores synchronized y volatile se utilizan principalmente en programación con hilos.

Modificador static

  • Variables estáticas:

    La palabra clave static se utiliza para declarar variables estáticas independientes de los objetos. No importa cuántos objetos se instancien de una clase, su variable estática tiene solo una copia. Las variables estáticas también se conocen como variables de clase. Las variables locales no pueden declararse como variables static.

  • Métodos estáticos:

    La palabra clave static se utiliza para declarar métodos estáticos independientes de los objetos. Los métodos estáticos no pueden usar variables no estáticas de la clase. Los métodos estáticos obtienen datos de la lista de parámetros y luego calculan esos datos.

El acceso a las variables y métodos de clase se puede realizar directamente utilizandoclassname.variablenameyclassname.methodnamela forma de acceso.

Como se muestra en el siguiente ejemplo, el modificador static se utiliza para crear métodos de clase y variables de clase.

public class InstanceCounter { private static int numInstances = 0; protected static int getCount() { return numInstances; } private static void addInstance() { numInstances++; } InstanceCounter() { InstanceCounter.addInstance(); } public static void main(String[] arguments) { System.out.println("Starting with " + InstanceCounter.getCount() + " instances"); for (int i = 0; i < 500; ++i){ new InstanceCounter(); } System.out.println("Created " + InstanceCounter.getCount() + " instances"); } }

El resultado de ejecutar el ejemplo anterior es el siguiente:

Starting with 0 instances
Created 500 instances

Modificador final

Variables final:

final tiene el significado de 'último, definitivo'. Una vez que una variable ha sido asignada, no puede volver a asignarse. Las variables de instancia modificadas con final deben especificar explícitamente un valor inicial.

El modificador final generalmente se usa junto con el modificador static para crear constantes de clase.

Ejemplo

public class Test{ final int value = 10; //El siguiente es un ejemplo de declaración de constantes public static final int BOXWIDTH = 6; static final String TITLE = "Manager"; public void changeValue(){ value = 12; //Se mostrará un error } }

Método final

Los métodos final de la clase padre pueden ser heredados por la subclase, pero no pueden ser sobrescritos por la subclase.

El propósito principal de declarar un método final es evitar que el contenido del método sea modificado.

Como se muestra a continuación, declare el método con el modificador final.

public class Test{ public final void changeName(){ //Cuerpo del método } }

Clase final

Una clase final no puede ser heredada; ninguna clase puede heredar ninguna característica de una clase final.

Ejemplo

public final class Test { //Cuerpo de la clase }

Modificador abstract

Clase abstracta:

Una clase abstracta no se puede utilizar para instanciar objetos; el único propósito de declarar una clase abstracta es para expandirla en el futuro.

Una clase no puede ser modificada a la vez por abstract y final. Si una clase contiene métodos abstractos, entonces dicha clase debe declararse como clase abstracta; de lo contrario, se producirá un error de compilación.

Una clase abstracta puede contener métodos abstractos y métodos no abstractos.

Ejemplo

abstract class Caravan{ private double price; private String model; private String year; public abstract void goFast(); //Método abstracto public abstract void changeColor(); }

Método abstracto

Un método abstracto es un método sin ninguna implementación; la implementación concreta de dicho método la proporciona la subclase.

Los métodos abstractos no pueden declararse como final y static.

Cualquier subclase que herede una clase abstracta debe implementar todos los métodos abstractos de la clase padre, a menos que la subclase también sea abstracta.

Si una clase contiene varios métodos abstractos, entonces la clase debe declararse como clase abstracta. Una clase abstracta puede no contener métodos abstractos.

La declaración de un método abstracto termina con punto y coma, por ejemplo:public abstract sample();。

Ejemplo

public abstract class SuperClass{ abstract void m(); //Método abstracto } class SubClass extends SuperClass{ //Implementar el método abstracto void m(){ ......... } }

Modificador synchronized

Un método declarado con la palabra clave synchronized solo puede ser accedido por un hilo a la vez. El modificador synchronized puede aplicarse a los cuatro modificadores de acceso.

Ejemplo

public synchronized void showDetails(){ ....... }

Modificador transient

Cuando un objeto serializado contiene variables de instancia modificadas con transient, la máquina virtual de Java (JVM) omite esa variable específica.

Este modificador se incluye en la declaración de la variable y se utiliza para preprocesar los tipos de datos de clases y variables.

Ejemplo

public transient int limit = 55; //No persistirá public int b; //Persistirá

Modificador volatile

Cuando una variable miembro modificada con volatile es accedida por un hilo, se fuerza a releer el valor de esa variable miembro desde la memoria compartida. Además, cuando la variable miembro cambia, se fuerza al hilo a escribir el valor cambiado de vuelta en la memoria compartida. De esta manera, en cualquier momento, dos hilos diferentes siempre ven el mismo valor de una variable miembro.

Una referencia de objeto volatile puede ser null.

Ejemplo

public class MyRunnable implements Runnable { private volatile boolean active; public void run() { active = true; while (active) //Primera línea { //Código } } public void stop() { active = false; //Segunda línea } }

Normalmente, en un hilo se llama al método run() (en el hilo iniciado por Runnable), y en otro hilo se llama al método stop(). SiPrimera línease usa el valor de active en el búfer, entonces enSegunda líneacuando active es false, el bucle no se detendrá.

Pero en el código anterior usamos volatile para modificar active, por lo que el bucle se detendrá.

Otras extensiones