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?
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 { } }
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.
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.
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!
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