W3docs

Modificadores de Acesso em Java

Controle a visibilidade em Java com os modificadores de acesso public, private, protected e package-private (padrão).

Modificadores de acesso determinam quem pode ver e usar uma classe, campo, método ou construtor. Java tem quatro níveis — public, protected, package-private (sem palavra-chave) e private — que vão de "o mundo inteiro" a "apenas esta classe". Escolher o correto é como você estabelece a fronteira entre a interface de um objeto e seus detalhes internos.

Os quatro níveis

Do mais permissivo ao mais restritivo:

ModificadorVisível a partir de
publicEm qualquer lugar
protectedMesmo pacote ou qualquer subclasse (mesmo em outro pacote)
(sem palavra-chave)Apenas o mesmo pacote — package-private
privateApenas a própria classe

É isso. Não existe "friend", nem "module-internal" neste nível; a visibilidade de módulos é um recurso separado do Java Platform Module System que você geralmente não precisa usar.

public

Um membro public faz parte da API publicada da classe — visível para qualquer código que possa ver a própria classe:

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

new Greeter().greet("world");    // anyone can call this

Use public para as coisas que você pretende que outro código — mesmo outros projetos — chame. O custo é que, uma vez que algo é público, você assumiu um compromisso com ele; alterar a assinatura quebra todos os chamadores.

private

private restringe um membro à sua classe declarante. Nada de fora pode tocá-lo — nem mesmo uma subclasse:

public class Account {
  private int balance;     // only Account can read/write

  public void deposit(int amount) {
    if (amount <= 0) throw new IllegalArgumentException();
    balance += amount;      // ok — same class
  }
}

Account a = new Account();
a.balance = -1;             // ERROR — balance is private

Este é o recurso mais utilizado para campos. Ocultar o estado com private é o que faz a validação no deposit ter significado real. O capítulo sobre encapsulamento aprofunda esse padrão.

Package-private (sem palavra-chave)

Omita o modificador completamente e o membro fica visível para tudo no mesmo pacote — mas nada fora dele:

// in package com.shop
class CartHelper {           // no public — package-private
  static int sum(int[] prices) { ... }
}

Outras classes em com.shop podem chamar CartHelper.sum(...); código em com.app nem mesmo sabe que a classe existe. Use isso para utilitários internos que o pacote precisa compartilhar, mas que não fazem parte da API externa do projeto.

Um erro comum: omitir o modificador por esquecimento e depois se surpreender quando a classe pode ser usada em main (também no mesmo pacote durante o aprendizado), mas não em um teste em um pacote diferente.

protected

protected é package-private mais subclasses. Código no mesmo pacote pode usar o membro, e qualquer subclasse — mesmo em um pacote diferente — também pode usá-lo:

public class Shape {
  protected double area;       // subclasses can read/write
}

public class Circle extends Shape {
  Circle(double r) {
    this.area = Math.PI * r * r;   // ok — subclass access
  }
}

Este é o modificador a usar quando você quer que subclasses possam se integrar à maquinaria da classe pai, mas não quer que código cliente geral a toque. Na prática, protected aparece bem menos do que public ou private; muitos designers preferem campos private com métodos acessores protected para o mesmo efeito com mais controle.

Onde os modificadores se aplicam

Você pode colocar um modificador em:

  • Uma classe em si (public class Foo). Classes de nível superior só podem ser public ou package-private. Classes internas podem ser qualquer uma das quatro.
  • Um campo (private int count).
  • Um método (public int get() {...}).
  • Um construtor (private Singleton() {...} — veja o padrão singleton).

Você não pode colocar um modificador de acesso em uma variável local ou em um parâmetro de método. Eles têm escopo determinado apenas pelo local onde são declarados.

A regra de "uma classe pública por arquivo"

Um arquivo .java pode declarar várias classes de nível superior, mas no máximo uma delas pode ser public, e o nome dela deve corresponder ao nome do arquivo:

// file: Order.java
public class Order { ... }          // ok — matches filename
class OrderHelper { ... }           // ok — package-private
public class Customer { ... }       // ERROR — second public class

A maioria dos projetos mantém uma classe por arquivo de qualquer forma, mas utilitários package-private ao lado de uma classe pública às vezes são úteis.

Escolhendo o modificador certo

Uma regra prática que funciona bem:

  1. Use private por padrão para campos e métodos auxiliares.
  2. public para os métodos que você realmente quer que sejam chamados de fora.
  3. Package-private para coisas que precisam ser compartilhadas dentro de um pacote, mas não expostas além dele.
  4. protected apenas quando você especificamente quer acesso por subclasses também.

É fácil ampliar o acesso depois (privatepublic); é doloroso restringi-lo sem quebrar chamadores. Comece restrito.

Modificadores não alteram o comportamento

Um modificador de acesso é uma verificação em tempo de compilação. Em tempo de execução, dois campos int iguais se comportam de forma idêntica, independentemente de terem sido declarados public ou private. O modificador existe puramente para impedir que outro código compile contra o membro — para reforçar uma fronteira que você está declarando.

Um exemplo prático

java— editable, runs on the server

O que vem a seguir

public, protected, private são modificadores de acesso. Java tem outra família — os modificadores sem acesso como static, final, abstract, synchronized — que controlam comportamento em vez de visibilidade. O próximo capítulo, modificadores sem acesso, apresenta esses modificadores.

Prática

Prática
Um campo é declarado sem nenhum modificador de acesso — apenas int count;. Quem pode lê-lo?
Um campo é declarado sem nenhum modificador de acesso — apenas int count;. Quem pode lê-lo?
Was this page helpful?