I have an Android error handler which never returns (it logs a message and throws an error exception). If I call my error handler from a method which normally returns a value, the Android Studio lint checker reports an error because no value is returned. Is there a way either to tell Android Studio either that my error handler does not return or that the point in the code after calling it is in fact unreachable.
Of course I could put in an unnecessary return statement returning a dummy value of the correct type, but this is inelegant and clutters up my app with an unreachable statement.
I can't find a code inspection to disable to prevent the error, but even if there is one to disable, that would stop it reporting really missing return statements.
Just to repeat, this is not a Java syntax issue. People have said that a Java method must return a value of the type declared. This is
(a) not relevant
(b) not true.
The correct statement is that a Java method, if it returns, must return a value of the declared type. This bit of code
public long getUnsignedLong(String columnName)
throws NumberFormatException, NoColumnException
{
String s = getString(columnName, "getUnsignedLong");
if ((s != null) && s.matches("^[0-9]+$")) {
return Long.parseLong(s);
}
else
{
throw(new NumberFormatException("Bad number " + s));
}
}
is perfectly valid Java, and AS does not complain about it. Indeed if I insert an unnecessary return
like this
public long getUnsignedLong(String columnName)
throws NumberFormatException, NoColumnException
{
String s = getString(columnName, "getUnsignedLong");
if ((s != null) && s.matches("^[0-9]+$")) {
return Long.parseLong(s);
}
else
{
throw(new NumberFormatException("Bad number " + s));
}
return 0;
}
AS complains that it is unreachable.
My problem with throwing the exception is that if it actually happens, what my app's user sees is a popup window saying that the app has stopped and asking the user if they want to disable it. This isn't very helpful to the user and isn't very helpful to me when the user reports back to me that it has happened. So instead of throwing the exception I call my fatal error handler which looks like this:-
// Always invoked with fatal = true
// Report a fatal error.
// We send a message to the log file (if logging is enabled).
// If this thread is the UI thread, we display a Toast:
// otherwise we show a notification.
// Then we throw an Error exception which will cause Android to
// terminate the thread and display a (not so helpful) message.
public MyLog(Context context, boolean fatal, String small, String big) {
new Notifier(context, small, big);
new MyLog(context, big, false);
throw(new Error());
}
Yes, I know that argument fatal
isn't referenced, but its presence arranges that this particular overload of my error handler is called, and you can see that it throws an exception and doesn't return.
My actual problem is that if I replace the throw
in getUnsignedLong
by a call to my fatal error handler, which doesn't return, AS complains at the end of getUnsignedLong
that it is returning without a value. Well, it's wrong: this point is just as unreachable as it was before. I tried putting a contract in front of MyLog
saying that it always fails, but this doesn't help, and pressing right arrow at the AS error report doesn't offer any way of suppressing it. I could put in a dummy return
statement or a dummy throw
, but either of these would in fact be unreachable code, and I regard this as inelegant and unnecessary.
So my question stands as it was originally asked: how do I tell Android Studio that a method does not return?