Modificadores
Na linguagem Java podemos utilizadas algumas palavras-chave para
modificar o modo como são declaradas classes, métodos e
variáveis. Veremos como aplicar cada um desses modificadores no
texto a seguir.
Classes
Para classes, existem apenas dois modificadores de acesso. Ao omitir o
nome do modificador em sua declaração, temos o chamado default
ou package, que indica que a classe estará
visível
para qualquer outra classe que esteja dentro do mesmo pacote. A outra
opção é deixar o acesso public, permitindo
que todas as classes tenham acesso a esta classe. Para acessar uma
classe public que esteja em um pacote diferente, é
necessário fazer o import ou utilizar seu nome completo.
Há também outros modificadores que podem ser utilizados
para classes. O strictfp força todos os métodos a
aderirem as regras IEE754, tornando possível saber exatamente
como números float e double irão se comportar, de forma
independente da plataforma. O final impede que a classe seja
herdada, sendo utilizado para impedir o overriding, ou seja,
que os métodos sejam sobrescritos por subclasses e depois
utilizados como se fossem da super classe através de
polimorfismo. É utilizado em algumas classes da API do Java,
como a String, para podermos sempre confiar em seu comportamento.
Porém vai contra os princípios de
orientação a objeto e por isso só deve ser
utilizado quando realmente necessário. E o abstract
significa justamente o contrário, pois neste caso a classe
não pode ser instanciada, sendo possível apenas herdar
esta classe para utilizá-la através de uma subclasse.
Modificadores de acesso de métodos e variáveis
Antes de iniciar a explicação sobre os modificadores de
variáveis, é necessário entender que existem dois
tipos delas:
Variáveis de instância são campos do objeto,
declarados fora de qualquer método e inicializados quando
é instanciado um objeto da classe. Também são
chamadas de campos, propriedades ou atributos.
Variáveis locais são as declaradas dentro de um
método. Seu ciclo de vida está relacionado ao seu escopo
(no máximo o do método) e elas sempre ficam no stack.
Antes de tentar utilizá-las é necessário
inicializá-las explicitamente, em uma parte atingível do
código (fora de um if, por exemplo), senão o compilador
retornará um erro. Variáveis locais também
são chamadas de variáveis de stack, temporárias,
automáticas ou de método.
É permitido que uma variável local tenha o mesmo nome de
uma variável de instância. Neste caso, utilize a
referência this para acessar a variável de
instância.
Métodos e variáveis de instância são
chamados de "membros" e podem utilizar modificadores de acesso, ao
contrário de variáveis locais. Porém, se a classe
em si não estiver visível para outra classe, seus membros
também não estarão visíveis,
independentemente de qualquer modificador utilizado neles. Os
modificadores de acesso aplicáveis são:
- public: qualquer classe pode acessar
- private: não pode ser acessado por nenhuma outra
classe. Como não é visto pelas subclasses, não
se aplica regras de overriding.
- default (não declarando explicitamente nenhum dos
outros modificadores): acessível somente por classes do mesmo
pacote.
- protected: acessível por classes do mesmo pacote ou
através de herança. Os membros herdados não
são acessíveis a outras classes fora do pacote em que
foram declarados. Como o conceito de protected tem alguns detalhes que
podem não ficar claros à primeira vista, veja estes
exemplos:
package pai;
public class Pai{
protected int teste = 9;
}
// Teste 1:
package filho;
import pai.Pai;
public class Filho extends Pai {
public void teste() {
System.out.println(teste); // OK, usa a variável herdada
Pai p = new Pai();
System.out.println(p.teste); // ERRO: teste has protected access in pai.Pai
}
}
// Teste 2:
package filho; // Funcionaria se o package fosse o pai
public class Cunhado{
void teste(){
Filho filho = new Filho();
System.out.println(filho.teste); // ERRO: teste has protected access in pai.Pai
}
}
Existem ainda outros modificadores de métodos. O final
impede que o método seja sobrescrito (overriding) na subclasse.
Ele também pode ser utilizado nos argumentos do método,
significando que estes não poderão ter seu valor ou
referência alterados. O abstract indica que método
não foi implementado. Neste caso é necessário
utilizar ponto e vírgula ao invés das chaves na sua
declaração. Existindo algum método abstrato, a
classe também deve ser declarada abstrata. A primeira subclasse
concreta será obrigada a implementar os métodos
abstratos, seguindo exatamente a mesma assinatura do método.
Métodos abstratos não podem ser static, final, private,
synchronized, strictfp ou native. Um método synchronized
só pode ser acessado por uma thread de cada vez. O native
indica que o método é implementado em uma linguagem
dependente de plataforma. E strictfp força o
método a aderir as regras IEE754, como explicado para as
classes.
No caso de variáveis, o modificador final
impossibilita que a variável seja reinicializada com outro
valor.
Lembre-se de que caso de objetos, a referência ao objeto que
é final, não o objeto em si. Se a variável for de
instância, é necessário fornecer um valor na hora
de declará-la ou em todos os construtores da classe, caso
contrário ocorrerá um erro de compilação.
Variáveis de interface sempre são final e precisam ter
seu valor declarado. O transient é aplicável
apenas a variáveis de instância, e faz a JVM ignorar a
variável quando tenta serializar seu objeto. O volatile
também só é aplicável a variáveis de
instância e indica que uma thread acessando esta variável
precisa sempre sincronizar o valor de sua cópia local com a
cópia principal da memória.
O modificador static
Variáveis e métodos marcados como static
pertencem
à classe, ao invés de a alguma instância
particular. É possível utilizá-los sem existir
nenhuma instância da classe, chamando diretamente pelo nome da
classe. Quando há instâncias, a variável static
irá ser compartilhada entre todas elas, existindo apenas uma
cópia por classe.
Métodos static não conseguem acessar diretamente
variáveis ou métodos que não sejam static, pois
eles pertencem a classe e não saberiam de qual instância
utilizar. Por isso, é necessário instanciar um objeto e
utilizá-lo explicitamente neste caso. Métodos static
também não podem ser overriden, como será
explicado quando falarmos de polimorfismo (mas podem ser redefinidos).
Coisas que podem ser marcadas como static: métodos,
variáveis de instância e classes aninhadas de nível
superior
Coisas que não podem ser marcadas como static:
construtores, classes, interfaces, inner classes (incluindo seus
métodos e variáveis) e variáveis locais
por
Vanessa Sabino
Fonte: Sun Certified Programmer & Developer for Java 2 - Kathy
Sierra & Bert Bates