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