2

The line in question is return pFile.exists() ? true : null;. As it does not raise any compilation error, what is the explanation for this. It ended up raising NPE.

import java.io.File;
public class Main {
  public static void main(String... args) {
    boolean accept = accept(new File(""));
    System.out.println("accept = " + accept);
  }
  public static boolean accept(File pFile) {
    System.out.println(pFile.exists()); // prints: false, so pFile is not null
    return pFile.exists() ? true : null; //this line should throw compilation error
  }
}

pFile is not null; a File is instantiated as you can see. But obviously the file is not there. The question is not about pFile. I am interested in how the operator is dealing with null.

JoshDM
  • 4,939
  • 7
  • 43
  • 72
Kowser
  • 8,123
  • 7
  • 40
  • 63
  • Why not just return `pFile.exists()`? – Buhake Sindi Sep 19 '11 at 05:12
  • Replace the body of accept(File pFile) method with the following: `return (pFile == null) ? false : pFile.exists();` or instead of using the ternary operator, you can just say `return (pFile != null) && pFile.exists();`. – styfle Sep 19 '11 at 05:14
  • Please see my edit. yes, i could write `return pFile.exists();` – Kowser Sep 19 '11 at 05:17
  • @Kowser: I just realized that the ternary operator is making this act differently than just `return null` which would give you an incompatible types error at compile time. You should have mentioned that in the question. – styfle Sep 19 '11 at 05:39
  • @styfle: i didn't know that :-S. That is why I had to ask. – Kowser Sep 19 '11 at 05:44

3 Answers3

7

You code is equivalent to:

public static boolean accept(File pFile) {
    System.out.println(pFile.exists()); // prints: false, so pFile is not null
    Boolean tmp = pFile.exists() ? true : null;
    return (boolean) tmp;
}

On other words, the type of the conditional operator is Boolean in this case, and then the value is being unboxed to return a boolean. When null is unboxed, you get an exception.

From section 15.25 of the Java Language Specification:

Otherwise, the second and third operands are of types S1 and S2 respectively. Let T1 be the type that results from applying boxing conversion to S1, and let T2 be the type that results from applying boxing conversion to S2. The type of the conditional expression is the result of applying capture conversion (§5.1.10) to lub(T1, T2) (§15.12.2.7).

I believe that's the case that's applicable here, although I'll grant it's not as clear as it might be.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • @Jon, to be honest, i find your answer correct but oververbose and not exactly to the point. You cited ternary operator specification, which, in fact, has nothing to go with the problem -- which is auto-unboxing of some expression `pFile.exists() ? true : null`. – Piotr Findeisen Sep 19 '11 at 17:25
  • @Piotr: But it relies on the type of that expression being `Boolean`, which is then unboxed. So it's not the execution of the conditional operator which is failing - it's the conversion step *after* that execution. I think that's an important aspect. – Jon Skeet Sep 19 '11 at 17:37
  • @Jon, no doubt that the condition (`?:`) runs smoothly. This is what i meant saying that the fact some `?` and `:` is in use has little importance.... Anyway, thank you for pointer to JLS :) – Piotr Findeisen Sep 19 '11 at 20:47
2

You return Boolean null from function defined as returning boolean (a primitive type; note small b). The null value is automatically unboxed, and casues NPE.

Piotr Findeisen
  • 19,480
  • 2
  • 52
  • 82
-1

Actually, an empty string is being used to create a file. This results in a empty abstract pathname with no prefix(or directory) and an empty name sequence. So windows is unable to create a file. This in turn is throwing a NPE

Varun Achar
  • 14,781
  • 7
  • 57
  • 74