I am extremely new in Java and I couldn't get one thing straight. I have E:\Java\ACP\Cricket\ directory where I have a Main.java, Player.java and CricPlayer.java. Now I am inheriting Player class into CricPlayer.
I have Main.Java as
import Java.ACP.Cricket.*;
public class Main
{
public static void main(String[] args)
{
System.out.println("Hello.");
}
}
CricPlayer.java As...
import Java.ACP.Cricket
public class CricPlayer extends Player
{
}
I need to use objects of CricPlayer in Main.java. As I mentioned earlier I am real new to Java so there might be some really obvious mistakes that I don't know about. But the question is how can I create a package for use in CricPlayer.java and Main.java? Because each time I compile the code using CMD it says "CricPlayer.java:6: error';' expected import java.ACP.Cricket.*" and points ^ to *. I don't know if I haven't created the Package properly or if it's some syntactical issue.
you need to add package declaration in the beginning of your code files. And you don't need imports if all the classes reside in the same package. BTW, good coding convention in java recommends that all letters in package name are lowercase :)
package Java.ACP.Cricket;
public class Main
{
// Your class contents
}
in the class below you shourd write a package (folder in project where file is situated)
for example
package ACP.Cricket;
You forgot the ; at your import in CricPlayer class:
import Java.ACP.Cricket.*;
Now you should be able to create CricPlayer Objects in your Main Class.
Also I don't know if "Java" in your package name is supposed to be capitalized or not. Seems like the compiler is expecting a lower case 'J' from your naming convention
Here's an alternative to your Programs.I've verified this myself, so you can be assured that it will work.
Important thing you need to know, is that any file can be compiled only if you have a main method for that file(ie in that class). so here's a detailed 'How to do it':
PlayerDemo.java:
package Java.ACP.Cricket;
class Player{
//class members & methods
}
class PlayerDemo{
public static void main(String[] args){
System.out.println("Player Class");
}
}
CricPlayerDemo.java:
package Java.ACP.Cricket;
class CricPlayer extends Player{
// class members & methods
}
class CricPlayerDemo{
public static void main(String[] args){
System.out.println("CricPlayer Class");
}
}
Main.java:
package Java.ACP.Cricket;
class Main{
public static void main(String[] args){
System.out.println("Main Class");
//use other class objects here directly.
}
}
In E: , do following stepwise:
1> javac PlayerDemo.java (this creates Player.class & PlayerDemo.class)
2> copy Player.class to Cricket folder.
3> javac CricPlayerDemo.java (this creates CricPlayer.class & CricPlayerDemo.class)
4> copy CricPlayer.class to Cricket folder.
5> javac Main.java
6> copy Main.class to Cricket folder.
7> now,also in E:, java Java/ACP/Cricket/Main
Instead of compiling from E:, you can also compile from Cricket,to avoid copying class files,but it wont work for CricPlayerDemo.java, as CricPlayer extends Player(whose location is acc to package) so you'll have to compile CricPlayerDemo from E:
Vincenzzochi is right, packages are lower case (but it should not break compilation).
And you need to declare the package at the begining of all your classes :
package java.acp.cricket;
And while all your source files are in the same package, you don't have to import anything!
Related
Purpose
I want to be able to create a package and call it.
Alternatively, I would like to create separate files for my method (to avoid having x classes in one file).
Setup
Here is my LetterGrader.java file:
package grade.util;
import java.util.*;
import java.io.*;
public class LetterGrader {
private void readArgs() {
System.out.println("Hello, read CLA!");
}
}
Here is my TestLetterGrader.java file:
import java.util.*;
import java.io.*;
public class TestLetterGrader {
public static void main(String[] args) {
LetterGrader letterGrader = new LetterGrader(); // instantiate
letterGrader.readArgs(); // call method
}
}
Steps Taken
First, I compile LetterGrader:
This auto creates the bin/grade/util/LetterGrader.class file
javac -d bin -sourcepath src src/grade/util/LetterGrader.java
Here is my working directory at this point
Second, I compile TestLetterGrader:
This fails
javac -d bin -sourcepath src src/grade/util/TestLetterGrader.java
The error message:
src/grade/util/TestLetterGrader.java:6: error: cannot find symbol
LetterGrader letterGrader = new LetterGrader(); // instantiate
^
symbol: class LetterGrader
location: class TestLetterGrader
Question
I believe I am misunderstanding how to call a classes from separate files (in the same location). How can I accomplish this?
You are importing class that is in bin folder. Don’t do that it would not work. You don’t need any import, because the classes are in the same place. Make package under src folder and place the classes there. Remove package grade.util and rename it to the package where you place the classes.
File structure:
src
\
\
yourpackage
\
\
LetterGrader.java TestLetterGrader.java
Then delete everything in your build folder and compile the classes. Java will make it’s magic. You do need to worry about bin folder, it is only for storing compiled classes.
Classes will look like this:
//package name that you created
package yourpackage;
public class LetterGrader {
//need to be public when calling from another class
public void readArgs() {
System.out.println("Hello, read CLA!");
}
}
And
//folder that you placed the .java files
package yourpackage;
//without any import
public class TestLetterGrader {
public static void main(String[] args) {
LetterGrader letterGrader = new LetterGrader(); // instantiate
letterGrader.readArgs(); // call method
}
}
Your second question:
You can use classes from other folders, but you you have to import them and they have to be under src folder.
Tell you have class A.java in folder Second and class B.java in folder Main. You will import the the folder in this case import Second.A;
And then call the class A a = new A();
When you have method in a that you want to call simply do:
a.yourmethod();
You have to change private void ... to public void... because you cannot call private outside of the class.
When you are running compiled classes they have to be in the same folder.
Thanks #maratonec for the guidance.
My initial mistake was that I was misunderstanding/misassigning the classpath assignment variable when running a program via terminal. The below helped me.
Compiling and Running a Java Program (on a PC)
• Set the working directory (say, JavaBook)
C:\> cd JavaBook
• Compile HelloWorld.java
C:\JavaBook> javac -d bin src\HelloWorld.java
•Run the program
C:\JavaBook> java -classpath bin HelloWorld
Also, the approach of having all my class files in the same location simplified things. I didn't have to worry about classpath. But not ideal as I have many files to work with.
As for the package creation, I am going to play around with java a bit more before using it. I think I need to solidify my understanding.
Thanks for helping me!
I have a Main class. I also have another class I have made (call it the "Runner" class). I would like to, however, have more Runner classes (the difference between them being modifications to each respective Runner class by other people). Would it be possible to have each Runner class in separate folders and have the folders in the same directory as the Main class, and then reference the Runner objects in the Main class as if they were a class in the same directory as the Main class?
Yes, this question strikes me like you're viewing Java like php or ruby, etc which isn't quite accurate. With Java, each class has what's called a "Fully Qualified Name" which is derived from the folder it's stored in (like Python). Because Java is compiled, you tell the compiler where to find the code needed to compile a java file, rather than putting a reference to those needed files in the top of the file (like a require statement in php) which would be an instruction to the interpreter.
Say for instance you had a structure like this:
src/
Main.java
/runner1
SomeRunner.java
/runner2
SomeOtherRunner.java
Main.java
public class Main{
public static void main(String[] args){
//use SomeRunner
runner1.SomeRunner.run();
//use SomeOtherRunner
runner2.SomeOtherRunner.run();
}
}
SomeRunner.java
package runner1;
public class SomeRunner{
public void run(){ ... }
}
SomeOtherRunner.java
package runner2;
public class SomeOtherRunner{
public void run(){ ... }
}
Alternatively, you can use imports:
Main.java
import runner1.SomeRunner;
import runner2.SomeOtherRunner;
public class Main{
public static void main(String[] args){
//use SomeRunner
SomeRunner.run();
//use SomeOtherRunner
SomeOtherRunner.run();
}
}
In this example, I chose arbitrary package names (runner1 and runner) which is technically fine. However, best practices state that your package names should be the reverse domain name of your project (i.e. com.myproject) to avoid collisions with other libraries etc. You can read more about that here. When you compile your Main class, you will need to supply the SomeRunner and SomeOtherRunner files to the compiler so it knows where to find them.
I have a TestClass java in folder:
c:\foo\bar\TestClass.java
The code looks like this:
public class TestClass {
public static void main(String[] args){
System.out.println("Hello World!");
}
}
When I type
c:\foo\bar\javac TestClass.java
then
c:\foo\bar\java TestClass
I see hello world fine.
But I want to append
package bar;
or
package foo.bar;
to my class, because it is actually in folder: foo\bar
When I add
package bar;
and do this:
c:\foo\javac bar\TestClass.java
compile is fine but when I try:
c:\foo\java bar\TestClass
I get: java.lang.NoClassDefFoundError because the package information is wrong I believe.
How can I make this work?
do
c:\foo>java bar.TestClass
instead
compiled class is different than just TestClass it is now bar.TestClass fully qualified
If you want to call the main method in a specific class inside a package, please specify the full path to the class. In your case this would be bar.TestClass, i.e.
c:\foo>java bar.TestClass
As you can see I replaced the file separator (/) with a ..
So, my code is pretty simple. Just wanted to try and create a package.
// /home/user1/Code/packageTest/src/myPackage/Test.java
package myPackage;
public class Test
{
public static void main(String[] args)
{
System.out.println("Hello, world.");
}
}
let's say this code is in some directory myPackage.
If I comment out the first line (package specification) the code runs fine, prints the message. It compiles either way, but if it compiled with the package line not commented out, it causes a run-time error.
What do I need to do to successfully make a package? I can't seem to find the right search terms to turn up a real explanation on this, only stuff about package naming conventions, why they're used to separate namespaces, bla bla bla. The next part of this experiment was going to be trying import my own packages, obviously I didn't even get that far.
Something to do with the classpath perhaps...? What and where is my "base directory"? Any information on this would be greatly appreciated.
You should create the class in a java file in a directory with name myPackage. Then you should come out of that directory and compile it as follows
javac myPackage/Test.java
Then run it with fully-qualified-class-name (FQCN) as follows:
java myPackage.Test
E.g.
C:\Temp\test1>type myPackage\Test.java
package myPackage;
public class Test
{
public static void main(String[] args)
{
System.out.println("Hello, world.");
}
}
C:\Temp\test1>javac myPackage/Test.java
C:\Temp\test1>java myPackage.Test
Hello, world.
C:\Temp\test1>
I have
public class TestApp { // TestApp.java
public static void main(String[] args) throws Exception {
TestClass x = new TestClass(); // compiler error
}
}
and
public class TestClass { // TestClass.java
public TestClass() {
}
}
TestClass was created by right clicking the project and clicking Add Class.
I'm using NetBeans
Assuming you didn't declare a package for either class:
The reason it worked after you placed them in the same folder is that they both became part of the same package.
This is the default unnamed package. All source files without a package declaration, in the same source folder, belong to that folders default package. Also, they cannot be imported for use in other packages.
It's useful for small test apps, but you should strive to put all classes in a proper package.
classes are known by their name, their full name !
com.myapplication.mymodule.Myclass
you can use the short part provided you :
use an import statement : import com.myapplication.mymodule.Myclass
use the short name in a class with same package
from your sample, before using import, you can to use full name :
com.test.TestClass x = new com.test.TestClass(); // change "com.test" for the real package