1. Obtendo um rastreamento de pilha
A linguagem de programação Java oferece muitas maneiras para um programador obter informações sobre o que está acontecendo em um programa. E não apenas palavras.
Por exemplo, depois que os programas C++ são compilados, eles se tornam um grande arquivo cheio de código de máquina, e tudo o que está disponível para um programador em tempo de execução é o endereço do bloco de memória que contém o código de máquina que está sendo executado no momento. Não muito, digamos.
Mas para Java, mesmo depois que um programa é compilado, as classes permanecem classes, os métodos e as variáveis não desaparecem, e o programador tem muitas maneiras de obter informações sobre o que está acontecendo no programa.
Rastreamento de pilha
Por exemplo, no ponto da execução de um programa, você pode descobrir a classe e o nome do método que está sendo executado. E não apenas um método — você pode obter informações sobre toda a cadeia de chamadas de método do método atual de volta ao main()
método.
Uma lista que consiste no método atual e no método que o invocou, e no método que o chamou, etc., é chamada de rastreamento de pilha . Você pode obtê-lo com esta declaração:
StackTraceElement[] methods = Thread.currentThread().getStackTrace();
Você também pode escrevê-lo como duas linhas:
Thread current = Thread.currentThread();
StackTraceElement[] methods = current.getStackTrace();
O método estático currentThread()
da Thread
classe retorna uma referência a um Thread
objeto, que contém informações sobre a thread atual, ou seja, a thread atual de execução. Você aprenderá mais sobre threads nos níveis 17 e 18 da missão Java Core .
Esse Thread
objeto tem um getStackTrace()
método, que retorna uma matriz de StackTraceElement
objetos, cada um contendo informações sobre um método. Juntos, todos esses elementos formam um rastreamento de pilha .
Exemplo:
Código |
---|
|
Saída do console |
|
Como podemos ver na saída do console do exemplo, o getStackTrace()
método retornou um array de três elementos:
getStackTrace()
método daThread
classetest()
método daMain
classemain()
método daMain
classe
A partir desse rastreamento de pilha, podemos concluir que:
- O
Thread.getStackTrace()
método foi chamado peloMain.test()
método na linha 11 do arquivo Main.java - O
Main.test()
método foi chamado peloMain.main()
método na linha 5 do arquivo Main.java - Ninguém chamou o
Main.main()
método — este é o primeiro método na cadeia de chamadas.
A propósito, apenas algumas das informações disponíveis foram exibidas na tela. Todo o resto pode ser obtido diretamente do StackTraceElement
objeto
2.StackTraceElement
Como o próprio nome sugere, a StackTraceElement
classe foi criada para armazenar informações sobre um elemento de rastreamento de pilha , ou seja, um método no arquivo stack trace
.
Esta classe tem os seguintes métodos de instância:
Método | Descrição |
---|---|
|
Retorna o nome da classe |
|
Retorna o nome do método |
|
Retorna o nome do arquivo (um arquivo pode conter várias classes) |
|
Retorna o número da linha no arquivo onde o método foi chamado |
|
Retorna o nome do módulo (pode ser null ) |
|
Retorna a versão do módulo (pode ser null ) |
Eles podem ajudá-lo a obter informações mais completas sobre a pilha de chamadas atual:
Código | Saída do console | Observação |
---|---|---|
|
|
nome da classe nome do método nome do arquivo número da linha nome do módulo versão do módulo nome da classe nome do método nome do arquivo número da linha nome do módulo versão do módulo nome da classe nome do método nome do arquivo número da linha nome do módulo versão do módulo |
3. Pilha
Você já sabe o que é um rastreamento de pilha , mas o que é uma pilha (classe Stack)?
Uma pilha é uma estrutura de dados à qual você pode adicionar elementos e da qual pode recuperar elementos. Ao fazer isso, você só pode pegar elementos do final: você primeiro pega o último adicionado, depois o penúltimo adicionado, etc.
A própria pilha de nomes sugere esse comportamento, como você interagiria com uma pilha de papéis. Se você colocar as folhas 1, 2 e 3 em uma pilha, deverá recuperá-las na ordem inversa: primeiro a terceira folha, depois a segunda e só depois a primeira.
Java ainda tem uma classe especial de coleção Stack com o mesmo nome e comportamento. Essa classe compartilha muitos comportamentos com ArrayList
e LinkedList
. Mas também possui métodos que implementam o comportamento da pilha:
Métodos | Descrição |
---|---|
|
Adiciona o obj elemento ao topo da pilha |
|
Pega o elemento do topo da pilha (a profundidade da pilha diminui) |
|
Retorna o item no topo da pilha (a pilha não muda) |
|
Verifica se a coleção está vazia |
|
Procura um objeto na coleção e retorna seuindex |
Exemplo:
Código | Conteúdo da pilha (o topo da pilha está à direita) |
---|---|
|
|
As pilhas são usadas com bastante frequência na programação. Portanto, esta é uma coleção útil.
4. Exibindo um rastreamento de pilha durante o tratamento de exceções
Por que uma lista de chamadas de método é chamada de rastreamento de pilha ? Porque se você pensar na lista de métodos como uma pilha de folhas de papel com nomes de métodos, quando chamar o próximo método, você adicionará uma folha com o nome desse método à pilha. E a próxima folha de papel vai em cima dessa, e assim por diante.
Quando um método termina, a planilha no topo da pilha é removida. Você não pode remover uma folha do meio da pilha sem remover todas as folhas acima dela. Da mesma forma, você não pode encerrar um método no meio de uma cadeia de chamadas sem encerrar todos os métodos que ele chamou.
Exceções
Outro uso interessante para pilhas é durante o tratamento de exceções.
Quando ocorre um erro em um programa e uma exceção é lançada , a exceção contém o rastreamento de pilha atual — uma matriz que consiste em uma lista de métodos começando, do método principal e terminando com o método onde ocorreu o erro. Existe até a linha onde a exceção foi lançada!
Este rastreamento de pilha é armazenado dentro da exceção e pode ser facilmente recuperado usando o seguinte método:StackTraceElement[] getStackTrace()
Exemplo:
Código | Observação |
---|---|
|
Capture a exceção Obtenha o rastreamento de pilha que existia quando o erro ocorreu. |
Este é um método da Throwable
classe, então todos os seus descendentes (ou seja, todas as exceções) possuem o getStackTrace()
método. Super conveniente, né?
Exibir o rastreamento de pilha da exceção
A propósito, a Throwable
classe tem outro método para trabalhar com rastreamentos de pilha, um método que exibe todas as informações de rastreamento de pilha armazenadas na exceção. É chamado printStackTrace()
.
Muito convenientemente, você pode chamá-lo em qualquer exceção.
Exemplo:
Código |
---|
|
Saída do console |
|
GO TO FULL VERSION