Loosening requirements for super() invocation
Archie Cobbs
archie.cobbs at gmail.com
Fri Nov 4 22:59:13 UTC 2022
On Fri, Nov 4, 2022 at 1:08 PM Brian Goetz <brian.goetz at oracle.com> wrote:
> We should check each file locally, without regard to whether superclasses
> or subclasses are problematic.
>
That definitely keeps things simpler.
So it sounds like we have boiled this down to the following:
1. Add one new warning, which applies to one class at a time
2. The warning looks for constructors with a possible 'this' escape
Obviously this is a "best effort" thing, false positives will happen. The
warning would say something like "possible early access before instance is
fully initialized".
Now we just need a definition of "possible 'this' escape".
The goal is to close off all routes by which 'this' could end up being
passed to code in any subclass. In other words we are not trying to save
the class from itself.
Attempt #1...
A 'this' escape is when, in a non-final class MyClass constructor, after a
super() call, a reference to the 'this' instance is used, explicitly or
implicitly, in any expression that (as far as the compiler can tell) might
possibly:
1. Invoke a non-static method declared in any strict supertype of MyClass
2. Invoke a non-static, non-private, non-final method declared in MyClass
3. Invoke a non-static, private or final method declared in MyClass that
has a possible 'this' escape (recursive definition)
4. Otherwise access a field or invoke a non-static method declared in
any subclass of MyClass
Any expression caught by #4 would necessarily involve a downcast, so the
compiler might choose to simply check for any expression that could
possibly downcast 'this'.
Test case 1: HashSet should generate a warning. It does because of case #1.
Test case 2: the class below should not generate a warning. It doesn't
because resetBoard() is private and contains no 'this' escapes.
public class TicTacToe {
private final char[][] board = new char[3][3];
public TicTacToe() {
this.resetBoard();
}
private void resetBoard() {
Stream.of(this.board).forEach(row -> Arrays.fill(row, ' '));
}
// more stuff here...
}
Test case 3: FilteredSet does not generate a warning. Instead, we are
putting the "blame" on HashSet.
-Archie
--
Archie L. Cobbs
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-dev/attachments/20221104/9bde5d36/attachment-0001.htm>
More information about the amber-dev
mailing list