V6051. Use of jump statements in 'finally' block can lead to the loss of unhandled exceptions.
Анализатор выявил использование операторов return/break/continue и т.п. внутри блока 'finally'. Их использование может привести к потере необработанного исключения, возникшего в блоках 'try' или 'catch'. Согласно JLS [14.20.2], в случае такого завершения блока 'finally', все сгенерированные исключения в 'try' или 'catch' будут подавлены.
Рассмотрим пример, когда анализатор выдаст предупреждение:
int someMethod(int a, int b, int c) throws SomeException
{
int value = -1;
...
try
{
value = calculateTransform(a, b, c);
...
}
finally
{
System.out.println("Result of someMethod()");
return value; // <=
}
}
В данном примере, несмотря на то, что в сигнатуре метода указано, что может возникнуть исключение, метод 'someMethod' никогда не выбросит его, так как применение оператора 'return' подавит исключение, и оно не выйдет наружу.
Возможно, это намеренный способ подавления исключений. В таком случае, чтобы анализатор не ругался, достаточно убрать исключение из сигнатуры метода.
int someMethod(int a, int b, int c)
{
int value = -1;
...
try
{
value = calculateTransform(a, b, c);
...
}
finally
{
System.out.println("Result of someMethod()");
return value;
}
}
Немного изменим предыдущий пример:
int someMethod(int a, int b, int c) throws SomeException
{
int value = -1;
...
try
{
value = calculateTransform(a, b, c);
...
}
catch (SomeException se)
{
...
throw se;
}
finally
{
System.out.println("Result of someMethod()");
return value; // <=
}
}
Здесь анализатор тоже выдаст предупреждение. Есть обработчик исключения 'SomeException', который что-то делает и пробрасывает это исключение дальше. После чего отработает блок 'finally' и функция вернет значение 'value'. А что же исключение? А исключение, что было проброшено дальше в обработчике, так и не выйдет за пределы метода.
Чтобы исправить ситуацию, можно исправить код следующим образом:
int someMethod(int a, int b, int c) throws SomeException
{
int value = -1;
...
try
{
value = calculateTransform(a, b, c);
...
}
catch (SomeException se)
{
...
throw se;
}
finally
{
System.out.println("Result of someMethod()");
}
return value;
}
В таком случае, если произошло исключение, то оно будет обязательно проброшено наружу, что и говорит сигнатура метода 'someMethod'.
Данная диагностика классифицируется как:
|
Взгляните на примеры ошибок, обнаруженных с помощью диагностики V6051. |