File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Beginning Java and the fly likes Why will class compile but public class will not compile? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "Why will class compile but public class will not compile?" Watch "Why will class compile but public class will not compile?" New topic
Author

Why will class compile but public class will not compile?

Jason Hardaway
Greenhorn

Joined: Apr 11, 2011
Posts: 26

Hello, everyone. I would like to ask a question that has me stumped at the moment. I was trying to run a program from the Head First Java 2 Ed. book on pg.196. Basically, I understand the coding as it relates to inheritance and polymorphism but I don't understand why if I copy the program verbatim from the book, the compiler will give three errors on lines 1, 9, and 43. Here is a copy of the code as it is written in the book.

This is what the compiler says:
C:\Java\src\HF2\ch7>javac TestBoats.java
TestBoats.java:1: class Rowboat is public, should be declared in a file named Rowboat.java
public class Rowboat extends Boat
^
TestBoats.java:9: class Boat is public, should be declared in a file named Boat.java
public class Boat
^
TestBoats.java:43: class Sailboat is public, should be declared in a file named
Sailboat.java
public class Sailboat extends Boat
^
3 errors
If I remove public from lines 1,9, and 43, the problem will be solved and it will compile just fine. Why is this? I understand that my TestBoats class on line 29 needs to be public because it contains main() method but why is the compiler complaining about the public declaration of the other classes? Also why did the authors use public on all the classes in this piece of code? (I don't recall them doing this on previous code exercises.) Does it have something to do with an earlier version of the JDK that the authors were possibly using at that time or am I missing something? So far, this is the only issue I have come across regarding the authors code in the book.

Thanks everyone for assisting me with this simple yet confusing issue because I am still a beginner. You all are much appreciated.

P.S - I am running JDK 1.6.0_update 24 at the moment and I set my Path and JAVA_HOME in System Variables to point to C:\Java\jdk1.6.0_24\bin if this helps solve the issue...but I don't think this is the problem.
Igor Mechnikov
Ranch Hand

Joined: Feb 13, 2011
Posts: 100

Hi,

I am in the same boat as you.

The code works when each of the public classes is in its own file.
If you want all code in one file you have to remove public.


String knock = "\u042F \u0418\u0433\u043e\u0440\u044c";
Jared Malcolm
Ranch Hand

Joined: May 02, 2011
Posts: 54

You can only have one public TOP level class per file.

For Example...

will break, but....

Is perfectly legal...
you can have a nested public class since it will never be able to be reached outside of the file...or...you can have a default access top level class for the same reasons.

Also keep in mind that if a class is public and is at the top level of a file it is REQUIRED to be in it's own .java file


SCJA 6 (Studying for SCJP 6)
Jason Hardaway
Greenhorn

Joined: Apr 11, 2011
Posts: 26

Thank you all for your replies. This is what I tried to do in regard to what Jared stated about having only one public top level class per file. I basically switched some things around in the code and made a new file called TestBoats2.java with a top level public class TestBoats2 and I placed all the other classes within the top level class. Here is what the code looks like:

Unfortunately, the compiler is still complaining. Here is what it says now:
C:\Java\src\HF2\ch7>javac TestBoats2.java
TestBoats2.java:5: non-static variable this cannot be referenced from a static context
Boat b1 = new Boat();
^
TestBoats2.java:6: non-static variable this cannot be referenced from a static context
Sailboat b2 = new Sailboat();
^
TestBoats2.java:7: non-static variable this cannot be referenced from a static context
Rowboat b3 = new Rowboat();
^
3 errors
Does anyone know what the compiler is referring to when it says that my variables b1,b2, and b3 are non-static and they can't be reference from a static context. I have not made it to these topics yet in the book so I'm not sure. Also, it appears that I do not fully understand the example Jared showed because the code still did not compile when I created a top level public class.

Also, I made another file called TestBoats3.java that only contains the main() class and I separated the other 3 classes into their own .java file like you guys stated and this compiled perfectly. I assume the authors mentioned this earlier in the book but I may have not noticed at the time. I also assume that they wrote the code in one big file to keep everything on the same page in the book but it looks like I'm supposed to separate each class into its own .java file. I will try to do that from now on to avoid confusion. At any rate, thanks again everyone for your help. It is appreciated.
Matthew Brown
Bartender

Joined: Apr 06, 2010
Posts: 4490
    
    8

Jason Hardaway wrote:
Unfortunately, the compiler is still complaining. Here is what it says now:
C:\Java\src\HF2\ch7>javac TestBoats2.java
TestBoats2.java:5: non-static variable this cannot be referenced from a static context
Boat b1 = new Boat();

What you've done there is convert all your other classes into inner classes - they are defined within the TestBoats2 class.

You might not have come across inner classes yet, but when you study them you'll find that they need to be created from an instance of the parent class. In other words, you'd need to create a TestBoats2 object before you create a Boat object.

You could fix it by turning them into static inner classes (also known as nested classes). So, for instance, the declaration becomes public static class Boat. But, to be honest, you're better off with the final approach you say works. One file per public class is the way to go. When you've studied inner classes you might want to come back to this example, though, as you'll understand better why it isn't working.
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19790
    
  20

Nested classes have the same constraints as fields and methods. If you don't make them static they need an instance of the enclosing class (TestBoats2) to be used.


SCJP 1.4 - SCJP 6 - SCWCD 5 - OCEEJBD 6
How To Ask Questions How To Answer Questions
Jason Hardaway
Greenhorn

Joined: Apr 11, 2011
Posts: 26

Matthew Brown wrote:
Jason Hardaway wrote:
Unfortunately, the compiler is still complaining. Here is what it says now:
C:\Java\src\HF2\ch7>javac TestBoats2.java
TestBoats2.java:5: non-static variable this cannot be referenced from a static context
Boat b1 = new Boat();

What you've done there is convert all your other classes into inner classes - they are defined within the TestBoats2 class.

You might not have come across inner classes yet, but when you study them you'll find that they need to be created from an instance of the parent class. In other words, you'd need to create a TestBoats2 object before you create a Boat object.

You could fix it by turning them into static inner classes (also known as nested classes). So, for instance, the declaration becomes public static class Boat. But, to be honest, you're better off with the final approach you say works. One file per public class is the way to go. When you've studied inner classes you might want to come back to this example, though, as you'll understand better why it isn't working.


You are right Matthew. I made each inner class in the TestBoats2 class a public static class and it now works perfectly. I still do not fully understand the details behind this because I have not yet made it to this part in the book.
Here is the code:

Nevertheless, this was an interesting find. I'll definitely have to come back to this code example later once I get to the chapter on this. Anyway, thanks once again guys. I appreciate your help.
Jared Malcolm
Ranch Hand

Joined: May 02, 2011
Posts: 54




Personally I would have recommended following this route. Instantiating your TestBoats2 class and then using the constructor (which is non static) to create your different objects.
Jason Hardaway
Greenhorn

Joined: Apr 11, 2011
Posts: 26

Jared Malcolm wrote:


Personally I would have recommended following this route. Instantiating your TestBoats2 class and then using the constructor (which is non static) to create your different objects.

Thank you for your help Jared. Now, I see what you were trying to show me on your earlier post for public class TestTape. Originally, I thought I was supposed to just create a new TestBoats2() object in main while keeping the other objects in main also. Here is a copy of the way I did it at that time. This is also before I learned about static.

Needless to say, the compiler was unhappy. But now, I see my mistake. At any rate, I would like to thank you all for your assistance in my learning progress. I see now that there is more than one way to skin a cat as the saying goes.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Why will class compile but public class will not compile?