W3docs

Modificadores Não-de-Acesso em Java

Use os modificadores não-de-acesso do Java — static, final, abstract, synchronized, transient, volatile — e o que cada um controla.

Os modificadores de acesso do Java — public, protected, private — controlam quem pode ver um membro. Os modificadores não-de-acesso controlam como ele se comporta. São um pequeno conjunto de palavras-chave que alteram propriedade, mutabilidade, threading, serialização e algumas outras coisas. Este capítulo é o mapa; cada modificador tem um capítulo ou seção mais completo em outro lugar.

A lista completa

ModificadorAplica-se aO que faz
staticcampos, métodos, classes aninhadas, blocosPertence à classe, não às instâncias
finalclasses, métodos, campos, parâmetros, variáveis locaisNão pode ser reatribuído/sobrescrito/estendido
abstractclasses, métodosSem corpo / não pode ser instanciado; deve ser implementado por uma subclasse
synchronizedmétodos, blocosApenas uma thread por vez pode executá-lo em um dado lock
volatilecamposLeituras/escritas não são armazenadas em cache na memória local da thread
transientcamposIgnorado pela serialização padrão
nativemétodosA implementação reside em código não-Java (geralmente C/C++)
strictfpclasses, métodosForça comportamento estrito de ponto flutuante IEEE-754 (em grande parte histórico)
defaultmétodos de interfaceFornece um corpo padrão em uma interface
sealed / non-sealedclasses, interfacesRestringe quais classes podem estender (Java 17+)

Você encontrará static, final, abstract e default constantemente. Os demais você verá apenas quando o problema específico deles surgir.

static — pertence à classe

Um membro static está associado à própria classe, não a nenhuma instância específica:

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

static é tão comum que tem seu próprio capítulo — veja java-static.

final — não pode mudar

final significa "esta ligação é fixa após ser definida." Aplica-se a algumas coisas diferentes:

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 é a base das constantes (static final), objetos imutáveis e design de herança seguro. Tratamento completo em java-final.

abstract — não tem corpo, precisa ser preenchido

abstract aplicado a uma classe significa "você não pode instanciar isso diretamente — apenas subclasses podem." Aplicado a um método, significa "sem corpo aqui — toda subclasse concreta deve fornecer um":

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() é um erro de compilação; new Circle() funciona. Abordado em classes abstratas.

synchronized — uma thread por vez

Quando duas threads podem chamar o mesmo método no mesmo objeto, marcar o método como synchronized garante que apenas uma seja executada por vez:

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

Esta é a forma mais simples de locking. Há uma seção inteira sobre concorrência mais adiante no livro; por ora, reconheça que a palavra-chave existe e o que ela faz de forma geral. Veja sincronização para a história completa.

volatile — visível entre threads

Sem volatile, as threads têm permissão para armazenar em cache o valor de um campo. Leituras em uma thread podem nunca ver escritas de outra:

private volatile boolean stopped = false;

volatile força cada leitura a vir da memória principal e cada escrita a ir para a memória principal. É o primo leve de synchronized para campos de flag simples — veja volatile para os detalhes do modelo de memória.

transient — ignorado na serialização

A serialização de objetos embutida do Java (Serializable) escreve todos os campos por padrão. transient diz "não inclua este" — normalmente usado para caches, valores computados ou coisas que não fazem sentido fora do programa em execução:

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

O código moderno usa serializadores JSON mais do que Serializable, mas a palavra-chave ainda é útil em bibliotecas que se importam com ela. Mais em serialização.

native — implementado em outro lugar

native é para métodos cujo corpo está em outra linguagem (C/C++ via JNI). Você raramente os escreve você mesmo; você os vê apenas em bibliotecas de baixo nível:

public native int currentTimeMillis();

strictfp — ponto flutuante estrito

Originalmente, strictfp forçava aritmética de ponto flutuante IEEE-754 previsível entre plataformas. A partir do Java 17, toda a matemática de ponto flutuante é implicitamente estrita, o que torna a palavra-chave um no-op. Você pode ignorá-la em grande parte; ela persiste em bases de código mais antigas.

default — em métodos de interface

Dentro de uma interface, default permite que você forneça um corpo para um método em vez de deixá-lo abstrato:

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

Sem default, um método de interface não tem corpo e toda classe implementadora precisa escrever o seu. Tratamento completo em métodos default.

sealed e non-sealed

Uma classe sealed nomeia a lista exata de classes com permissão para estendê-la. As subclasses devem então escolher ser final, sealed ou non-sealed:

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

Útil para hierarquias de tipos fechadas — veja classes sealed.

Combinando modificadores

Geralmente você pode empilhar modificadores livremente, nesta ordem convencional:

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

Algumas combinações são ilegais: um método não pode ser ao mesmo tempo abstract e final, ao mesmo tempo abstract e private, ou ao mesmo tempo abstract e static. O compilador informará quando você cruzar uma linha.

Um exemplo prático

java— editable, runs on the server

O que vem a seguir

Os próximos dois capítulos aprofundam os dois modificadores que você usará com mais frequência: static para membros no nível de classe e final para imutabilidade. Leia-os em ordem.

Prática

Prática
Qual modificador não-de-acesso significa que um membro de classe pertence à própria classe e não a cada instância?
Qual modificador não-de-acesso significa que um membro de classe pertence à própria classe e não a cada instância?
Was this page helpful?