Redundant bridge methods in nested classes

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Fri Jul 31 10:40:22 UTC 2015


FYI - bug filed here:

https://bugs.openjdk.java.net/browse/JDK-8132776

Maurizio

On 29/07/15 18:30, Liam Miller-Cushon wrote:
> I've been trying to get a better understanding of bridge methods, and 
> noticed that javac seems to emit different bridge methods depending on 
> the order of sources passed to the compilation.
>
> As far as I can tell this occurs because TransTypes.translateClass 
> calls super.visitClassDef before addBridges. The super implementation 
> of visitClassDef processes all declarations (including nested 
> classes), so nested classes get translated before their enclosing 
> classes. If a nested class extends its enclosing class, the enclosing 
> class' bridges won't have been generated, so the nested class ends up 
> with redundant bridge methods.
>
> I don't think it's a correctness issue, but I found it surprising. Do 
> you think this is worth fixing?
>
> Here's the repro:
>
> A and B are symmetric: A's nested class extends B, B's nested class 
> extends A. Depending on the order of compilation a bridge method is 
> generated in A$Nested or B$Nested, but not both.
>
> $ cat I.java
> interface I<T> {
>   void f(T t);
> }
> $ cat A.java
> class A implements I<Number> {
>   public void f(Number x) {}
>   static class Nested extends B {
>   }
> }
> $ cat B.java
> class B implements I<Number> {
>   public void f(Number x) {}
>   static class Nested extends A {
>   }
> }
>
> # pass A.java to javac first, A$Nested has a bridge method
>
> $ rm -f *.class
> $ javac I.java A.java B.java
> $ javap -private 'A$Nested'
> Compiled from "A.java"
> class A$Nested extends B {
>   A$Nested();
>   public void f(java.lang.Object);
> }
> $ javap -private 'B$Nested'
> Compiled from "B.java"
> class B$Nested extends A {
>   B$Nested();
> }
>
> # pass B.java to javac first, B$Nested has a bridge method
>
> $ rm -f *.class
> $ javac I.java B.java A.java
> $ javap -private 'A$Nested'
> Compiled from "A.java"
> class A$Nested extends B {
>   A$Nested();
> }
> $ javap -private 'B$Nested'
> Compiled from "B.java"
> class B$Nested extends A {
>   B$Nested();
>   public void f(java.lang.Object);
> }



More information about the compiler-dev mailing list