Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does classname$1.class generate in this situation? [duplicate]

I wrote the following code to implement the Singleton pattern:

public final class Test {      static final class TestHolder {          private static final Test INSTANCE = new Test();      }            private Test() {}       public static Test getInstance() {          return TestHolder.INSTANCE;      } } 

When I compile this file, it should generate Test.class and Test$TestHolder.class, but it also generates Test$1.class. This doesn't make sense. So why and how would this be?

like image 500
handrenliang Avatar asked Jun 09 '13 04:06

handrenliang


People also ask

What is$ 1 class files in java?

The $1 are anonymous inner classes you defined in your WelcomeApplet. java file. e.g. compiling public class Run { public static void main(String[] args) { System.out.println(new Object() { public String toString() { return "77"; } }); } private class innerNamed { } }

What is the class name in Java?

Java provides a class with name Class in java. lang package. Instances of the class Class represent classes and interfaces in a running Java application. The primitive Java types (boolean, byte, char, short, int, long, float, and double), and the keyword void are also represented as Class objects.

How do you create an inner class in Java?

Creating an inner class is quite simple. You just need to write a class within a class. Unlike a class, an inner class can be private and once you declare an inner class private, it cannot be accessed from an object outside the class.


1 Answers

Class TestHolder needs to call the private constructor in Test. But it's private, and can't actually be called from another class. So the compiler plays a trick. It adds a new non-private constructor to Test which only it knows about! That constructor takes an (unused) instance of this anonymous class Test$1 -- which nobody knows exists. Then TestHolder creates an instance of Test$1 and calls that constructor, which is accessible (it's default-protected.)

You can use javap -c Test (and javap -c Test\$1, and javap -c Test\$TestHolder) to see the code. It's quite clever, actually!

like image 107
Ernest Friedman-Hill Avatar answered Sep 19 '22 22:09

Ernest Friedman-Hill