Nestmates
John Rose
john.r.rose at oracle.com
Thu Jan 28 18:48:21 UTC 2016
On Jan 28, 2016, at 8:06 AM, Eric Lippert <ericlippert at gmail.com> wrote:
>
> Later versions generated a private bridge method in Bravo that called Alpha.Echo and then had the generated closure invoke that helper method.
FTR here's the a version of Eric's example, coded with lambdas and then with inner classes.
Some disassembly is included.
In both cases javac emits a non-public helper method in Bravo that is shared with the Delta object.
In the case of lambdas, it fits together securely with a method handle.
In the case of inner classes, there is a package-scope "hole" in the access control.
The IC case would be fixed by nestmate access, if we figure out how to expand "protected"
access across a nest. Which is tricky. It might be that protected access must always go
through delegation via private methods with "proprietary" rights to call protected.
— John
http://cr.openjdk.java.net/~jrose/draft/ClosureCallSuper.java <http://cr.openjdk.java.net/~jrose/draft/ClosureCallSuper.java>
class ClosureCallSuper {
public static void main(String... av) {
new Bravo().charlie();
new Bravo_with_IC().charlie();
}
}
interface Delta { void invoke(); }
class Alpha {
public void echo() { System.out.println("Alpha.echo"); }
}
class Bravo extends Alpha {
public @Override void echo() { System.out.println("Bravo.echo"); }
public void charlie() {
int x = 123;
Delta foxtrot = () ->
{
this.echo(); //Bravo.echo
super.echo(); //Alpha.echo
System.out.println(x); //123
};
foxtrot.invoke();
}
}
class Bravo_with_IC extends Alpha {
public @Override void echo() { System.out.println("Bravo_with_IC.echo"); }
public void charlie() {
int x = 123;
Delta foxtrot = new Delta() {
public void invoke() {
Bravo_with_IC.this.echo(); //Bravo_with_IC.echo
Bravo_with_IC.super.echo(); //Alpha.echo
System.out.println(x); //123
} };
foxtrot.invoke();
}
}
/*
$ javac ClosureCallSuper.java && java ClosureCallSuper
Bravo.echo
Alpha.echo
123
Bravo_with_IC.echo
Alpha.echo
123
$ javap -p -c Bravo.class
Compiled from "ClosureCallSuper.java"
class Bravo extends Alpha {
Bravo();
Code:
0: aload_0
1: invokespecial #1 // Method Alpha."<init>":()V
4: return
public void echo();
Code:
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #3 // String Bravo.echo
5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: return
public void charlie();
Code:
0: bipush 123
2: istore_1
3: aload_0
4: iload_1
5: invokedynamic #5, 0 // InvokeDynamic #0:invoke:(LBravo;I)LDelta;
[[ (javap includes this info in -v mode)
BootstrapMethods:
0: #29 invokestatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
Method arguments:
#30 ()V
#31 invokespecial Bravo.lambda$charlie$0:(I)V
#30 ()V
]]
10: astore_2
11: aload_2
12: invokeinterface #6, 1 // InterfaceMethod Delta.invoke:()V
17: return
private void lambda$charlie$0(int);
Code:
0: aload_0
1: invokevirtual #7 // Method echo:()V
4: aload_0
5: invokespecial #8 // Method Alpha.echo:()V
8: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
11: iload_1
12: invokevirtual #9 // Method java/io/PrintStream.println:(I)V
15: return
}
$ javap -p -c Bravo_with_IC.class
Compiled from "ClosureCallSuper.java"
class Bravo_with_IC extends Alpha {
Bravo_with_IC();
Code:
0: aload_0
1: invokespecial #2 // Method Alpha."<init>":()V
4: return
public void echo();
Code:
0: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #4 // String Bravo_with_IC.echo
5: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: return
public void charlie();
Code:
0: bipush 123
2: istore_1
3: new #6 // class Bravo_with_IC$1
6: dup
7: aload_0
8: iload_1
9: invokespecial #7 // Method Bravo_with_IC$1."<init>":(LBravo_with_IC;I)V
12: astore_2
13: aload_2
14: invokeinterface #8, 1 // InterfaceMethod Delta.invoke:()V
19: return
static void access$001(Bravo_with_IC); <<<< THIS SHOULD BE PRIVATE BUT IS PACKAGE
Code:
0: aload_0
1: invokespecial #1 // Method Alpha.echo:()V
4: return
}
*/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/valhalla-spec-experts/attachments/20160128/56c7807c/attachment-0001.html>
More information about the valhalla-spec-experts
mailing list