Why Does Java Code with an Inner Class Generates a Third Someclass$1.Class File

Why does Java code with an inner class generates a third SomeClass$1.class file?

The SomeClass$1.class represent anonymous inner class

hava a look at the anonymous inner class section here

How come my Java class creates multiple .class files when compiled?

Those are names given to inner classes -- it does not mean you are doing anything wrong, or that there's anything wrong with the code.

what is the signficance of the Java class files of the sort myClass$1.class?

These are anonymous inner classes in bytecode form. The compiler gives them numerical names starting with 1 (it is not allowed in Java to have a class name starting with a number, but it is possible in the bytecode, so the compiler does it to avoid name clashes, I guess). Normal (named) inner classes are named like OuterType$InnerType.class.

Multiple .class files generated for a class?

These are for inner classes and static nested classes. The ones with numbers are anonymous inner classes.

For example:


class Foo {
class Bar { }
static class Baz { }
void run() {
Helper t = new Helper() {
int helpMethod() {
return 2;
}
};
}
}

This will produce class files Foo.class, Foo$Bar.class, Foo$Baz.class and Foo$1.class (for the implementation of the Helper interface)

Why is an anonymous inner class containing nothing generated from this code?

I don't have the answer, but I'm able to confirm that, and reduce the snippet to the following:

public class OuterClass {
private class PrivateInnerClass {
}
public void instantiate() {
new PrivateInnerClass();
}
}

This creates OuterClass$1.class

Compiled from "OuterClass.java"
class OuterClass$1 extends java.lang.Object{
}

And here's javap -c for OuterClass.class:

Compiled from "OuterClass.java"
public class OuterClass extends java.lang.Object{
public OuterClass();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return

public void instantiate();
Code:
0: new #2; //class OuterClass$PrivateInnerClass
3: dup
4: aload_0
5: aconst_null
6: invokespecial #3; //Method OuterClass$PrivateInnerClass."<init>":
//(LOuterClass;LOuterClass$1;)V
9: pop
10: return

}

And for OuterClass$PrivateInnerClass:

Compiled from "OuterClass.java"
class OuterClass$PrivateInnerClass extends java.lang.Object{
final OuterClass this$0;

OuterClass$PrivateInnerClass(OuterClass, OuterClass$1);
Code:
0: aload_0
1: aload_1
2: invokespecial #1; //Method "<init>":(LOuterClass;)V
5: return

}

As you can see, the synthesized constructor takes an OuterClass$1 argument.

So javac creates the default constructor to take an extra argument, of type $1, and the value of that default argument is 5: aconst_null.


I've found that $1 doesn't get created if either of the following is true:

  • You make public class PrivateInnerClass
  • You declare a nullary constructor for PrivateInnerClass
  • Or you don't call the new on it
  • Probably other things (e.g. static nested, etc).

Possibly related

  • Bug ID:4295934: Compiling a private inner class creates an anonymous class file in the wrong dir

Create the following source in a directory called test:

package test;
public class testClass
{
private class Inner
{
}
public testClass()
{
Inner in = new Inner();
}
}

Compile the file from the parent directory javac test/testClass.java

Notice that the file testClass$1.class is created in the current directory.
Not sure why this file is even created since there is also a test/testClass$Inner.class created as well.

EVALUATION

The testClass$1.class file is for a dummy class needed by an "access
constructor" for the private constructor of the private inner class
testClass$Inner. Dissassembly shows that the fully-qualified name of
this class is correctly noted, so it is unclear why the class file ends
up in the wrong directory.

Strange class files appearing in my bin folder

These are class files generated for anonymous inner classes inside MainWindow. It probably contains a bunch of event listeners implemented as such.

Anonymous inner classes get compiled into separate class files with the name <OuterClass>$<nnn>.class, where <nnn> is a compiler-generated number.

Multiple Activity files for a single activity in android byte code

You probably have anonymous inner classes created within your activity. Since you give an anonymous inner class no name, the compiler has to come up with some way to represent it, and this is what it has chosen. Have a look at Why does Java code with an inner class generates a third SomeClass$1.class file? for more info.

Java local class .class file names

With both local classes and anonymous classes the compiler adds a number to the generated name.

Compiling the below code produced classes Test.class, Test$1Local.class, Test$2Local.class and Test$1Another.class so the compiler (jdk1.6.0_24) always adds a number to the name (maybe to avoid conflicts with inner classes) and if there are two local classes with the same name then it increments the number to avoid conflicts.

public class Test {
public void foo() {
class Local {
}
}

public void bar() {
class Local {
}
}

public void baz() {
class Another {
}
}
}

Multiple Activity files for a single activity in android byte code

You probably have anonymous inner classes created within your activity. Since you give an anonymous inner class no name, the compiler has to come up with some way to represent it, and this is what it has chosen. Have a look at Why does Java code with an inner class generates a third SomeClass$1.class file? for more info.



Related Topics



Leave a reply



Submit