Asserções (assertions)

em 06/08/2002 , por Luthiano Vasconcelos
Introdução
O lançamento do Java 2 Standard Edition 1.4 trouxe algumas mudanças que agregaram importantes funcionalidades à linguagem Java. Dentre elas, podemos destacar as exceções encadeadas, as expressões regulares, a API de log, e as asserções. Esse artigo se propõe a esclarecer o princípio básico das asserções e demonstrar como elas podem auxiliar o programador a escrever aplicações estáveis e robustas. O uso de asserções não é novo, já que há anos esse recurso está disponível em várias linguagens orientadas a objeto, como a linguagem Eiffel. As asserções, como as exceções, derivam do conceito de "Projeto por Contrato", que tem sido amplamente implementado na maioria das linguagens orientadas a objeto. A teoria do "Projeto por Contrato" prega que uma aplicação é criada ou planejada de acordo com um contrato (ou especificação) acordado entre o desenvolvedor e o cliente sobre o funcionamento da aplicação. Alguns estudos apontam que a utilização das asserções durante a codificação de uma aplicação é um dos mais rápidos e eficientes métodos de detectar e corrigir falhas. Como benefício adicional, asserções servem para documentar o funcionamento interno da aplicação, melhorando substancialmente sua manutenibilidade. Outra consideração importante é que o assunto das asserções é amplamente cobrado na mais recente versão do exame de certificação da Sun (Programmer for the Java 2 Platform 1.4).
Afinal, o que são as asserções?
Segundo a Sun: "Uma asserção é um comando contendo uma expressão booleana que o programador acredita ser verdadeira no momento que o comando é executado". Ou seja, a asserção é um recurso da linguagem para testar as suposições feitas pelo programador dentro do código.
Então, as asserções substituem as exceções?
Não, definitivamente, não. As exceções Java são usadas inicialmente para tratar condições incomuns ocorridas durante a execução de uma aplicação. Por sua vez, as asserções são usadas para especificar condições que o programador assume que sejam verdadeiras para o correto funcionamento de uma aplicação. Elas auxiliam no aperfeiçoamento da aplicação, durante a fase de desenvolvimento.
Como foi implementado?
Existe um grande debate neste ponto. Asserções em java ganhou sua própria palavra chave. Muitas pessoas poderiam se perguntar, porque não foi criada uma API ao invés da palavra chave, já que pela API você poderia ativar e desativar as asserções. A resposta da SUN é que todas as alternativas foram estudadas, e com a palavra chave, se você desabilitá-la, a execução ganha performance!
Como usar asserções?
A instrução de asserção, no Java, tem duas sintaxes:

A primeira forma é a mais simplificada, recebe uma expressão booleana como um argumento. A expressão é condição que o programador deseja que seja verdadeira. Quando o sistema executa a asserção, a expressão é avaliada, e se ela for falsa, uma exceção AssertionError é lançada. Caso contrário, o processamento da aplicação prossegue normalmente.

A segunda forma é mais descritiva. O primeiro argumento recebe uma expressão booleana, enquanto a segunda expressão deverá ser um valor ou o resultado da execução de um método, que será fornecido para o construtor da classe AssertionError. O compilador irá lançar um erro se a segunda expressão não retornar nenhum valor. Como discutido antes, uma asserção não é um substituto para uma exceção e não pode ser usada para exibir erros para o usuário. Erros em nível de usuário precisam ser passados para a apropriada rotina de tratamento de erros e eles precisam ser apresentados ao usuário de forma mais elegante.
Onde usar as asserções
As asserções podem ser usadas para garantir que um programa se comporte sob uma determinada condição, e lance um erro quando a condição for violada. Por exemplo, a instrução de asserção abaixo garante que a idade não será um número negativo.

Elas também podem ser usadas para verificar a possibilidade de alcançar instruções em um método. No exemplo abaixo o comando assert é incluído em um ponto do código que não deverá ser alcançado. Porém, se por alguma razão o código é executado, nós saberemos que um sério problema ocorreu, e a mensagem do segundo argumento do assert irá aparecer!

Seguindo os princípios do "Projeto por Contrato", instruções assert podem ser usadas para verificar pré-condições, ou seja, se os valores ou parâmetros passados para um método são adequados para o correto funcionamento do método. Porém, as instruções assert não devem ser usadas para verificar parâmetros de métodos públicos. As instruções assert também podem ser usadas para verificar pós-condições, ou seja, se os valores de retorno dos métodos são válidos ou atendem às expectativas do programador.
Onde não usar asserções
Asserções não devem ser usadas para verificar argumentos em métodos públicos. Argumentos incorretos devem lançar a exceção apropriada (IllegalArgumentException) ao invés do genérico AssertionError. Caso contrário, se você desabilitar as assertions, poderá ter graves erros, aceitando argumentos inválidos.
Compilando programas com asserções
Por definição, as asserções são desativadas durante a compilação usando o compilador J2SE 1.4. Dessa forma, para compilar uma classe Java com asserções é necessário incluir a opção -source 1.4 na linha de comando.

Isso evita problemas de compatibilidade com aplicações que já tenham usado a palavra assert como identificador. Um arquivo Java precisa ser compilado com as asserções ativadas para que o programa possa executar as asserções em tempo de execução.
Ativando e desativando as asserções
Por definição, o processamento das instruções de asserção também está desativado no novo ambiente de execução do JDK 1.4. Para ativar as asserções, é necessário especificar o parâmetro -ea na linha de comando:

Conclusão
Asserções na nova especificação J2SE 1.4 são uma inclusão bem vinda, mas ainda resta ver como a comunidade de desenvolvimento irá reagir a ela, e como iniciará a usá-la. A idéia de ter asserções tem sido considerada desde a primeira versão do Java. A Sun admite que não o fizera antes por questões de tempo de implementação. Programadores familiarizados com linguagens orientadas a objeto como Eiffel e Smalltalk provavelmente já esperavam as asserções, enquanto para a nova geração de programadores o recurso apresenta-se como um conceito novo que precisa ser explorado e implementado. Além disso, a idéia de incluir as asserções como uma mudança na especificação mostra o comprometimento da Sun em fazê-la como uma mudança permanente e irreversível.
Mais informações
http://java.sun.com/j2se/1.4/docs/guide/lang/assert.html