The InnerClasses attribute description says that
If a class has members that are classes or interfaces, its constant_pool table (and hence its InnerClasses attribute) must refer to each such member, even if that member is not otherwise mentioned by the class. These rules imply that a nested class or interface member will have InnerClasses information for each enclosing class and for each immediate member.
outer_class_info_index:
If C is not a member of a class or an interface (that is, if C is a top-level class or interface (JLS §7.6) or a local class (JLS §14.3) or an anonymous class (JLS §15.9.5)), ...
You can notice from the second paragraph that a local class or an anonymous class are not treated as "members". That means the first paragraph isn't applied to local classes or an anonymous classes. But when i compile this code (tried eclipse compiler and javac):
package bc_data;
public class Pokus {
public void metoda() {
class Pokus_Lokalni {
}
}
}
javap -v Pokus.class
Classfile /home/jara/projects/bp/bc_data/src/bc_data/Pokus.class
Last modified May 15, 2015; size 321 bytes
MD5 checksum cf9cd7707c297e7ba43b8408a9ff6e2f
Compiled from "Pokus.java"
public class bc_data.Pokus
SourceFile: "Pokus.java"
InnerClasses:
#5= #4; //Pokus_Lokalni=class bc_data/Pokus$1Pokus_Lokalni
minor version: 0
major version: 51
flags: ACC_PUBLIC, ACC_SUPER
You can see that the local class Pokus_Lokalni
is included in InnerClasses attribute even if it is not otherwise mentioned by the class Pokus
, so it is treated as "member"? Or why the local class Pokus_Lokalni
is included in the InnerClasses attribute? It is enforced by the specification somewhere?
My thoughts here are that:
Class.getDeclaredClasses
).You can notice from the second paragraph that a local class or an anonymous class are not treated as "members".
Yes, they are not members. They are still inner classes, though, so they would show up here normally.
Take a look at the first statement of the "classes[]" section:
Every CONSTANT_Class_info entry in the constant_pool table which represents a class or interface C that is not a package member must have exactly one corresponding entry in the classes array.
This means that all classes other than top-level must be included in InnerClasses.
Now outer_class_info_index section:
If C is not a member of a class or an interface (that is, if C is a top-level class or interface (JLS §7.6) or a local class (JLS §14.3) or an anonymous class (JLS §15.9.5)), the value of the outer_class_info_index item must be zero.
Otherwise, the value of the outer_class_info_index item must be a valid index into the constant_pool table, and the entry at that index must be a CONSTANT_Class_info (§4.4.1) structure representing the class or interface of which C is a member.
This means that if a class is nested (is member of another class) then outer_class_info_index must point to CONSTANT_Class_info of the enclosing class, but for local/anonymous class there exists an enclosing method instead of enclosing class.
In your case Pokus class is not obligated to have InnerClasses entry for Pokus_Lokalni. It looks like javac includes it anyway and I think I have an idea why.
If you have a local class then it is either used in a method that declares it or is not used at all (let's ignore possibility to access it with reflection). Unused local class seems to be a really strange and rare thing, so it probably doesn't worth effort to treat such situation differently. So javac may just add all local classes in constant pool (and therefore in InnerClasses).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With