Menu

Modificadores de acesso em Java: public, private, protected, default

Como os quatro níveis de acesso do Java - public, private, protected e package-private - controlam o que o restante do código pode ver e tocar.

Esta página tem editores executáveis - edite, execute e veja a saída na hora.

Quem pode mexer no seu código

Um modificador de acesso é uma palavra-chave antes de uma classe, campo, método ou construtor que decide quem mais tem permissão para usá-lo. É a base do encapsulamento: você esconde as entranhas bagunçadas de uma classe e expõe apenas as partes que confia que outro código chame.

Java tem quatro níveis, do mais aberto ao mais fechado: public, protected, default (sem palavra-chave nenhuma) e private. Acerte neles e uma classe se torna segura para alterar depois, porque nada externo depende de detalhes que você nunca prometeu manter.

private: visível apenas dentro da classe

private é o nível mais restrito. Um membro private só pode ser tocado por código escrito dentro da mesma classe - nem subclasses, nem outras classes do mesmo pacote, ninguém. É aqui que a maioria dos seus campos deve ficar.

balance é private, então a única forma de alterá-lo é por meio de deposit, que recusa valores negativos. Se balance fosse public, qualquer código poderia escrever account.balance = -9999 e pular a verificação por completo. Essa proteção é todo o sentido de esconder o campo.

Tente descomentar account.balance = 500; em main e você obterá um erro de compilação: balance has private access in BankAccount.

public: visível em todo lugar

public é o extremo oposto - qualquer um, em qualquer lugar, pode usar o membro. Os nomes dos seus métodos que outro código deve chamar geralmente são public. A própria classe também é, quando precisa ser alcançável a partir de outros pacotes.

O padrão comum - às vezes chamado de API pública de uma classe - é campos privados, métodos públicos. Os campos guardam o estado em que ninguém mais deveria mexer; os métodos são as portas controladas de entrada e saída. getBalance e deposit acima são exatamente isso.

default (package-private): nenhuma palavra-chave

Se você não escrever nenhum modificador, obtém acesso default, também chamado de package-private. O membro é visível para todas as classes do mesmo pacote e invisível para tudo que está fora. Não há palavra-chave para esse nível - a ausência de uma é o nível.

class Invoice {       // sem modificador -> visível apenas dentro deste pacote
    int amount;       // sem modificador -> campo package-private
}

Isso pega muitos iniciantes: deixar de fora o public não torna algo private, torna-o package-private. Um campo que você pretendia manter em segredo continua totalmente legível e gravável por qualquer classe que por acaso esteja no mesmo pacote. Se você quer que ele fique realmente oculto, precisa escrever private explicitamente.

O acesso default é genuinamente útil para classes auxiliares que são um detalhe de implementação de um pacote - você não as exporta, mas as classes que cooperam dentro do pacote ainda podem usá-las livremente.

protected: pacote mais subclasses

protected é um degrau mais aberto que default. Um membro protected é visível em todo lugar onde default é (o mesmo pacote), e também para as subclasses - mesmo subclasses em um pacote diferente. Foi projetado para coisas que você quer compartilhar com as classes que estendem a sua, mas não com o mundo inteiro.

Dog acessa name e sound() porque eles são protected e Dog é uma subclasse. Código externo que não é uma subclasse e não está no pacote continua sem conseguir tocá-los. Recorra a protected quando estiver projetando uma classe destinada a ser estendida; caso contrário, prefira private.

Os quatro níveis num relance

Aqui está o quadro completo, do mais restritivo ao mais aberto:

ModificadorMesma classeMesmo pacoteSubclasse (outro pacote)Em todo lugar
privatesimnãonãonão
defaultsimsimnãonão
protectedsimsimsimnão
publicsimsimsimsim

Uma regra prática simples: comece com private e só afrouxe quando algo realmente precisar de um acesso mais amplo. É muito mais fácil ampliar o acesso depois do que restringi-lo depois que outro código já começou a depender de um membro.

Modificadores nas próprias classes

Os modificadores de acesso se aplicam também às classes, não só aos membros - mas uma classe de nível superior (uma que não está aninhada dentro de outra) só pode ser public ou default. Você não pode escrever uma classe de nível superior private ou protected.

public class Order { ... }   // alcançável a partir de qualquer pacote
class LineItem { ... }       // default - só este pacote pode vê-la

Uma classe de nível superior public deve ficar em um arquivo com o nome dela (Order.java). As classes aninhadas, por outro lado, podem usar os quatro modificadores - por isso os exemplos acima podiam marcar as classes internas como private ou default. Um ponto sutil: um método public que retorna um tipo package-private não é muito útil para quem chama de fora, então mantenha sua superfície pública coerente.

Próximo: membros estáticos

Até agora, cada campo e método aqui pertence a uma instância - você cria um objeto com new e então chama métodos nele. Mas às vezes um valor ou comportamento pertence à classe como um todo, compartilhado entre todas as instâncias, como um contador de quantos objetos existem. É para isso que serve a palavra-chave static, e é o que vem a seguir.

Perguntas frequentes

Quais são os quatro modificadores de acesso em Java?

public, private, protected e o default (sem palavra-chave, também chamado de package-private). public é visível em todo lugar, private apenas dentro da mesma classe, protected dentro do pacote mais as subclasses, e default apenas dentro do mesmo pacote.

Qual é a diferença entre public e private em Java?

public significa que qualquer código em qualquer lugar pode acessar o membro. private significa que apenas o código dentro da mesma classe pode: subclasses e outras classes nem conseguem enxergá-lo. Normalmente você deixa os campos private e os expõe por meio de métodos public.

O que significa quando um campo Java não tem modificador de acesso?

Nenhuma palavra-chave significa acesso default (package-private): o membro é visível para todas as classes do mesmo pacote, mas invisível fora dele. É mais restrito que public, porém mais aberto que private - e é fácil esquecer de colocar por acidente, então seja deliberado quanto a isso.

Coddy programming languages illustration

Aprenda a programar com o Coddy

COMEÇAR