3 .class files generated for 1 .java file

3 .class files generated for 1 .java file

Post by qazm » Tue, 20 Jan 2004 01:44:02



I wrote the following code to get more type-safe C++-equivalent enum in Java.
Whenever I compile this code, 3 class files are generated. Why?
testClass$1.class          
testClass$State.class  
testClass.class

I expected only 1 class, 'testClass.class' to be generated. I do not understand
why other two classes(mainly testClass$1.class) are generated additionally.
Please clarify.

------testClass.java------
public class testClass
{
  public static class State
  {
    private final String StateStr ;
    private State(String StateStr ) { this.StateStr = StateStr ; }
    public String toString()  { return StateStr ; }
    public final boolean equals(Object that)
    {
      return super.equals(that);
    }
    public final int hashCode()
    {
      return super.hashCode();
    }
  }

  public static final State STATE_ONE = new State( "STATE_ONE" ) ;
  public static final State STATE_TWO = new State( "STATE_TWO" ) ;

Quote:}

------testClass.java------
 
 
 

3 .class files generated for 1 .java file

Post by Suds » Tue, 20 Jan 2004 01:57:21



> I wrote the following code to get more type-safe C++-equivalent enum in Java.
> Whenever I compile this code, 3 class files are generated. Why?
> testClass$1.class          
> testClass$State.class  
> testClass.class

> I expected only 1 class, 'testClass.class' to be generated. I do not understand
> why other two classes(mainly testClass$1.class) are generated additionally.
> Please clarify.

