Anonymous classes are not final according to reflection API

Srikanth srikanth.adayapalam at oracle.com
Mon Jun 29 15:00:09 UTC 2015



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.
>>>>>>>
>>>>>>
>>>>>
>>>>
>>>
>>
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20150629/7f57e1c5/attachment.html>


More information about the compiler-dev mailing list