Neste tutorial, aprenderemos sobre a instrução Java assert (Java assertions) com a ajuda de exemplos.
Asserções em Java ajudam a detectar bugs testando o código que supomos ser verdadeiro.
Uma afirmação é feita usando a assert
palavra - chave.
Sua sintaxe é:
assert condition;
Aqui, condition
está uma expressão booleana que assumimos ser verdadeira quando o programa é executado.
Habilitando Asserções
Por padrão, as asserções são desabilitadas e ignoradas no tempo de execução.
Para habilitar asserções, usamos:
java -ea:arguments
OU
java -enableassertions:arguments
Quando as asserções estão habilitadas e a condição é true
, o programa é executado normalmente.
Mas se a condição for avaliada como false
enquanto as asserções estiverem ativadas, a JVM lançará um AssertionError
e o programa será interrompido imediatamente.
Exemplo 1: asserção Java
class Main ( public static void main(String args()) ( String() weekends = ("Friday", "Saturday", "Sunday"); assert weekends.length == 2; System.out.println("There are " + weekends.length + " weekends in a week"); ) )
Resultado
Existem 3 fins de semana em uma semana
Obtemos a saída acima porque este programa não tem erros de compilação e, por padrão, as asserções estão desabilitadas.
Depois de ativar as asserções, obtemos a seguinte saída:
Exceção no thread "main" java.lang.AssertionError
Outra forma de declaração de asserção
assert condition : expression;
Nessa forma de declaração de asserção, uma expressão é passada para o construtor do AssertionError
objeto. Esta expressão possui um valor que é exibido como mensagem de detalhe do erro se a condição for false
.
A mensagem detalhada é usada para capturar e transmitir as informações da falha de asserção para ajudar na depuração do problema.
Exemplo 2: asserção Java com exemplo de expressão
class Main ( public static void main(String args()) ( String() weekends = ("Friday", "Saturday", "Sunday"); assert weekends.length==2 : "There are only 2 weekends in a week"; System.out.println("There are " + weekends.length + " weekends in a week"); ) )
Resultado
Exceção no thread "main" java.lang.AssertionError: Existem apenas 2 fins de semana em uma semana
Como podemos ver no exemplo acima, a expressão é passada para o construtor do AssertionError
objeto. Se nossa suposição for false
e as asserções estiverem habilitadas, uma exceção será lançada com uma mensagem apropriada.
Essa mensagem ajuda a diagnosticar e corrigir o erro que causou a falha da asserção.
Habilitando asserção para classes e pacotes específicos
Se não fornecermos nenhum argumento para as opções de linha de comando de asserção,
java -ea
Isso permite asserções em todas as classes, exceto classes do sistema.
Também podemos habilitar a asserção para classes e pacotes específicos usando argumentos. Os argumentos que podem ser fornecidos para essas opções de linha de comando são:
Habilitar asserção em nomes de classe
Para habilitar a asserção para todas as classes do nosso programa Main,
java -ea Main
Para habilitar apenas uma classe,
java -ea:AnimalClass Main
Isso permite a asserção apenas AnimalClass
no Main
programa.
Ativar asserção em nomes de pacotes
Para habilitar asserções para o pacote com.animal
e seus subpacotes apenas,
java -ea:com.animal… Main
Ativar asserção em pacotes sem nome
Para habilitar a asserção em pacotes não nomeados (quando não usamos uma instrução de pacote) no diretório de trabalho atual.
java -ea:… Main
Habilitar asserção em classes de sistema
Para habilitar a asserção em classes de sistema, usamos uma opção de linha de comando diferente:
java -esa:arguments
OU
java -enablesystemassertions:arguments
Os argumentos que podem ser fornecidos a essas opções são os mesmos.
Desabilitando Asserções
Para desativar asserções, usamos:
java -da arguments
OU
java -disableassertions arguments
To disable assertion in system classes, we use:
java -dsa:arguments
OR
java -disablesystemassertions:arguments
The arguments that can be passed while disabling assertions are the same as while enabling them.
Advantages of Assertion
- Quick and efficient for detecting and correcting bugs.
- Assertion checks are done only during development and testing. They are automatically removed in the production code at runtime so that it won’t slow the execution of the program.
- It helps remove boilerplate code and make code more readable.
- Refactors and optimizes code with increased confidence that it functions correctly.
When to use Assertions
1. Unreachable codes
Unreachable codes are codes that do not execute when we try to run the program. Use assertions to make sure unreachable codes are actually unreachable.
Let’s take an example.
void unreachableCodeMethod() ( System.out.println("Reachable code"); return; // Unreachable code System.out.println("Unreachable code"); assert false; )
Let’s take another example of a switch statement without a default case.
switch (dayOfWeek) ( case "Sunday": System.out.println("It’s Sunday!"); break; case "Monday": System.out.println("It’s Monday!"); break; case "Tuesday": System.out.println("It’s Tuesday!"); break; case "Wednesday": System.out.println("It’s Wednesday!"); break; case "Thursday": System.out.println("It’s Thursday!"); break; case "Friday": System.out.println("It’s Friday!"); break; case "Saturday": System.out.println("It’s Saturday!"); break; )
The above switch statement indicates that the days of the week can be only one of the above 7 values. Having no default case means that the programmer believes that one of these cases will always be executed.
However, there might be some cases that have not yet been considered where the assumption is actually false.
This assumption should be checked using an assertion to make sure that the default switch case is not reached.
default: assert false: dayofWeek + " is invalid day";
If dayOfWeek has a value other than the valid days, an AssertionError
is thrown.
2. Documenting assumptions
To document their underlying assumptions, many programmers use comments. Let’s take an example.
if (i % 2 == 0) (… ) else ( // We know (i % 2 == 1)… )
Use assertions instead.
Comments can get out-of-date and out-of-sync as the program grows. However, we will be forced to update the assert
statements; otherwise, they might fail for valid conditions too.
if (i % 2 == 0) (… ) else ( assert i % 2 == 1 : i;… )
When not to use Assertions
1. Argument checking in public methods
Arguments in public methods may be provided by the user.
So, if an assertion is used to check these arguments, the conditions may fail and result in AssertionError
.
Instead of using assertions, let it result in the appropriate runtime exceptions and handle these exceptions.
2. To evaluate expressions that affect the program operation
Do not call methods or evaluate exceptions that can later affect the program operation in assertion conditions.
Let us take an example of a list weekdays which contains the names of all the days in a week.
ArrayList weekdays = new ArrayList(Arrays.asList("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" )); ArrayList weekends= new ArrayList(Arrays.asList("Sunday", "Saturday" )); assert weekdays.removeAll(weekends);
Here, we are trying to remove elements Saturday
and Sunday
from the ArrayList weekdays.
Se a asserção estiver habilitada, o programa funciona bem. No entanto, se as asserções forem desabilitadas, os elementos da lista não serão removidos. Isso pode resultar em falha do programa.
Em vez disso, atribua o resultado a uma variável e, em seguida, use essa variável para afirmação.
ArrayList weekdays = new ArrayList(Arrays.asList("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" )); ArrayList weekends= new ArrayList(Arrays.asList("Sunday", "Saturday" )); boolean weekendsRemoved = weekdays.removeAll(weekends); assert weekendsRemoved;
Desta forma, podemos garantir que todos os fins de semana sejam removidos dos dias da semana, independentemente de a asserção estar habilitada ou desabilitada. Como resultado, não afeta a operação do programa no futuro.