Qual é o especificador de acesso padrão em Java?

108

Acabei de começar a ler um livro sobre Java e me perguntei; qual especificador de acesso é o padrão, se nenhum for especificado?

Bennedich
fonte
O termo correto é 'modificador de acesso'. A palavra 'especificador' não aparece no JLS.
Marquês de Lorne

Respostas:

116

A visibilidade padrão é conhecida como “pacote-privado” (embora você não possa usar isso explicitamente), o que significa que o campo estará acessível de dentro do mesmo pacote ao qual a classe pertence.

Como o mdma apontou, não é verdade para membros da interface, para os quais o padrão é "público".

Veja os especificadores de acesso do Java

KeatsPeeks
fonte
25
incorreto - não é verdade para membros da interface. o acesso padrão é então público
mdma
2
Na verdade, ele é conhecido como 'pacote privado'. Os sites de terceiros não são referências normativas. Você deve citar apenas o JLS.
Marquês de Lorne
81

O especificador padrão depende do contexto.

Para classes e declarações de interface, o padrão é package private. Isso fica entre protegido e privado, permitindo apenas acesso a classes no mesmo pacote. (protegido é assim, mas também permitindo acesso a subclasses fora do pacote.)

class MyClass   // package private
{
   int field;    // package private field

   void calc() {  // package private method

   }
}

Para membros da interface (campos e métodos), o acesso padrão é público. Mas observe que a própria declaração da interface é padronizada como pacote privado.

interface MyInterface  // package private
{
   int field1;         // static final public

   void method1();     // public abstract
}

Se tivermos a declaração

public interface MyInterface2 extends MyInterface
{

}

As classes que usam MyInterface2 podem ver o campo1 e o método1 da superinterface, porque são públicas, embora não possam ver a declaração da própria MyInterface.

mdma
fonte
1
"Pacote privado" (às vezes escrito no código-fonte como /* pp */) é apenas um nome conveniente para acesso padrão . Não é o nome JLS.
Tom Hawtin - tackline de
10
@Tom - correto, o JLS usa "acesso padrão". Eu poderia ter escrito "o padrão é o acesso padrão". Mas isso não pareceu muito útil!
mdma de
16

Se nenhum especificador de acesso for fornecido, é o acesso em nível de pacote (não há especificador explícito para isso) para classes e membros de classe. Os métodos de interface são implicitamente públicos.

Michael Borgwardt
fonte
9

A visibilidade padrão (sem palavra-chave) é pacote, o que significa que estará disponível para todas as classes localizadas no mesmo pacote.

Uma observação interessante é que protected não limita a visibilidade para as subclasses, mas também para as outras classes no mesmo pacote

Johannes Wachter
fonte
8

Depende do que a coisa é.

  • Tipos de nível superior (ou seja, classes, enums, interfaces e tipos de anotação não declarados dentro de outro tipo) são privados de pacote por padrão. ( JLS §6.6.1 )

  • Em classes, todos os membros (isso significa campos, métodos e declarações de tipo aninhado) e construtores são privados do pacote por padrão. ( JLS §6.6.1 )

    • Quando uma classe não tem um construtor declarado explicitamente, o compilador insere um construtor de argumento zero padrão que tem o mesmo especificador de acesso da classe . ( JLS §8.8.9 ) O construtor padrão é comumente declarado incorretamente como sendo sempre público, mas em casos raros isso não é equivalente.
  • Em enums, os construtores são privados por padrão. Na verdade, os construtores enum devem ser privados, e é um erro especificá-los como públicos ou protegidos. As constantes de enum são sempre públicas e não permitem nenhum especificador de acesso. Outros membros de enums são privados do pacote por padrão. ( JLS §8.9 )

  • Em interfaces e tipos de anotação, todos os membros (novamente, isso significa campos, métodos e declarações de tipo aninhado) são públicos por padrão. Na verdade, os membros das interfaces e tipos de anotação devem ser públicos e é um erro especificá-los como privados ou protegidos. ( JLS §9.3 a 9.5 )

  • As classes locais são classes nomeadas declaradas dentro de um método, construtor ou bloco inicializador. Eles têm como escopo o bloco {.. }no qual são declarados e não permitem nenhum especificador de acesso. ( JLS §14.3 ) Usando reflexão, você pode instanciar classes locais de outro lugar, e elas são privadas de pacote , embora eu não tenha certeza se esse detalhe está no JLS.

  • Classes anônimas são classes personalizadas criadas com as newquais especificam um corpo de classe diretamente na expressão. ( JLS §15.9.5 ) Sua sintaxe não permite nenhum especificador de acesso. Usando reflexão, você pode instanciar classes anônimas de outro lugar, e tanto elas quanto seus construtores gerados são privados do pacote , embora eu não tenha certeza se esse detalhe está no JLS.

  • Os blocos inicializadores estáticos e de instância não têm especificadores de acesso no nível de linguagem ( JLS §8.6 e 8.7 ), mas os blocos inicializadores estáticos são implementados como um método denominado <clinit>( JVMS §2.9 ), portanto, o método deve, internamente, ter algum especificador de acesso. Eu examinei classes compiladas por javac e pelo compilador do Eclipse usando um editor hexadecimal e descobri que ambos geram o método como um pacote privado . No entanto, você não pode chamar <clinit>()dentro da linguagem porque os caracteres <e >são inválidos em um nome de método, e os métodos de reflexão são conectados para negar sua existência, portanto, efetivamente, seu especificador de acesso é nenhum acesso . O método só pode ser chamado pela VM, durante a inicialização da classe.Os blocos inicializadores de instância não são compilados como métodos separados; seu código é copiado em cada construtor, portanto, eles não podem ser acessados ​​individualmente, mesmo por reflexão.