> ------testClass.java------
> public class testClass
> {
>   public static class State

You've got an inner class here. That gives rise to the
testClass$State.class file. Note the name following the
$ sign: same as the name of your inner class. Why ARE
you trying to create the inner class in the first place?

 
 
 

3 .class files generated for 1 .java file

Post by Dave Glasse » Tue, 20 Jan 2004 03:13:45



-0500 in comp.lang.java.programmer:


>> I wrote the following code to get more type-safe C++-equivalent enum in Java.
>> Whenever I compile this code, 3 class files are generated. Why?
>> testClass$1.class          
>> testClass$State.class  
>> testClass.class

>> I expected only 1 class, 'testClass.class' to be generated. I do not understand
>> why other two classes(mainly testClass$1.class) are generated additionally.
>> Please clarify.

>> ------testClass.java------
>> public class testClass
>> {
>>   public static class State

>You've got an inner class here. That gives rise to the
>testClass$State.class file. Note the name following the
>$ sign: same as the name of your inner class. Why ARE
>you trying to create the inner class in the first place?

What difference does that make?

--
Check out QueryForm, a free, open source, Java/Swing-based
front end for relational databases.

http://qform.sourceforge.net

 
 
 

3 .class files generated for 1 .java file

Post by Tony Morri » Tue, 20 Jan 2004 08:07:20


testClass$State.class
Inner class called "State"

testClass$1.class
Anonymous inner class.

--
Tony Morris
(BInfTech, Cert 3 I.T., SCJP[1.4], SCJD)
Software Engineer
IBM Australia - Tivoli Security Software
(2003 VTR1000F)


Quote:> I wrote the following code to get more type-safe C++-equivalent enum in
Java.
> Whenever I compile this code, 3 class files are generated. Why?
> testClass$1.class
> testClass$State.class
> testClass.class

> I expected only 1 class, 'testClass.class' to be generated. I do not
understand
> why other two classes(mainly testClass$1.class) are generated
additionally.
> Please clarify.

> ------testClass.java------
> public class testClass
> {
>   public static class State
>   {
>     private final String StateStr ;
>     private State(String StateStr ) { this.StateStr = StateStr ; }
>     public String toString()  { return StateStr ; }
>     public final boolean equals(Object that)
>     {
>       return super.equals(that);
>     }
>     public final int hashCode()
>     {
>       return super.hashCode();
>     }
>   }

>   public static final State STATE_ONE = new State( "STATE_ONE" ) ;
>   public static final State STATE_TWO = new State( "STATE_TWO" ) ;
> }
> ------testClass.java------

 
 
 

3 .class files generated for 1 .java file

Post by Dave Glasse » Tue, 20 Jan 2004 08:56:11



09:07:20 +1000 in comp.lang.java.programmer:

Quote:>testClass$State.class
>Inner class called "State"

>testClass$1.class
>Anonymous inner class.

Where's the code that's creating the anonymous inner class?

--
Check out QueryForm, a free, open source, Java/Swing-based
front end for relational databases.

http://qform.sourceforge.net

 
 
 

3 .class files generated for 1 .java file

Post by Chris Uppa » Tue, 20 Jan 2004 18:19:11



> I wrote the following code to get more type-safe C++-equivalent enum in
> Java. Whenever I compile this code, 3 class files are generated. Why?

Expanding on the answers the others have already offered.

It is important to realise that Java is compiled *into* a high-level,
object-oriented, garbage collected, programming language called "JVM
bytecodes".  Also known as classfiles.

That language is quite clean*, and is (I think) well worth looking into -- if
nothing else you will gain a better understanding of what Java can and can't do
(I'm not recommending that you learn to read/write JVM bytecodes themselves --
far too fiddly -- but it *is* worthwhile finding out what the semantics of the
JVM are).

In this case, the point is that while *Java* has nested classes, the *JVM* does
not.  It never has had, and -- I expect -- never will have.  So, the Java
compiler has to do some tricks to make it look as if those nested classes were
real (they are not, but the trick is quite good all the same).   To compile
your code, the compiler "pretends" that it had been written:

================
public class TestClass
{
    public static final State STATE_ONE
                = new State("STATE_ONE", (TestClass$1)null);
    public static final State STATE_TWO
                = new State("STATE_TWO", (TestClass$1)null);

Quote:}

class TestClass$1
{

Quote:}

public class TestClass$State
{
    private final String StateStr;
    private TestClass$State(String StateStr) { this.StateStr = StateStr; }
    TestClass$State(String StateStr, TestClass$1 x) { this(StateStr); }
    public String toString() { return StateStr; }
    public final boolean equals(Object that)
    {
       return super.equals(that);
    }
    public final int hashCode()
    {
            return super.hashCode();
    }
Quote:}

================

(I've changed the class name to conform to the important convention that *all*
class names start in UPPER-CASE.)

You'll see that your nested class 'State' has been made into a real class in
its own right.  Since the nested class was static, that's almost all the
compiler had to do (if it had been non-static, and especially if it had been an
inner class, then the compiler would have had to do more work).  The only "odd"
thing is that, since you have declared the constructor for TestClass.State to
be private, that's what it has to be.  So it is.  But that gives the compiler a
problem, because the class initialiser for TestClass seems to call it.  So what
the compiler does is create a "hidden" constructor that is not public, but
which is used only by TestClass.  That constructor has to be different from the
one you provided, so the compiler creates a third class which is only ever used
as a "label" (no instances are ever created) for the additional constructor.

Since the extra constructor is package private, as is the label class itself,
this doesn't constitute an *enormous* hole in the Java security model, although
it's quite easy (unless you seal the jar file) for another programmer to access
the hidden constructor if he/she wants.  But then, if you are worried about
such things, then you should also be aware that (for instance) the Sun 1.4.x
JVM does *not* enforce the member access rules at runtime unless you give it
the -future flag (it *should*, according to the spec, but it doesn't ;-).

    -- chris

[*] cleaner than Java anyway.

 
 
 

3 .class files generated for 1 .java file

Post by Karl von Lauderma » Wed, 21 Jan 2004 00:39:04



> I wrote the following code to get more type-safe C++-equivalent enum in Java.

As others have given you thorough answers to your actual question, I
won't reiterate what they've said. But I'd just like to point out that
Sun has a recommended pattern for typesafe enums, which you can find
at
http://developer.java.sun.com/developer/Books/shiftintojava/page1.htm...

It's similar to the way you've done it, but it doesn't use an inner
class. Also, supposedly Java 1.5 will include language support for
enums. There will basically be a simple syntax from which the compiler
generates the above pattern automatically.

 
 
 

1. Java Kernel Support can't find class in .class file

I've recompiled for kernel support of Java.  Using a module for Java.
Using Linux 2.0.27

/etc/bashrc:
export CLASSPATH=/usr/local/java/lib/classs:.

I tried to run the HelloWorld.java program from Documentation/java.txt

Any ideas?
--
=============== ==============================================
Paul Cummings   "That's an awful lot of ships." --Ivanova

=Linux=v2.0.27= ==============================================

2. Solaris 2.6 and /dev/term devices. How to remove a term from interactive group/control??

3. Simple .java file won't compile - Permission to write .class file denied

4. rmmod: device or resource busy?

5. java/44041: Generate bsd.java.mk from an XML file

6. SLS X386 dies with blue screen. how to debug?

7. java/43981: java/jdk1?-doc ports should dynamically generate plist file

8. fsck out of memory

9. java/44041: Generate bsd.java.mk from an XML file

10. Organization of Java class files (admin question).

11. java.class files

12. Apache JServ and servlet using non-public classes within the same .java file

13. Help on running java class files