To my understand correctly anonymous classes
are always final
:
This has been mentioned specifically in JLS 15.9.5
However, when i run the following code to check that it is showing that Inner
class is not final
.
public class Test{
static class A<T> {
}
public static void main(String arg[]) {
A<Integer> obj = new A() {
};
if ((obj.getClass().getModifiers() & Modifier.FINAL) != 0) {
System.out.println("It is a final " + obj.getClass().getModifiers());
} else {
System.out.println("It is not final " + obj.getClass().getModifiers());
}
}
}
Output of above program is :
It is not final 0
Please clear my doubt as i am not able to understand this behavior.
JLS 15.9.5 "...implicitly final"... But that is not "final", what is meant is that you just can't extend an anonymous class. There is no syntactic construction for this, but the class is not marked as final.
I agree this may be considered a bug, given that other cases in the JLS exhibit a different behavior. Case in point is an interface: As per section 9.1.1.1:
And when running the below:
It returns true.
Another example is an enum where the JLS specifies:
And the below example is perfectly aligned with it.
Explicit is something what is written in the source code. So, if something is declared as
public final class
, it means that the class is explicitly final.Implicit is something that is not written down in the source code, but that in the context of a certain construct or based on the language rules, an element behaves as it were declared with the specified modifier.
For example, the keyword
enum
in the declarationenum SomeEnum { }
causesSomeEnum
to befinal
, because the language rules prescribe it. Its effect is the same as the effect of the keywordfinal
.The example of an anonymous class being implicitly final is because no language construct exists to override an anonymous class. So it behaves as if it were
final
. I think the word "effectively" is better here.However, you cannot make assumptions based on how reflection presents things. Consider the following snippet:
The result is this:
Both
interface
andabstract interface
are considered an abstract interface. They are also considered static by reflection. Apparently, in the process of parsing and compiling the Java source code, some modifiers could be removed or added.