Boann
fonte
7

default é uma palavra-chave usada como modificador de acesso para métodos e variáveis.
Usar este modificador de acesso tornará sua classe, variável, método ou construtor acessível da própria classe ou pacote, ele também será definido se nenhum modificador de acesso estiver presente.

  Access Levels
    Modifier    Class   Package Subclass  EveryWhere
    public        Y        Y       Y         Y
    protected     Y        Y       Y         N
    default       Y        Y       N         N
    private       Y        N       N         N

se você usar um padrão em uma interface, você será capaz de implementar um método como este exemplo

public interface Computer {    
    default void Start() {
        throw new UnsupportedOperationException("Error");
    }    
}

No entanto, só funcionará a partir da versão 8 do Java

Documentação Oficial

Modificadores de acesso em Java

Amadeu Antunes
fonte
3

Veja aqui para mais detalhes. O padrão não é privado / público / protegido, mas uma especificação de acesso completamente diferente. Não é amplamente utilizado e prefiro ser muito mais específico em minhas definições de acesso.

Brian Agnew
fonte
3

o especificador de acesso padrão é pacote. As classes podem acessar os membros de outras classes no mesmo pacote. mas fora do pacote ele aparece como privado

abhi
fonte
3

Aqui está uma citação sobre a visibilidade no nível do pacote de uma entrevista com James Gosling, o criador do Java:

Bill Venners : Java tem quatro níveis de acesso. O padrão é pacote. Sempre me perguntei se tornar o acesso ao pacote padrão era conveniente porque as três palavras-chave que as pessoas de C ++ já conheciam eram private, protected e public. Ou se você teve algum motivo específico que acha que o acesso ao pacote deve ser o padrão.

James Gosling : Um pacote geralmente é um conjunto de coisas que são meio que escritas juntas. De maneira geral, eu poderia ter feito uma de duas coisas. Uma era forçar você a sempre colocar uma palavra-chave que desse o domínio. Ou eu poderia ter um valor padrão. E então a questão é: o que torna um padrão sensato? E eu tendo a ir para o que é menos perigoso.

Então, público teria sido uma coisa muito ruim tornar o padrão. Privado provavelmente teria sido uma coisa ruim tornar um padrão, apenas porque as pessoas na verdade não escrevem métodos privados com tanta frequência. E a mesma coisa com protegido. E ao olhar para um monte de código que eu tinha, decidi que a coisa mais comum que era razoavelmente segura estava no pacote. E C ++ não tinha uma palavra-chave para isso, porque eles não tinham noção de pacotes.

Mas eu gostei mais do que da noção de amigos, porque com amigos você meio que tem que enumerar quem são todos os seus amigos, então se você adicionar uma nova classe a um pacote, então você geralmente acaba tendo que ir para todos os aulas naquele pacote e atualizar seus amigos, o que eu sempre achei ser um pé no saco.

Mas a própria lista de amigos causa uma espécie de problema de versão. E então havia essa noção de uma classe amigável. E a coisa boa que eu estava tornando isso o padrão - vou resolver o problema, então qual deveria ser a palavra-chave?

Por um tempo, houve realmente uma palavra-chave amigável. Mas como todos os outros começam com "P", era "amigável" com um "PH". Mas isso durou apenas um dia.

http://www.artima.com/intv/gosling2P.html

Vitalii Fedorenko
fonte
2

Atualizar o uso de palavras-chave do Java 8default : como muitos outros notaram, a visibilidade padrão (sem palavra-chave)

o campo estará acessível de dentro do mesmo pacote ao qual a classe pertence.

Não deve ser confundido com o novo recurso Java 8 ( Métodos Padrão ) que permite que uma interface forneça uma implementação quando rotulada com a defaultpalavra - chave.

Veja: modificadores de acesso

Ahmad Sanie
fonte
-2

Em primeiro lugar, deixe-me dizer uma coisa que não existe um termo como "especificador de acesso" em java. Devemos chamar tudo de "Modificadores". Como sabemos que final, static, synchronized, volatile .... são chamados de modificadores, mesmo Public, private, protected, default, abstract também devem ser chamados de modificadores. O padrão é um desses modificadores onde a existência física não existe, mas nenhum modificador é colocado, então ele deve ser tratado como modificador padrão.

Para justificar, pegue um exemplo:

public class Simple{  
    public static void main(String args[]){  
     System.out.println("Hello Java");  
    }  
}  

O resultado será: Hello Java

Agora mude público para privado e veja qual erro do compilador você obtém: Diz "Modificador privado não é permitido aqui" A conclusão é que alguém pode estar errado ou algum tutorial pode estar errado, mas o compilador não pode estar errado. Portanto, podemos dizer que não existe um termo especificador de acesso em java, tudo são modificadores.

Sagar Raut
fonte
A primeira frase é exata, mas o fato de que uma classe externa não pode ser privada não prova que não existe especificador de acesso em Java.
Marquês de Lorne
@EJP Este é apenas um exemplo. O que estou dizendo é que o termo especificador de acesso é usado em outras linguagens como c, ponto net etc, mas o termo técnico em java para isso é modificadores. Se você usa eclipse ou qualquer outro IDE, pode ver que, no momento da criação de uma nova classe, somos solicitados a fornecer o nome dos modificadores e na lista eles fornecem público, privado, abstrato, etc.
Sagar Raut
No meu exemplo, o que tento dizer é que o compilador dá uma mensagem de erro: modificadores privados não são permitidos, não está dando mensagem como o especificador de acesso privado não permitido. Portanto, o termo técnico que devemos dizer é modificadores em java, não especificador de acesso em java
Sagar Raut