Here is a sample constructor for a class called UIMenus
:
1 UIMenus() {
2 PropertyChangeListener focusListener = evt -> {
3 Component focusOwner = (Component) evt.getNewValue();
4 //noinspection ObjectEquality
5 if (focusOwner != caretOwner) {
6 if (caretOwner != null) {
7 caretOwner.removeCaretListener(this); // Checker Frame knows caretOwner isn't null here.
8
9 // error: [dereference.of.nullable] dereference of possibly-null reference caretOwner
10 final String text = caretOwner.getText();
11 System.out.printf("deFocus c with %s to %s%n",
12 text, (focusOwner == null) ? "None" : focusOwner.getClass().toString());
13 }
14 if (focusOwner instanceof JTextComponent) {
15 // focusOwner can't be null, so caretOwner can't get set to null here.
16 caretOwner = (JTextComponent) focusOwner;
17 caretOwner.addCaretListener(this);
18
19 // error: [dereference.of.nullable] dereference of possibly-null reference caretOwner
20 final String text = caretOwner.getText();
21 System.out.printf("Focus c with %s%n", text);
22 }
23 }
24 };
25 focusManager.addPropertyChangeListener("permanentFocusOwner", focusListener);
26 }
On lines 10 and 20, I'm getting a dereference.of.nullable
error. But each statement is inside
an if
block and has been tested for null. Furthermore, each has been already dereferenced on
the previous line. So on line 7, the checker framework knows that caretOwner is not null, but
not on line 10. The same is true of lines 17 and 20. It seems to me that the null checker should
know that the value is not null for the rest of the if
block, but that's not what I'm seeing.
Am I misunderstanding something about how the null checker works? Or is this a bug?
For a reproducible test case, see the UIMenus class at https://github.com/SwingGuy1024/CheckerQuestions