Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

InnerClasses attribute

Tags:

java

class

jvm

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?

like image 921
Krab Avatar asked Oct 19 '22 11:10

Krab


2 Answers

My thoughts here are that:

  • The inclusion in the class file needs to be mandated for member classes for the purpose of reflection (because of e.g. Class.getDeclaredClasses).
  • This is not so for local and anonymous classes, but there isn't a reason they can't be stored anyway, even though it's not mandated.

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.

like image 152
Radiodef Avatar answered Nov 15 '22 05:11

Radiodef


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

like image 41
Stanislav Lukyanov Avatar answered Nov 15 '22 03:11

Stanislav Lukyanov