W3docs

Modificadores sin acceso en Java

Usa los modificadores sin acceso de Java — static, final, abstract, synchronized, transient, volatile — y lo que controla cada uno.

Los modificadores de acceso de Java — public, protected, private — controlan quién puede ver un miembro. Los modificadores sin acceso controlan cómo se comporta. Son un pequeño conjunto de palabras clave que modifican la propiedad, la mutabilidad, los hilos, la serialización y algunas otras cosas. Este capítulo es el mapa; cada modificador tiene un capítulo o sección más completo en otro lugar.

La lista completa

ModificadorSe aplica aQué hace
staticcampos, métodos, clases anidadas, bloquesPertenece a la clase, no a las instancias
finalclases, métodos, campos, parámetros, variables localesNo se puede reasignar/sobrescribir/extender
abstractclases, métodosSin cuerpo / no puede instanciarse; debe ser implementado por una subclase
synchronizedmétodos, bloquesSolo un hilo a la vez puede ejecutarlo sobre un bloqueo dado
volatilecamposLas lecturas/escrituras no se almacenan en caché en la memoria local del hilo
transientcamposSe omite en la serialización predeterminada
nativemétodosLa implementación reside en código no Java (generalmente C/C++)
strictfpclases, métodosFuerza el comportamiento estricto de punto flotante IEEE-754 (mayormente histórico)
defaultmétodos de interfazProporciona un cuerpo predeterminado en una interfaz
sealed / non-sealedclases, interfacesRestringe qué clases pueden extenderla (Java 17+)

Usarás static, final, abstract y default constantemente. El resto los verás solo cuando surja su problema específico.

static — pertenece a la clase

Un miembro static está asociado con la clase en sí, no con ninguna instancia individual:

public class Counter {
  int instanceCount;          // one per Counter object
  static int classCount;      // one shared by everyone
}

static es tan común que tiene su propio capítulo — ver java-static.

final — no puede cambiar

final significa "este enlace está fijo una vez establecido." Se aplica a varias cosas distintas:

final int MAX = 100;          // local variable cannot be reassigned
public final class Money {}   // class cannot be extended
public final void close() {}  // method cannot be overridden
private final int balance;    // field assigned once, then immutable

final es la base de las constantes (static final), los objetos inmutables y el diseño seguro de herencia. Tratamiento completo en java-final.

abstract — no tiene cuerpo, debe completarse

abstract aplicado a una clase significa "no puedes instanciar esto directamente — solo las subclases." Aplicado a un método, significa "sin cuerpo aquí — cada subclase concreta debe proporcionar uno":

public abstract class Shape {
  public abstract double area();      // no body
}

public class Circle extends Shape {
  double r;
  public double area() { return Math.PI * r * r; }
}

new Shape() es un error de compilación; new Circle() funciona. Cubierto en clases abstractas.

synchronized — un hilo a la vez

Cuando dos hilos podrían llamar al mismo método en el mismo objeto, marcar el método como synchronized garantiza que solo uno se ejecute a la vez:

public synchronized void deposit(int amount) {
  balance += amount;
}

Esta es la forma más sencilla de bloqueo. Hay toda una sección de concurrencia más adelante en el libro; por ahora, reconoce que la palabra clave existe y qué hace en términos generales. Ver sincronización para la historia completa.

volatile — visible entre hilos

Sin volatile, los hilos pueden almacenar en caché el valor de un campo. Las lecturas en un hilo podrían nunca ver las escrituras de otro:

private volatile boolean stopped = false;

volatile obliga a que cada lectura provenga de la memoria principal y cada escritura vaya a la memoria principal. Es el primo liviano de synchronized para campos de indicador simples — ver volatile para los detalles del modelo de memoria.

transient — omitir en la serialización

La serialización de objetos incorporada de Java (Serializable) escribe todos los campos de forma predeterminada. transient dice "no incluir este" — típicamente usado para cachés, valores calculados o cosas que no tienen sentido fuera del programa en ejecución:

public class Session {
  String userId;
  transient String passwordHash;     // not serialized
}

El código moderno usa serializadores JSON más que Serializable, pero la palabra clave sigue siendo útil en bibliotecas que la consideran. Más en serialización.

native — implementado en otro lugar

native es para métodos cuyo cuerpo está en otro lenguaje (C/C++ a través de JNI). Rara vez los escribes tú mismo; solo los ves en bibliotecas de bajo nivel:

public native int currentTimeMillis();

strictfp — punto flotante estricto

Originalmente, strictfp forzaba una aritmética de punto flotante IEEE-754 predecible entre plataformas. A partir de Java 17, toda la aritmética de punto flotante es implícitamente estricta, lo que hace que la palabra clave sea un no-op. Puedes ignorarla en su mayoría; persiste en bases de código antiguas.

default — en métodos de interfaz

Dentro de una interfaz, default te permite proporcionar un cuerpo para un método en lugar de dejarlo abstracto:

public interface Greeter {
  default String greet(String name) {
    return "Hello, " + name;
  }
}

Sin default, un método de interfaz no tiene cuerpo y cada clase que lo implementa tiene que escribir el suyo. Tratamiento completo en métodos default.

sealed y non-sealed

Una clase sealed nombra la lista exacta de clases permitidas para extenderla. Las subclases deben entonces elegir ser final, sealed o non-sealed:

public sealed class Shape permits Circle, Square { }
public final class Circle extends Shape { }
public non-sealed class Square extends Shape { }

Útil para jerarquías de tipos cerradas — ver clases selladas.

Combinar modificadores

Normalmente puedes apilar modificadores libremente, en este orden convencional:

public  static  final   int MAX = 100;
private static  volatile int counter;
protected abstract       void onInit();

Algunas combinaciones son ilegales: un método no puede ser a la vez abstract y final, ni abstract y private, ni abstract y static. El compilador te dirá cuando hayas cruzado una línea.

Un ejemplo práctico

java— editable, runs on the server

Qué sigue

Los dos próximos capítulos profundizan en los dos modificadores que usarás con más frecuencia: static para los miembros a nivel de clase, y luego final para la inmutabilidad. Léelos en orden.

Práctica

Práctica
¿Qué modificador sin acceso significa que un miembro de clase pertenece a la clase misma en lugar de a cada instancia?
¿Qué modificador sin acceso significa que un miembro de clase pertenece a la clase misma en lugar de a cada instancia?
Was this page helpful?