RFE - Relax error about "will never throw the exception" to a warning

4 respostas
victorwss

Oi pessoal. A uns meses atrás criei uma RFE no site da sun.

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6589290

O objetivo é transformar aqueles erros de compilação do tipo “exception XXX is never throw in the corresponding try block” para uma warning, visto que:

  1. É possível enganar o compilador às vezes, de forma que a exceção é lançada e o compilador não vê isso (genéricos em cláusulas throws, JNI, descompiladores e Class.newInstance() conseguem fazer isso).

  2. É possível escrever-se código morto que faz com que o compilador não emita esse erro.

Repetindo, eu postei isso a uns meses atrás, e até agora apenas dois votos (sendo um deles o meu). Então, venho pedir encarecidamente a todos, que votem nesta RFE para que no Java 7 esse erro se torne uma warning.

Obrigado. :slight_smile:

4 Respostas

Mauricio_Linhares

Juro que eu não entendi.

Se o compilador diz que a exceção nunca vai ser lançada, ela realmente nunca vai ser lançada, mesmo que você faça um Class.newInstance(), porque a exceção que seria lançada pelo construtor chamado por Class.newInstance() vai ser empacotada em uma checked exception específica, que realmente nunca vai subir.

Se a exceção foi lançada através de alguma alteração do bytecode depois que o código foi compilado e antes de ser compilado você já sabia que tal exceção iria ser lançada em uma chamada a um código qualquer, ou você sabe demais sobre o código que está sendo chamado (até porque isso só vale pra checked exceptions) ou porque é erro de programação mesmo, o código não está explicando corretamente o que ele vai fazer e quais são as pós-condiçoes do acontecimento.

IMHO, esse comportamento deve continuar valendo pra máquina virtual, não vejo nenhum problema nisso, se é realmente necessário pegar uma checked exception que não está explicitamente declarada (e que teoricamente não deveria ser lançada) que se transforme ela em uma runtime exception e que isso fique claro em algum lugar pra quem estiver chamando o código.

D

Meio sem sentido isso né?

Vamos deixar q eles gastem tempo com coisas relevantes… =)

victorwss

De acordo com o javadoc do método Class.newInstance():

Ou seja, o seguinte código não compila porque o compilador pensa que a exceção nunca é lançada:

import java.sql.SQLException;

public class X {
    public X() throws SQLException {
        throw new SQLException();
    }

    public static void problemas() {
        try {
            X.class.newInstance();
        } catch (InstantiationException e) {
        } catch (IllegalAccessException e) {
        }
    }

    public static void main(String[] args) {
        try {
            problemas();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

Na verdade, a máquina virtual não está nem aí para isso (tanto que se estivesse, a técnica de alterar-se os bytecodes não funcionaria). Apenas o compilador faz esta verificação.
O problema é quando se trabalha com bibliotecas de terceiros de código fechado que apresentam este problema (eu sofria disso na época). Uma simples cláusula catch resolveria, mas o compilador não deixava porque a exceção nunca deveria aparecer. Daí, para resolver o problema, foi preciso colocar um if (1==2) throw new SQLException(); para enganar o compilador.

Essa mudança no compilador é fácil de ser feita em poucas horas e não gera nenhum problema de compatibilidade com ninguém.

victorwss

Só revivendo o tópico aí. Ninguém tem mais nada a comentar não? :frowning:

Criado 29 de dezembro de 2007
Ultima resposta 4 de jan. de 2008
Respostas 4
Participantes 3