Exceção é engolida por finalmente

static int retIntExc() throws Exception{ int result = 1; try { result = 2; throw new IOException("Exception rised."); } catch (ArrayIndexOutOfBoundsException e) { System.out.println(e.getMessage()); result = 3; } finally { return result; } } 

Um amigo meu é um desenvolvedor .NET e atualmente está migrando para o Java e ele me faz a seguinte pergunta sobre essa fonte. Em teoria, isso deve throw IOException("Exception rised.") E todo o método retIntExc() deve throws Exception . Mas nada acontece, o método retorna 2.

Eu não testei o exemplo dele, mas acho que esse não é o comportamento esperado.

EDIT: Obrigado por todas as respostas. Alguns de vocês ignoraram o fato de que o método é chamado de retIntExc , o que significa que este é apenas um exemplo experimental / de teste, mostrando problemas em mecanismos de arremesso / captura. Eu não precisava de ‘consertar’, eu precisava de explicação porque isso acontece.

É por isso que você não pode retornar de um bloco final em c # 🙂

É absolutamente o comportamento descrito na Especificação da Linguagem Java. Está especificado na seção 14.20.2 .

Se o bloco finally for completado abruptamente pelo motivo S, então a instrução try será completada abruptamente pelo motivo S (e o lançamento do valor V será descartado e esquecido).

Retornar é um exemplo de conclusão abrupta; se o bloco finally lançasse uma exceção, isso também terminaria abruptamente, perdendo a exceção original.

A citação acima era desse conjunto nested de marcadores, deixando de fora as opções que não são aplicáveis ​​aqui:

  • Se a execução do bloco try for concluída abruptamente devido a um lance de um valor V, então existe uma escolha:
    • Se o tipo de tempo de execução de V não for atribuível ao parâmetro de qualquer cláusula catch da instrução try, o bloco finally será executado. Então há uma escolha:
      • Se o bloco finally for completado abruptamente pelo motivo S, então a instrução try será completada abruptamente pelo motivo S (e o lançamento do valor V será descartado e esquecido).

Ele retornará 2 porque

finally sempre execute

O bloco finally executado, não importa qual exceção seja lançada. Ele não é executado apenas depois que as exceções são capturadas pelos blocos catch você declara. Ele é executado após o bloco try e exceções capturadas, se houver . Se o seu método lançar uma exceção, ele não poderá retornar nada a menos que você o engula em seu método e retorne o result . Mas você não pode ter os dois.

Além disso, a menos que seu método tenha outro código, ArrayIndexOutOfBoundsException nunca será encontrado.

Isso ocorre porque você emite uma instrução de retorno antes que a exceção seja passada e, assim, um valor válido é retornado. Você não pode retornar um valor e lançar uma exceção.

Remover o bloco finalmente em torno do retorno dará o comportamento desejado.

A class IOException não é um filho da class ArrayIndexOutOfBoundsException, portanto, a parte catch nunca será executada.

Se você mudar para isso, ele retornará 3.

 static int retIntExc() throws Exception{ int result = 1; try { result = 2; throw new ArrayIndexOutOfBoundsException ("Exception rised."); } catch (ArrayIndexOutOfBoundsException e) { System.out.println(e.getMessage()); result = 3; } finally { return result; } } 

Não vejo por que isso não seria um comportamento esperado. No final deste bloco de códigos, o resultado é igual a 2.

 static int retIntExc() throws Exception{ int result = 1; try { result = 2; 

Em seguida, você lança uma exceção, mas seu bloco catch captura exceções de um tipo diferente para que nada seja executado.

  throw new IOException("Exception rised."); } catch (ArrayIndexOutOfBoundsException e) { ... } 

O bloco finally é garantido para ser executado, então a etapa final é retornar 2.

Esse retorno bem-sucedido anula a exceção borbulhante. Se você quiser que a exceção continue a borbulhar, então você não deve retornar no bloco finally.

Ao colocar o método return in finally, você sobrescreve a exceção lançada e o resultado é retornado. Seu código deve ser algo assim:

 static int retIntExc() throws Exception{ int result = 1; try { result = 2; throw new IOException("Exception rised."); } catch (ArrayIndexOutOfBoundsException e) { System.out.println(e.getMessage()); result = 3; } finally { // do something } // it gets here only when exception is not thrown return result; }