Neste artigo, você aprenderá e compreenderá como funciona o fenômeno Java StackTrace, também conhecido como Call Stack Tracing. Estas informações foram estruturadas para iniciantes que encontraram esse conceito no início do Java Syntax Level 9. Acho que todos vocês, pelo menos uma vez, encontraram erros semelhantes ao trabalhar em seu IDE, independentemente de ser Idea , Eclipse ou qualquer outra coisa.
Exception in thread "main" java.lang.ArithmeticException
at com.example.task01.Test.division(Test.java:10)
at com.example.task01.Test.main(Test.java:6)
Este, como você deve ter adivinhado, é o nosso rastreamento. Mas não entre em pânico, agora vamos detalhar esse exemplo para você. Primeiro você precisa entender o fato de que StackTrace
funciona como Стэк
o nome sugere. Neste ponto nos deteremos um pouco mais detalhadamente. No oitavo nível, você já conhece as coleções e sabe que elas estão divididas em três grupos Set
- conjunto, List
- lista, Map
- dicionário (ou mapa). De acordo com JavaRush (c). O nosso Stack
faz parte do grupo List
. O princípio de seu funcionamento pode ser descrito como LIFO , que significa Last In First Out. Ou seja, esta é uma lista semelhante a uma pilha de livros; para pegar o elemento que colocamos Stack
primeiro, precisamos primeiro extrair todos os elementos que adicionamos à nossa lista depois. Conforme indicado na imagem acima, ao contrário, por exemplo, de uma lista normal ArrayList
onde podemos obter qualquer elemento da lista por índice. Mais uma vez para reforço. Obter um elemento Стэка
só é possível no final! Enquanto o primeiro elemento adicionado está no início (ou na parte inferior, como for mais conveniente). Estes são os métodos que nosso Stack
objeto possui push()
- Adiciona um elemento ao topo da pilha. Object pop()
- Retorna o elemento no topo da pilha, removendo-o no processo. Object peek()
- Retorna o elemento no topo da pilha, mas não o remove. int search()
- Procura um elemento na pilha. Se encontrado, seu deslocamento do topo da pilha será retornado. Caso contrário, -1 será retornado. boolean empty()
- Verifica se a pilha está vazia. Retorna verdadeiro se a pilha estiver vazia. Retorna falso se a pilha contiver elementos. Então, por que você Java
precisa StackTrace
de um baseado nos princípios de operação Stack
? Vejamos abaixo o exemplo de um erro que ocorreu durante a execução de um programa tão simples.
public class Test {
public static void main(String[] args) {
System.out.println(convertStringToInt(null));
}
public static int convertStringToInt(String s) {
int x = Integer.parseInt(s);
return x;
}
}
Temos uma classe Test
com dois métodos. Todos estão familiarizados main
e convertStringToInt
cuja lógica é converter e retornar uma string recebida de fora (ou seja, do método main
) em um número inteiro do tipo int
. Como você pode ver, passamos intencionalmente o parâmetro em vez de uma string com algum número null
. Nosso método não conseguiu processar esse parâmetro corretamente e causou um erro NumberFormatException
. Como vocês sabem, o programa começa a trabalhar seu trabalho a partir do método main
e neste momento ele cria um novo Стэк
com um nome StackTrace
onde coloca o valor atual do seu trabalho sob o número 1 , então vamos ao método convertStringToInt
e ao programa novamente insere os parâmetros da nossa localização naquele criado anteriormente StackTrace
sob o número 2 , então é chamado de método invisível aos nossos olhos parseInt
localizado na classe Integer
e este já será o nosso elemento número 3StackTrace
, neste método haverá outra chamada interna adicionada para StackTrace
o número 4 para verificar se há nulo no elemento , o que levará a um erro. O programa precisa exibir nosso erro indicando toda a cadeia de nossas transições até o erro ocorrer. É aqui que vem em seu auxílio aquele criado anteriormente com os dados de nossas transições StackTrace
.
Exception in thread "main" java.lang.NumberFormatException: null
at java.base/java.lang.Integer.parseInt(Integer.java:614)
at java.base/java.lang.Integer.parseInt(Integer.java:770)
at com.example.task01.Test.convertStringToInt(Solution.java:10)
at com.example.task01.Test.main(Solution.java:6)
Antes de ocorrer o erro, o programa se aprofundou nos métodos, mas assim que ocorreu o erro, tudo começou a acontecer na ordem inversa. Uma linha descrevendo o problema é impressa (nº 1 no exemplo), então o último (e no topo) valor adicionado ao nosso é obtido, Стэк
era o número quatro e impresso no console (nº 2 no exemplo) e vemos que o problema surgiu na classe Integer
na linha 614 do código e chamamos esta linha, linha 770 de um método parseInt
da mesma classe (nº 3 no exemplo) que, quando somado, Стэк
era o número três e este método de classe, Integer
ainda não visível para nós, já foi chamado pelo nosso método convertStringToInt
localizado na linha 10 do nosso programa (nº 4 no exemplo, e ao adicionar era o segundo), e ele, por sua vez, foi chamado main
na linha 6 (nº 5 no exemplo, e ao adicionar, respectivamente, o primeiro). Assim, armazenando Стек
passo a passo nossos métodos chamados, conseguimos retornar à main
impressão paralela das informações que exatamente nos levaram ao erro. Mas StackTrace
isto não é apenas trabalhar com erros, permite-nos obter muitas informações interessantes sobre o processo da nossa aplicação. Vejamos outro exemplo popular nos comentários da palestra principal do nível 9. Temos o código e anexarei imediatamente uma imagem que visualiza o processo do programa:
public class Test {
public static void main(String[] args) {
method1();
method2();
}
public static void method1() {
//не вызывает ничего
}
public static void method2() {
method3();
method4();
}
public static void method3() {
//не вызывает ничего
}
public static void method4() {
method5();
}
public static void method5() {
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
for (StackTraceElement element:stackTraceElements) {
System.out.println(element.getMethodName());
}
}
}
Aqui nosso programa faz seu trabalho perfeitamente e termina. Isto é o que veremos na saída do console:
getStackTrace
method5
method4
method2
main
Process finished with exit code 0
Como chegamos a essa conclusão e o que aconteceu no quinto método, a partir da linha 20? Receio que o melhor que posso fazer é adicionar a explicação mais popular (abreviada) do usuário Kirill dos comentários à palestra. Vamos voltar para a linha de criação StackTrace
e analisá-la elemento por elemento:
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
StackTraceElement[]
- uma indicação do tipo do array (Nos níveis iniciais você já aprendeu sobre arrays como int[], String[], aqui é a mesma coisa). stackTraceElements
- o nome do array pode ser qualquer coisa, levando em consideração as regras gerais de nomenclatura, isso não afeta o trabalho. Thread.currentThread()
- obter um link para o thread atual no qual os métodos que queremos rastrear são executados (por enquanto isso não é importante, você analisará os threads com mais detalhes no nível 16 na missão Java Core) getStackTrace()
- obtemos todos Стэк
os métodos chamados (Este é um getter regular para StackTrace
) Agora vamos ver o que o array criado pode ser útil para nós. Entendemos que o array armazena informações sobre os métodos executados. (c) E para isso, na 21ª linha, lançamos um ciclo modificado for
chamado forEach
(aliás, para quem ainda não estudou esse ciclo, aconselho que leia sobre ele) e enviamos os dados do array para o console , nomeadamente informação sobre quais os métodos executados durante a obra de construção element.getMethodName()
. Atenção, como vemos, o elemento zero do array acabou sendo ele mesmo, getStackTrace()
respectivamente, pois no momento do recebimento do array de dados foi o último método que foi executado e assim acabou no topo Стэка
, e lembrando nossa construção “ Último a entrar, primeiro a sair ”é imediatamente o primeiro a ser adicionado à matriz sob o elemento zero. Aqui está o que mais podemos obter StackTraceElement
: String getClassName()
- Retorna o nome da classe. String getMethodName()
- Retorna o nome do método. String getFileName()
- Retorna o nome do arquivo (pode haver muitas classes em um arquivo). String getModuleName()
- Retorna o nome do módulo (pode ser nulo). String getModuleVersion()
– Retorna a versão do módulo (pode ser nulo). int getLineNumber()
- Retorna o número da linha do arquivo em que o método foi chamado. Agora que você entende o princípio geral de operação, aconselho você a tentar métodos diferentes StackTrace
em seu Ide . Mesmo que você não tenha dominado tudo completamente, continue aprendendo e o quebra-cabeça ficará da mesma forma que aconteceu comigo neste assunto. Desejo a todos sucesso! Ps Se você gostou deste material, por favor, apoie-o com um like. Não é difícil para você, estou satisfeito. Obrigado e nos vemos no nível 41 ;)
GO TO FULL VERSION