Asserções
A partir do Java 1.4 foi criado um mecanismo para o programador testar
hipóteses, durante o desenvolvimento, que ele assume que
não irão acontecer uma vez que o programa esteja
completo.
Por exemplo, para um determinado método supõe-se que o
parâmetro passado para ele não pode ser um número
negativo. Seria possível testar seu valor com um if/else ou
então criar algum tipo de mecanismo que gere uma
exceção se o número for negativo, mas isso teria
um impacto na performance se fosse deixado no programa final e daria um
certo trabalho para tirar estes testes antes de entregar o produto. As
asserções permitem que você teste suas
hipóteses durante o desenvolvimento sem causar nenhum impacto
quando o programa é entregue, não deixando overhead para
a performance ou código para debug que deveria ser removido
manualmente.
Veja um exemplo de seu uso:
private void metodo(int num) {
assert (num>=0); // gera um AssertionError caso o teste não seja verdadeiro
// resto do codigo supondo que num é positivo
}
Além de deixar o código mais limpo e menor, elas ficam
inativas a não ser que sejam especificamente habilitadas.
O mecanismo de asserções funciona de forma muito simples:
você faz a asserção de que alguma coisa é
verdadeira. Se for, o código continua normalmente. Caso
contrário, a execução é interrompida e gera
um AssertionError (que nunca deverá ser tratado em seu
código). Para ter mais informação sobre a causa do
AssertionError, você pode colocar uma segunda cláusula,
separada por dois pontos (:), como mostrado no exemplo abaixo:
private void método(int x, int y) {
assert (y > x): "y vale " + y + " e x vale " + x;
// mais código assumindo que y é maior do que x
}
A primeira cláusula, a que será testada, deve ser sempre
uma expressão boleana. A segunda pode ser qualquer coisa que
resulte em um valor, e será usada para gerar uma mensagem
(String) que irá aparecer no stack trace do erro.
As asserções estão desabilitadas por
padrão, portanto a palavra assert pode ser utilizada como
identificador (nome de variáveis, métodos, etc). Quando
habilitadas, ela torna-se uma palavra reservada do Java e o compilador
só aceitará a sintaxe correta para o mecanismo de
asserções. Para isso, compile seu código com a
opção -source 1.4 (se esta opção for
omitida, será considerado -source 1.3).
Exemplo:
javac -source 1.4 Teste.java
Na hora de executar a aplicação, novamente será
necessário informar que você quer habilitar as
asserções, que ficam desabilitadas por padrão.
Para isso, utilize a opção -ea ou -enableassertions. A
opção padrão corresponde a -da ou
-disableassertions
Exemplo:
java -ea Teste
É até possível habilitar/desabilitar
asserções para classes e pacotes específicos, como
mostrado no exemplo abaixo:
java -ea -da:com.portaljava...
Neste caso, as asserções estão habilitadas para
todas as classes, exceto aquelas que estão no pacote
com.portaljava ou algum subpacote dele.
O AssertionError é uma subclasse de Throwable, portanto poderia
ser pego através de um bloco catch, mas isso não é
considerado uma boa prática de programação.
Utilize Exceptions se for um erro a ser tratado pelo programa. No exame
de certificação, aparecendo a palavra appropriate
ou correct, considere o uso determinado oficialmente pela Sun,
e
não apenas se o código funciona ou não.
Mais algumas dicas sobre usos apropriados de asserções:
- Não utilize asserções para validar
argumentos de um método público, uma vez que você
não tem controle sobre como ele será chamado. Isto inclui
argumentos passados pela linha de comando. Neste caso, é
importante que o próprio método valide os argumentos que
está recebendo, pois as asserções podem estar
desabilitadas durante a execução. Uma boa
solução é lançar algo como uma
"IllegalArgumentException" caso o argumento não seja
válido.
- Não utilize expressões de teste que alteram o
estado do objeto, por exemplo chamando um método que retorna um
boleano mas antes disso altera o valor de alguma variável. Como
não é garantido que a expressão será
executada, não é recomendado que seu código tenha
um comportamento diferente dependendo das asserções
estarem habilitadas ou não.
- Utilize asserções para métodos privados,
em que provavelmente você já está utilizando a
lógica correta no método que irá chamá-lo.
- Utilize asserções para checar casos que
você sabe que nunca devem acontecer, como por exemplo um valor
inválido de um bloco switch. Neste caso, basta colocar "assert
false" na parte do código pela qual ele não deveria
passar.