-3

Is there any way to tell IDEA that the following is OK:

public static void main(String[] args) {
    String stringValue = args.length > 0 ? args[0] : null;
    long longValue;
    try {
        longValue = Long.parseLong(stringValue);
    } catch (NumberFormatException e) {
        throw new IllegalArgumentException("hmm...", e);
    }
    System.out.println(longValue);
}

It insists on highlighting stringValue and warning "Argument stringValue might be null". I know it might, but if it is, the exception will be caught.

Klitos Kyriacou
  • 8,630
  • 2
  • 32
  • 59
  • The exception is not caught here, because it will be a `NullPointerException`, not a `NumberFormatException`. – RealSkeptic May 19 '20 at 14:04
  • You could always do `assert stringValue != null` or annotate it `@NotNull` if it is a parameter to your method – user May 19 '20 at 14:06
  • 1
    @RealSkeptic no, `parseLong` checks for null and throws `NumberFormatException`, not `NullPointerException`. – Klitos Kyriacou May 19 '20 at 14:12
  • 1
    @user I can't do that because stringValue _can_ be null. – Klitos Kyriacou May 19 '20 at 14:13
  • @KlitosKyriacou For me your code does not highlight a warning. Is it vanilla IntelliJ, or is it a plugin? – Magnilex May 19 '20 at 14:17
  • @Magnilex it is vanilla IntelliJ (latest version) with possibly some warnings turned up a bit higher than standard. In my case, Settings -> Inspections -> Java -> Probable Bugs -> "Constant Conditions & Exceptions" is turned on at Warning level. I've also edited my question and added a full main method that use can use as a "Complete Minimal Verifiable Example". – Klitos Kyriacou May 19 '20 at 14:31

1 Answers1

1

Well, is it really OK? You are essentially using the exception to control the flow of the code. This is generally considered an anti-pattern (Why not use exceptions as regular flow of control?).

It can easily be avoided by doing the null check yourself:

if (stringValue != null) {
  longValue = Long.parseLong(stringValue);
}

However, if you want to keep your code the way it is and let the null case be handled by the parseLong() method, you can:

Annotate your method with @SuppressWarnings("ConstantConditions")

@SuppressWarnings("ConstantConditions")
public static void main(String[] args) {
  String stringValue = args.length > 0 ? args[0] : null;
  long longValue;
  try {
    longValue = Long.parseLong(stringValue);
  } catch (NumberFormatException e) {
    throw new IllegalArgumentException("hmm...", e);
  }
}

Add a comment //noinspection ConstantConditions

public static void main(String[] args) {
  String stringValue = args.length > 0 ? args[0] : null;
  long longValue;
  try {
    //noinspection ConstantConditions
    longValue = Long.parseLong(stringValue);
  } catch (NumberFormatException e) {
    throw new IllegalArgumentException("hmm...", e);
  }
}

IntelliJ helped me with both these by pressing alt + enter, bringing up the intentions menu where you can either choose Supress for method or Supress for statement.

However, I think both of these are IDE-specific, so my advise would simply be to let the warning be. Or even better, do the null check yourself.

Magnilex
  • 10,219
  • 8
  • 49
  • 72