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 atest/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
Why Would One Declare a Java Interface Method as Abstract
Problems Resteasy 3.09 Corsfilter
How to Change the Color of Specific Words in a Jtextpane
How to Round Time to the Nearest Quarter Hour in Java
How to Convert Words to a Number
How to Fix Invalid Byte 1 of 1-Byte Utf-8 Sequence
How Are Constructors Called During Serialization and Deserialization
Converting a String to Color in Java
Difference Between Webdriver.Get() and Webdriver.Navigate()
Using Ntlm Authentication in Java Applications
Java: Split String When an Uppercase Letter Is Found
Netbeans How to Set Command Line Arguments in Java
Why Is Super Class Constructor Always Called
Are Two Java Objects with Same Hashcodes Not Necessarily Equal
Programmatically Import Ca Trust Cert into Existing Keystore File Without Using Keytool