Desenvolvimento - Java

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.

por Vanessa Sabino



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, temporarias, 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: quaquer classe pode acessar
  • private: não pode ser acessado por nenhuma outra classe. Como não é visto pelas subclasses, não aplica-se 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:

Listagem 1: Exemplo de uso de atributo protegido

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 utilizando 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 impossiblita 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.

Vanessa Sabino

Vanessa Sabino