The Artima Developer Community
Sponsored Link

Legacy Java Answers Forum
March 2001

Advertisement

Advertisement

This page contains an archived post to the Java Answers Forum made prior to February 25, 2002. If you wish to participate in discussions, please visit the new Artima Forums.

Message:

surprise with static classes having private constructors

Posted by Neville on April 01, 2001 at 12:19 AM

(delete "antispam" from the domain name above to obtain my true email address)

Can anyone explain to me the strange treatment by the JDK 1.3 javac compiler of a static nested class with a private constructor? An unexpected, apparently local, class file is compiled from the sample code shown below:

class Outer
{
Outer(){
Nested i = new Nested();
}
static class Nested
{
// Outer$1.class is created if constructor is private
private Nested(){
}
}
}

A file Outer$1.class is created in addition to the expected Outer.class and Outer$Nested.class. The compiler does not generate Outer$1.class if the private access modifier is deleted from the Nested constructor declaration as follows:

class Outer
{
Outer(){
Nested i = new Nested();
}
static class Nested
{
// Outer$1.class is created if constructor is private
Nested(){
}
}
}

When the Nested constructor is declared private, a disassembly
of the Outer$Nested.class shows an unexpected extra constructor
that takes an argument of type Outer$1:

---- disassembly of Outer$Nested (private constructor) ----

Compiled from Outer.java
public static class Outer. Nested extends java.lang.Object
/* ACC_SUPER bit NOT set */
{
private Outer.Nested();
/* ()V */
/* Stack=1, Locals=1, Args_size=1 */
Outer.Nested(Outer$1);
/* (LOuter$1;)V */
/* Stack=1, Locals=2, Args_size=2 */
}

Method Outer. Nested()
0 aload_0
1 invokespecial #2
4 return

Line numbers for method Outer. Nested()
line 12: 0
line 13: 4

Method Outer. Nested(Outer$1)
0 aload_0
1 invokespecial #1
4 return

Line numbers for method Outer. Nested(Outer$1)
line 8: 0

--- end disassembly of Outer$Nested (private constructor) ---

A disassembly of Outer.class contains the following entry
that shows the undeclared Nested constructor is performed
on the Nested object created in the Outer constructor:

9 invokespecial #3

A disassembly of Outer$1 shows it to be an empty class:

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

When the Nested constructor has package access,
a disassembly shows only one constructor as expected:

---- disassembly of Outer$Nested (package constructor) ----

Compiled from Outer.java
public static class Outer. Nested extends java.lang.Object
/* ACC_SUPER bit NOT set */
{
Outer.Nested();
/* ()V */
/* Stack=1, Locals=1, Args_size=1 */
}

Method Outer. Nested()
0 aload_0
1 invokespecial #1
4 return

Line numbers for method Outer. Nested()
line 12: 0
line 13: 4

--- end disassembly of Outer$Nested (package constructor) ---

When the Nested constructor has package access,
the Outer constructor calls the expected Nested constructor:

8 invokespecial #3

Why this strange distinction between public and private
static classes? Does this have anything to do with
security?




Replies:

Sponsored Links



Google
  Web Artima.com   
Copyright © 1996-2009 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use - Advertise with Us