0

I found that prevent forgetting to initialize objects isn't fully covered in Java compiler and/or Sonar warning, I'm using latest Eclipse with latest Sonar plugin.

I'm missing error/warning about not initializing for example for Map (similarly can be String)

In the example Class Variable mapStatic and Member Variable map, both private and not final and can be declared without initialization and without any error/warning about the NullPointerException to come.

Although for local variables as mapVar I get compile error Compile The local variable mapVar may not have been initialized

Obviously Local variables are not assign with default value, but still why compiler/sonar doesn't warn about NullPointerException?

Local variables are slightly different; the compiler never assigns a default value to an uninitialized local variable.

private static Map<String, String> mapStatic; // Missing compile/warning
private Map<String, String> map; // Missing compile/warning
public void  put() {
    map.put("x", "1"); // NullPointerException
    //Map<String, String> mapVar;
    //mapVar.put("x", "1"); // Compile The local variable mapVar may not have been initialized
}
static {
    mapStatic.put("x", "1"); // NullPointerException        
}

Also if I add final I'll get compile error Compile The local variable map may not have been initialized.

I found an answer that it won't be in compile time, so how can avoid or found this issues beforehand?

Failing to initialise a value is a logic error on the part of the programmer, and should be caught as soon as possible. Java does this at compile time for locals, but only at runtime (or not at all) for fields.

Ori Marko
  • 56,308
  • 23
  • 131
  • 233
  • 1
    what exactly kind of warning do you want? do you want the compiler to verify each and every method to see if there is an instantiation in there, do you expect that it goes looking for each and every class that uses your class whether or not that method is called before any other using the variable. – Stultuske Oct 15 '18 at 06:01
  • @Stultuske good point, but still it's a private, without a public setter and I want to avoid/find such issues – Ori Marko Oct 15 '18 at 06:02
  • Short Answer: You can't. – Johannes Kuhn Oct 15 '18 at 06:03
  • @user7294900 any method can set the value of an instance variable (except for static methods), it doesn't per se has to be a classic setter – Stultuske Oct 15 '18 at 06:04
  • @JohannesKuhn there's even no static analyzer that can found it? – Ori Marko Oct 15 '18 at 06:04
  • @Stultuske true, but it's a private variable without any instantiation, can this rule be added to one of existing source code analyzer as PMD? – Ori Marko Oct 15 '18 at 06:08
  • depending on the requirements, this might be expected behaviour, so I sure hope they'll never add it as a standard – Stultuske Oct 15 '18 at 06:12
  • 1
    Compiler errors won't replace the need for decent unit tests which will pick up this type of error very easily. – Peter Lawrey Oct 15 '18 at 06:16
  • 2
    I would make Maps and Collections final where ever possible as well as being initialized on the line they are declared. Doing either of these will prevent a NPE. – Peter Lawrey Oct 15 '18 at 06:19
  • 1
    [jonskeet's answer to a related question](https://stackoverflow.com/a/1560704/3788176) spends a little time discussing why this isn't checked by the compiler. – Andy Turner Oct 15 '18 at 06:22

1 Answers1

2

The behavior you seem to be looking for is more likely to produce unnecessary warnings than to help the design.

The fact that class-level fields get a JVM-assigned default value is by design, and it's OK for many reasons, including:

  • It's possible that the field's value won't be known until after object construction. This is typical, because many field values only get set in setters.
  • It's possible that the current class itself doesn't know what the value is. In this case, the responsibility to set the value is outside the class, so the warning would simply be an annoyance.
  • What if the field won't be used in the current class at all?

This is the area where the responsibility lies with the developer. Only you know the order of execution, only you know what data the code depends on, and only you have the responsibility to test the code and ensure that it's bug-free.

ernest_k
  • 44,416
  • 5
  • 53
  • 99
  • If I don't use (remove `put`) it in class I'll get a warning `The value of the field map/mapStatic is not used` – Ori Marko Oct 15 '18 at 06:10
  • @user7294900 Yes, but that's a different thing. Initialization warnings would need to know the order of calls (which would be impossible to figure out at compile time - if not in local scope). Given just the access modifier and references in the current class, it can be established that the field may be useless, which justifies the unused warning. – ernest_k Oct 15 '18 at 06:15