O trybloco é concluído com a execução da returninstrução e o valor de sno momento em que a returninstrução é executada é o valor retornado pelo método. O fato de a finallycláusula alterar posteriormente o valor de s(após a conclusão da returninstrução) não muda (nesse ponto) o valor de retorno.
Observe que o item acima lida com alterações no valor de ssi mesmo no finallybloco, não no objeto que faz sreferência. Se sfosse uma referência a um objeto mutável (o que Stringnão é) e o conteúdo do objeto fosse alterado no finallybloco, essas alterações seriam vistas no valor retornado.
As regras detalhadas de como tudo isso funciona podem ser encontradas na Seção 14.20.2 da Especificação da linguagem Java . Observe que a execução de uma returninstrução conta como um término abrupto do trybloco (a seção que inicia " Se a execução do bloco try for concluída abruptamente por qualquer outro motivo, R .... " se aplica). Consulte a Seção 14.17 do JLS para saber por que uma returninstrução é um encerramento abrupto de um bloco.
Por meio de mais detalhes: se o trybloco e o finallybloco de uma try-finallyinstrução terminam abruptamente devido a returninstruções, as seguintes regras do §14.20.2 se aplicam:
Se a execução do trybloco for concluída abruptamente por qualquer outro motivo R [além de gerar uma exceção], o finallybloco será executado e haverá uma opção:
- Se o
finallybloco for concluído normalmente, a tryinstrução será concluída abruptamente pelo motivo R.
- Se o
finallybloco for concluído abruptamente pelo motivo S, a tryinstrução será concluída abruptamente pelo motivo S (e o motivo R será descartado).
O resultado é que a returninstrução no finallybloco determina o valor de retorno de toda a try-finallyinstrução e o valor retornado do trybloco é descartado. O mesmo ocorre em uma try-catch-finallyinstrução se o trybloco lança uma exceção, é capturado por um catchbloco e o catchbloco e o finallybloco têm returninstruções.