A linguagem Java fornece muitos modificadores, que são divididos principalmente nas duas categorias a seguir:
Modificadores são usados para definir classes, métodos ou variáveis e geralmente são colocados no início da instrução. Ilustramos isso através do seguinte exemplo:
public class className { // ... } private boolean myFlag; static final double weeks = 9.5; protected static final int BOXWIDTH = 42; public static void main(String[] arguments) { // 方法体}
Em Java, os controles de acesso podem ser usados para proteger o acesso a classes, variáveis, métodos e construtores. Java suporta 4 direitos de acesso diferentes.
O padrão, também chamado de padrão, é visível no mesmo pacote e não usa nenhum modificador.
Private, especificado com o modificador private, visível na mesma classe.
Público, especificado com o modificador public, visível para todas as classes.
Protegido, especificado com o modificador protected, visível para classes e todas as subclasses no mesmo pacote.
Variáveis e métodos declarados com modificadores de acesso padrão são visíveis para classes no mesmo pacote. Variáveis na interface são declaradas implicitamente como public static final
e os métodos na interface têm permissões de acesso public
por padrão.
Exemplo:
Conforme mostrado no exemplo a seguir, variáveis e métodos podem ser declarados sem quaisquer modificadores.
String version = "1.5.1"; boolean processOrder() { return true; }
O modificador de acesso privado é o nível de acesso mais restritivo, portanto métodos, variáveis e construtores declarados como privados só podem ser acessados pela classe a qual pertencem, e classes e interfaces não podem ser declaradas como privadas.
Variáveis declaradas como tipos de acesso privado só podem ser acessadas por classes externas através dos métodos getter públicos da classe.
O uso do modificador de acesso privado é usado principalmente para ocultar os detalhes de implementação da classe e proteger os dados da classe.
A classe a seguir usa o modificador de acesso privado:
public class Logger { private String format; public String getFormat() { return this.format; } public void setFormat(String format) { this.format = format; } }
No exemplo, a variável de formato na classe Logger é uma variável privada, portanto, outras classes não podem obter e definir diretamente o valor da variável. Para permitir que outras classes operem esta variável, dois métodos public
são definidos: getFormat()
(retorna o valor do formato) e setFormat(String)
(define o valor do formato)
Classes, métodos, construtores e interfaces declaradas como públicas podem ser acessadas por qualquer outra classe.
Se diversas classes públicas que acessam umas às outras forem distribuídas em pacotes diferentes, será necessário importar o pacote onde a classe pública correspondente está localizada. Devido à herança de classe, todos os métodos e variáveis públicas de uma classe podem ser herdados por suas subclasses.
As seguintes funções usam controle de acesso público:
public static void main(String[] arguments) { // ... }
O método main() do programa Java deve ser definido como público, caso contrário, o interpretador Java não será capaz de executar a classe.
Variáveis, métodos e construtores declarados como protegidos podem ser acessados por qualquer outra classe no mesmo pacote ou por subclasses em pacotes diferentes.
Modificadores de acesso protegidos não podem modificar classes e interfaces. Métodos e variáveis de membro podem ser declarados protegidos, mas variáveis de membro e métodos de membro de interfaces não podem ser declarados protegidos.
As subclasses podem acessar métodos e variáveis declaradas com o modificador Protected, protegendo assim classes não relacionadas do uso desses métodos e variáveis.
A classe pai a seguir usa o modificador de acesso protegido e a subclasse substitui o método openSpeaker() da classe pai.
class AudioPlayer { protected boolean openSpeaker(Speaker sp) { // 实现细节} } class StreamingAudioPlayer extends AudioPlayer { boolean openSpeaker(Speaker sp) { // 实现细节} }
Se o método openSpeaker() for declarado privado, outras classes além de AudioPlayer não poderão acessar este método.
Se openSpeaker() for declarado como público, todas as classes poderão acessar este método.
Se quisermos que o método seja visível apenas para as subclasses de sua classe, declare o método como protegido.
Observe as seguintes regras para herança de método:
Os métodos declarados como públicos na classe pai também devem ser públicos na classe filha.
Os métodos declarados como protegidos na classe pai são declarados como protegidos ou públicos na subclasse. Não pode ser declarado privado.
Os métodos declarados como privados na classe pai não podem ser herdados.
Para implementar algumas outras funções, Java também fornece muitos modificadores de não acesso.
modificador estático, usado para criar métodos de classe e variáveis de classe.
O modificador final é usado para modificar classes, métodos e variáveis. As classes modificadas por final não podem ser herdadas, os métodos modificados não podem ser redefinidos por classes herdadas e as variáveis modificadas são constantes e não podem ser modificadas.
modificador abstrato, usado para criar classes abstratas e métodos abstratos.
Os modificadores sincronizados e voláteis são usados principalmente para programação de threads.
Variáveis estáticas:
A palavra-chave static é usada para declarar variáveis estáticas que são independentes de objetos. Não importa quantos objetos uma classe instancie, há apenas uma cópia de suas variáveis estáticas. Variáveis estáticas também são conhecidas como variáveis de classe. Variáveis locais não podem ser declaradas como variáveis estáticas.
Método estático:
A palavra-chave static é usada para declarar métodos estáticos independentes de objetos. Os métodos estáticos não podem usar variáveis não estáticas da classe. Os métodos estáticos obtêm dados de uma lista de parâmetros e depois calculam os dados.
O acesso às variáveis e métodos de classe pode ser acessado diretamente usando classname.variablename
e classname.methodname
.
Conforme mostrado no exemplo a seguir, o modificador estático é usado para criar métodos de classe e variáveis de classe.
public class InstanceCounter { private static int numInstances = 0; protected static int getCount() { return numInstances; } private static void addInstance() { numInstances++; } InstanceCounter() { InstanceCounter.addInstance(); } public static void main(String[] arguments) { System.out.println("Starting with " + InstanceCounter.getCount() + " instances"); for (int i = 0; i < 500; ++i){ new InstanceCounter(); } System.out.println("Created " + InstanceCounter.getCount() + " instances"); } }
Os resultados de edição da execução do exemplo acima são os seguintes:
Started with 0 instances Created 500 instances
variáveis finais:
As variáveis finais podem ser inicializadas explicitamente e apenas uma vez. As referências a objetos declarados como finais não podem apontar para objetos diferentes. Mas os dados do objeto final podem ser alterados. Em outras palavras, a referência do objeto final não pode ser alterada, mas o valor interno pode ser alterado.
O modificador final é frequentemente usado junto com o modificador estático para criar constantes de classe.
Exemplo:
public class Test{ final int value = 10; // 下面是声明常量的实例public static final int BOXWIDTH = 6; static final String TITLE = "Manager"; public void changeValue(){ value = 12; //将输出一个错误} }
O método Final em uma classe pode ser herdado por subclasses, mas não pode ser modificado por subclasses.
O principal objetivo de declarar um método final é evitar que o conteúdo do método seja modificado.
Conforme mostrado abaixo, declare o método usando o modificador final.
public class Test{ public final void changeName(){ // 方法体} }
As classes finais não podem ser herdadas e nenhuma classe pode herdar quaisquer características de uma classe final.
Exemplo:
public final class Test { // 类体}
Classe abstrata:
Classes abstratas não podem ser usadas para instanciar objetos. O único propósito de declarar uma classe abstrata é estendê-la no futuro.
Uma classe não pode ser modificada por abstract e final ao mesmo tempo. Se uma classe contém métodos abstratos, a classe deve ser declarada como uma classe abstrata, caso contrário ocorrerá um erro de compilação.
Classes abstratas podem conter métodos abstratos e métodos não abstratos.
Exemplo:
abstract class Caravan{ private double price; private String model; private String year; public abstract void goFast(); //抽象方法public abstract void changeColor(); }
Um método abstrato é um método sem qualquer implementação. A implementação específica do método é fornecida pela subclasse. Métodos abstratos não podem ser declarados finais e estáticos.
Qualquer subclasse que herde uma classe abstrata deve implementar todos os métodos abstratos da classe pai, a menos que a subclasse também seja uma classe abstrata.
Se uma classe contém vários métodos abstratos, a classe deve ser declarada abstrata. Uma classe abstrata não precisa conter métodos abstratos.
A declaração de um método abstrato termina com ponto e vírgula, por exemplo: public abstract sample();
Exemplo:
public abstract class SuperClass{ abstract void m(); //抽象方法} class SubClass extends SuperClass{ //实现抽象方法void m(){ ......... } }
O método declarado com a palavra-chave sincronizada só pode ser acessado por um thread ao mesmo tempo. O modificador Sincronizado pode ser aplicado a quatro modificadores de acesso.
Exemplo:
public synchronized void showDetails(){ ....... }
Quando o objeto serializado contém uma variável de instância que é modificada por transitório, a Java Virtual Machine (JVM) ignora essa variável específica.
Este modificador está incluído na instrução que define a variável e é usado para pré-processar o tipo de dados da classe e da variável.
Exemplo:
public transient int limit = 55; // will not persist public int b; // will persist
Cada vez que uma variável de membro modificada por volátil é acessada por um thread, o valor da variável de membro é forçado a ser relido na memória compartilhada. Além disso, quando uma variável de membro é alterada, o thread é forçado a gravar o valor alterado de volta na memória compartilhada. Dessa forma, a qualquer momento, dois threads diferentes sempre veem o mesmo valor de uma variável membro.
Uma referência de objeto volátil pode ser nula.
Exemplo:
public class MyRunnable implements Runnable { private volatile boolean active; public void run() { active = true; while (active) // line 1 { // 代码} } public void stop() { active = false; // line 2 } }
Geralmente, o método run() é chamado em um thread e o método stop() é chamado em outro thread. Se o valor de ativo na linha 1 do buffer for usado, o loop não irá parar quando ativo na linha 2 for definido como falso.