El lenguaje Java proporciona muchos modificadores, que se dividen principalmente en las dos categorías siguientes:
Los modificadores se utilizan para definir clases, métodos o variables y generalmente se colocan al principio de la declaración. Ilustramos esto a través del 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) { // 方法体}
En Java, los controles de acceso se pueden utilizar para proteger el acceso a clases, variables, métodos y constructores. Java admite 4 derechos de acceso diferentes.
El valor predeterminado, también llamado predeterminado, es visible dentro del mismo paquete y no utiliza ningún modificador.
Privado, especificado con el modificador privado, visible dentro de la misma clase.
Público, especificado con el modificador público, visible para todas las clases.
Protegido, especificado con el modificador protegido, es visible para las clases y todas las subclases del mismo paquete.
Las variables y métodos declarados con modificadores de acceso predeterminados son visibles para las clases del mismo paquete. Las variables en la interfaz se declaran implícitamente como public static final
, mientras que los métodos en la interfaz tienen permisos de acceso public
de forma predeterminada.
Ejemplo:
Como se muestra en el siguiente ejemplo, las variables y los métodos se pueden declarar sin ningún modificador.
String version = "1.5.1"; boolean processOrder() { return true; }
El modificador de acceso privado es el nivel de acceso más restrictivo, por lo que a los métodos, variables y constructores declarados como privados solo puede acceder la clase a la que pertenecen, y las clases e interfaces no pueden declararse como privadas.
Solo las clases externas pueden acceder a las variables declaradas como tipos de acceso privado a través de los métodos getter públicos de la clase.
El uso del modificador de acceso privado se utiliza 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 de formato en la clase Logger es una variable privada, por lo que otras clases no pueden obtener ni establecer directamente el valor de la variable. Para permitir que otras clases operen esta variable, se definen dos métodos public
: getFormat()
(devuelve el valor del formato) y setFormat(String)
(establece el valor del formato)
Cualquier otra clase puede acceder a las clases, métodos, constructores e interfaces declarados como públicos.
Si varias clases públicas que acceden entre sí están distribuidas en diferentes paquetes, debe importar el paquete donde se encuentra la clase pública correspondiente. Debido a la herencia de clases, todas las variables y métodos 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() del programa Java debe configurarse como público; de lo contrario, el intérprete de Java no podrá ejecutar la clase.
Cualquier otra clase del mismo paquete o subclases de paquetes diferentes pueden acceder a las variables, métodos y constructores declarados como protegidos.
Los modificadores de acceso protegido no pueden modificar clases e interfaces. Los métodos y las variables miembro se pueden declarar protegidos, pero las variables miembro y los métodos miembro de las interfaces no se pueden declarar protegidos.
Las subclases pueden acceder a métodos y variables declarados con el modificador Protegido, protegiendo así a clases no relacionadas del uso de estos métodos y variables.
La siguiente clase principal utiliza el modificador de acceso protegido y la subclase anula el método openSpeaker() de la clase principal.
class AudioPlayer { protected boolean openSpeaker(Speaker sp) { // 实现细节} } class StreamingAudioPlayer extends AudioPlayer { boolean openSpeaker(Speaker sp) { // 实现细节} }
Si el método openSpeaker() se declara privado, las clases distintas a AudioPlayer no podrán acceder a este método.
Si openSpeaker() se declara como público, todas las clases pueden acceder a este método.
Si solo queremos que el método sea visible para las subclases de su clase, declaramos el método como protegido.
Tenga en cuenta las siguientes reglas para la herencia de métodos:
Los métodos declarados como públicos en la clase principal también deben ser públicos en la clase secundaria.
Los métodos declarados como protegidos en la clase principal se declaran como protegidos o públicos en la subclase. No se puede declarar privado.
Los métodos declarados como privados en la clase principal no se pueden heredar.
Para implementar algunas otras funciones, Java también proporciona muchos modificadores sin acceso.
Modificador estático, utilizado para crear métodos de clase y variables de clase.
El modificador final se utiliza para modificar clases, métodos y variables. Las clases modificadas por final no se pueden heredar, los métodos modificados no se pueden redefinir mediante clases heredadas y las variables modificadas son constantes y no se pueden modificar.
Modificador abstracto, utilizado para crear clases abstractas y métodos abstractos.
Los modificadores sincronizados y volátiles se utilizan principalmente para la programación de subprocesos.
Variables estáticas:
La palabra clave estática se utiliza para declarar variables estáticas que son independientes de los objetos. No importa cuántos objetos instancia una clase, solo hay una copia de sus variables estáticas. Las variables estáticas también se conocen como variables de clase. Las variables locales no se pueden declarar como variables estáticas.
Método estático:
La palabra clave estática se utiliza para declarar métodos estáticos independientes de los objetos. Los métodos estáticos no pueden utilizar variables no estáticas de la clase. Los métodos estáticos obtienen datos de una lista de parámetros y luego los calculan.
Se puede acceder directamente a las variables y métodos de clase usando classname.variablename
y classname.methodname
.
Como se muestra en el siguiente ejemplo, el modificador estático 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"); } }
Los resultados de edición de ejecutar el ejemplo anterior son los siguientes:
Started with 0 instances Created 500 instances
variables finales:
Las variables finales se pueden inicializar explícitamente y solo una vez. Las referencias a objetos declarados finales no pueden apuntar a objetos diferentes. Pero los datos del objeto final se pueden cambiar. En otras palabras, la referencia del objeto final no se puede cambiar, pero se puede cambiar el valor interior.
El modificador final se utiliza a menudo junto con el modificador estático para crear constantes de clase.
Ejemplo:
public class Test{ final int value = 10; // 下面是声明常量的实例public static final int BOXWIDTH = 6; static final String TITLE = "Manager"; public void changeValue(){ value = 12; //将输出一个错误} }
El método Final de una clase puede ser heredado por las subclases, pero no puede ser modificado por las subclases.
El objetivo principal de declarar un método final es evitar que se modifique el contenido del método.
Como se muestra a continuación, declare el método usando el modificador final.
public class Test{ public final void changeName(){ // 方法体} }
Las clases finales no se pueden heredar y ninguna clase puede heredar ninguna característica de una clase final.
Ejemplo:
public final class Test { // 类体}
Clase abstracta:
Las clases abstractas no se pueden utilizar para crear instancias de objetos. El único propósito de declarar una clase abstracta es extender la clase en el futuro.
Una clase no puede ser modificada por resumen y final al mismo tiempo. Si una clase contiene métodos abstractos, la clase debe declararse como una clase abstracta; de lo contrario, se producirá un error de compilación.
Las clases abstractas pueden 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(); //抽象方法public abstract void changeColor(); }
Un método abstracto es un método sin ninguna implementación. La implementación específica del método la proporciona la subclase. Los métodos abstractos no pueden declararse finales y estáticos.
Cualquier subclase que herede una clase abstracta debe implementar todos los métodos abstractos de la clase principal, a menos que la subclase también sea una clase abstracta.
Si una clase contiene varios métodos abstractos, entonces la clase debe declararse como clase abstracta. Una clase abstracta no necesita contener métodos abstractos.
La declaración de un método abstracto termina con un punto y coma, por ejemplo: muestra abstracta pública();
Ejemplo:
public abstract class SuperClass{ abstract void m(); //抽象方法} class SubClass extends SuperClass{ //实现抽象方法void m(){ ......... } }
Solo un hilo puede acceder al método declarado con la palabra clave sincronizada al mismo tiempo. El modificador Sincronizado se puede aplicar a cuatro modificadores de acceso.
Ejemplo:
public synchronized void showDetails(){ ....... }
Cuando el objeto serializado contiene una variable de instancia modificada por un transitorio, la máquina virtual Java (JVM) omite esa variable en particular.
Este modificador se incluye en la declaración que define la variable y se utiliza para preprocesar el tipo de datos de la clase y la variable.
Ejemplo:
public transient int limit = 55; // will not persist public int b; // will persist
Cada vez que un subproceso accede a una variable miembro modificada volátil, se fuerza a releer el valor de la variable miembro desde la memoria compartida. Además, cuando una variable miembro cambia, el hilo se ve obligado a escribir el valor modificado nuevamente en la memoria compartida. De esta forma, en cualquier momento, dos hilos diferentes siempre ven el mismo valor de una variable miembro.
Una referencia a un objeto volátil puede ser nula.
Ejemplo:
public class MyRunnable implements Runnable { private volatile boolean active; public void run() { active = true; while (active) // line 1 { // 代码} } public void stop() { active = false; // line 2 } }
Generalmente, el método run() se llama en un hilo y el método stop() se llama en otro hilo. Si se utiliza el valor de activo en la línea 1 del búfer, entonces el bucle no se detendrá cuando activo en la línea 2 se establezca en falso.