Anonymous classes are not final according to reflection API

Alex Buckley alex.buckley at oracle.com
Tue Jun 30 21:16:25 UTC 2015


Philosophically I would love to mark all anonymous classes as ACC_FINAL, 
but JDK-4777101 makes clear that it can't happen for reasons of 
compatibility. (Hat tip to Peter for his explanatory mail.) If anything, 
it was a lucky escape that only a subset of anonymous classes (the inner 
ones) were marked ACC_FINAL by JDK-6219964.

In my view, Core Reflection should be changed to "lie" about the class 
files by showing the 'final' modifier as set for all anonymous classes. 
However, if it was that easy, it would have been done already, so I bet 
core-libs-dev will offer their own compatibility concerns.

Alex

On 6/29/2015 8:00 AM, Srikanth wrote:
> On Monday 29 June 2015 07:27 PM, Maurizio Cimadamore wrote:
>> Ouch. It seems like this problem existed for a very long time; the
>> logic used to strip away the ACC_FINAL flag from anon classes is more
>> or less like this:
>>
>> if (c.isInner() && c.name.isEmpty()) {
>>    flags &= ~FINAL;
>> }
>>
>> Now, isInner() will only return true _if the class has an enclosing
>> instance_ which is clearly not the case if an anon class appears in a
>> static context.
>>
>> In other words:
>>
>> class Test{
>>    void finalNo() {
>>       new Object() { }; //ACC_FINAL not set
>>    }
>>
>>     static void finalYesy() {
>>        new Object() { }; //ACC_FINAL set here
>>     }
>> }
>>
>> javap Test\$1.class
>> Compiled from "Main.java"
>> class Test$1 {
>>   final Test this$0;
>>   Test$1(Test);
>> }
>>
>> javap Test\$2.class
>> Compiled from "Main.java"
>> *final* class Test$2 {
>>   Test$2();
>> }
>>
>> I think this should be fixed so that anon classes (regardless of their
>> context) always have their ACC_FINAL bit unset; this is probably not
>> very hot from a compatibility perspective (given that it's been like
>> that for a long time) - but, given the consistency issue and the fact
>> that reflection cannot handle this anyway, I'd say we should just make
>> this consistent.
>>
>> Thoughts?
>
> Alex's comment in https://bugs.openjdk.java.net/browse/JDK-4777101,
> calls out that for anonymous classes declared in static context this bit
> is set but *seems* to take
> a position of leaving that as it is - Don't know why.
>
> I also have https://bugs.openjdk.java.net/browse/JDK-8129576 against my
> name which should closed as not an issue.
>
> Here is a query for ACC_FINAL + anonymous:
>
> https://bugs.openjdk.java.net/issues/?jql=text%20~%20%22ACC_FINAL%20anonymous%22
>
> Srikanth
>
>
>
>
>>
>> Maurizio
>>
>>
>> On 29/06/15 14:49, Maurizio Cimadamore wrote:
>>> More specifically, I was talking about this related issue:
>>>
>>> https://bugs.openjdk.java.net/browse/JDK-8130032
>>>
>>> Popping back one level, I think the issue you are seeing there, is
>>> that ACC_FINAL is erroneosuly set by javac for diamond anon classes.
>>> This seems to be against all the documentation that can be found on
>>> JBS = example:
>>>
>>> https://bugs.openjdk.java.net/browse/JDK-8023945
>>>
>>> I seem to be able to get javac spit out ACC_FINAL reliably on JDK
>>> 7/8/9 - so the question is - when did it come back? Was it
>>> deliberate? If so, was reflection ever updated to handle this?
>>>
>>> Maurizio
>>>
>>> On 29/06/15 14:36, Remi Forax wrote:
>>>> yes, right,
>>>> it seems to be a backward compatibility land of mines.
>>>>
>>>> Rémi
>>>>
>>>> On 06/29/2015 03:29 PM, Maurizio Cimadamore wrote:
>>>>> I've closed it as 'not an issue' - this seems to be an outstanding
>>>>> issue that was fixed for some time and then reverted because of
>>>>> compatibility problems:
>>>>>
>>>>> https://bugs.openjdk.java.net/browse/JDK-6520152
>>>>>
>>>>> Maurizio
>>>>>
>>>>> On 23/06/15 14:42, Georgiy Rakov wrote:
>>>>>> I've filed the issue JDK-8129576.
>>>>>> <https://bugs.openjdk.java.net/browse/JDK-8129576>
>>>>>>
>>>>>> There is following issue in JBS: JDK-4777101
>>>>>> <https://bugs.openjdk.java.net/browse/JDK-4777101> which seems to
>>>>>> relate to this one.
>>>>>>
>>>>>> Thank you,
>>>>>> Georgiy.
>>>>>>
>>>>>> On 22.06.2015 18:56, Victor Rudometov wrote:
>>>>>>> This seems to be a reflection bug, since ACC_FINAL is present in
>>>>>>> Test12$1.class file:
>>>>>>>
>>>>>>> final class test.Test12$1 extends test.Test12$Foo<java.lang.Integer>
>>>>>>>   minor version: 0
>>>>>>>   major version: 52
>>>>>>>   flags: ACC_FINAL, ACC_SUPER
>>>>>>>
>>>>>>> Thanks.
>>>>>>> Victor.
>>>>>>>
>>>>>>> On 22-Jun-15 18:35, Remi Forax wrote:
>>>>>>>> I wonder if it's not a reflection bug,
>>>>>>>> did you check with 'javap -c -verbose' the modifiers of the
>>>>>>>> generated class (something like Test12$1.class) ?
>>>>>>>>
>>>>>>>> cheers,
>>>>>>>> Rémi
>>>>>>>>
>>>>>>>> On 06/22/2015 05:17 PM, Georgiy Rakov wrote:
>>>>>>>>> Hello,
>>>>>>>>>
>>>>>>>>> if I understand correctly according to following assertion from
>>>>>>>>> JLS 15.9.5 anonymous classes are always final:
>>>>>>>>>
>>>>>>>>>     An anonymous class is always implicitly final (§8.1.1.2).
>>>>>>>>>
>>>>>>>>> But reflection API reports that the class is not final. Namely
>>>>>>>>> let's consider following code:
>>>>>>>>>
>>>>>>>>>     import java.lang.reflect.Modifier;
>>>>>>>>>
>>>>>>>>>     public class Test12 {
>>>>>>>>>         static class Foo<T> {}
>>>>>>>>>
>>>>>>>>>         public static void main(String argv[]) {
>>>>>>>>>             Foo<Integer> foo = new Foo<>() {};
>>>>>>>>>             if ( (foo.getClass().getModifiers() &
>>>>>>>>>     Modifier.FINAL) != 0 ) {
>>>>>>>>>                 System.out.println("final, modifiers: " +
>>>>>>>>>     foo.getClass().getModifiers());
>>>>>>>>>             } else {
>>>>>>>>>                 System.out.println("not final, modifiers: " +
>>>>>>>>>     foo.getClass().getModifiers());
>>>>>>>>>             }
>>>>>>>>>         }
>>>>>>>>>     }
>>>>>>>>>
>>>>>>>>> On JDK9b69 it reports:
>>>>>>>>>
>>>>>>>>>     not final, modifiers: 0
>>>>>>>>>
>>>>>>>>> Could you please tell if you consider this as a discrepancy
>>>>>>>>> between spec and javac (VM?) which should be fixed.
>>>>>>>>>
>>>>>>>>> Thank you,
>>>>>>>>> Georgiy.
>>>>>>>>
>>>>>>>
>>>>>>
>>>>>
>>>>
>>>
>>
>


More information about the compiler-dev mailing list