1
resposta

Dúvida exception, JVM e compilador.

Olá pessoal tenho algumas dúvidas:

  1. Sobre checked e unchecked, não existe nada no código especificando quem é o que. Essa verificação está embutida no compilador?

  2. Não sei se estou certo, mas parece que para as exceções que criamos(que não fazem parte do padrão java) precisamos explicitamente usar o throw para que a JVM lançe elas. Já as outras exceções não. O ArithmeticException é lançado automaticamente caso um exista um int / 0 sem que precise usar throw. Porque isso acontece?

  3. Como que a JVM entende que um inteiro / 0 deve ser lançado como uma exceção? Posso estar enganado mas acho que não vi nenhuma verificação desse tipo nas classes throwable assim como não vi verificação da variável que aponta pra nenhum objeto. Essas coisas estão implícitas na programação da JVM?

Sei que pode ter ai coisas muito avançadas pra explicar e ainda ser muito cedo pra entender, mas se algum puder dar uma breve explicação agradeço.

1 resposta

Eai José, tranquilo?

  1. Realmente, a questão é que o compilador tem acesso a declaração de métodos e pode verificar se o método lança exceção e se essa é uma exceção é checked ou unchecked, por exemplo:
public static void lancaExcecao() throws NullPointerException {
        throw new NullPointerException();
}

Aqui temos uma questão que exceções do tipo unchecked não precisam estar na assinatura do método, mas apenas para ficar mais didático eu coloquei

Em nosso main, podemos tranquilamente:

lancaExcecao();

Sem precisar adicionar um throws ou try/catch, pois o compilador sabe ao ler a assinatura do método que está sendo lançando uma exceção que ele não precisa lidar

Se mudarmos a nossa lancaExcecao para uma simples Exception, por exemplo:

public static void lancaExcecao() throws Exception {
        throw new Exception();
}

Ai sim precisamos ter todo o tratamento, pois o compilador ao ler a assinatura do método vai perceber que há uma exceção que o usuário precisa tratar, então teoricamente podemos dizer que em nosso código a assinatura do método da uma pista, pois exceções derivadas de Runtime não precisam declarar que lançam erros, enquanto as checkeds obrigatoriamente precisam, e o compilador consegue analisar e fazer a verificação do nosso código :)

Agora em relação a dúvida 2 e 3 temos coisas que estão embutidas dentro da JVM e estão de formas realmente implícitas, mas também existem coisas relacionadas ao Sistema Operacional, então por exemplo (vou explicar de uma maneira beeem simples, mas existe um mundo enorme quando começamos a entender os sistemas operacionais:

No caso da divisão por zero, quando tentamos fazer essa operação na maioria das linguagens de programação, o que ocorre é que é emitido um sinal de interrupção para o sistema operacional derivado da nossa CPU, então o S.O pega esse erro e encaminha para a JVM que tem um tratador específico para esse sinal, e o tratamento pode ser simplesmente interromper o programa lançando uma exceção de ArithmeticException

Podemos ter algo parecido com o NullPointer, talvez a JVM possa fazer uma verificação implícita para verificar a nulidade do objeto, mas também poderia trabalhar com uma memoria virtual, e ao tentar acessar um espaço de memória nulo teríamos um outro sinal de erro, que por sua vez contém outro "tratador" especifico, que em outras linguagens como C é o famoso segment fault

Como eu disse existe um mundo enorme para entender mais afundo sobre como o Sistema Operacional lida com nossos programas, erros, e interrupções, mas alguns erros não necessariamente precisam estar explicitamente utilizando um throws pois o próprio S.O ou a JVM pode fazer verificações e emitir sinais de que algo não está funcionando corretamente.

Abraços e Bons Estudos!!!