A Beginning Programmer’s Guide to Java
Each source file can contain one public class. The source file’s name has to be the name of that class. By convention, the source file uses a .java filename extension (a tail end of a file name that marks the file as being of a particular type of file.)
So, for a class declared as such:
The file it is stored in should be named HelloWorld.java.
The capitalization should be the same in both cases. Some operating systems don’t notice whether file names are capitalized or not. It doesn’t matter, you should be in the habit of using the correct capitalization in case you work on a system that does care about capitalization.
When you compile your file with javac, you pass the full file name to javac:
Let’s say we save the file under a different name. We write the following program:
public class HelloThere public static void main(String arg[]) System.out.println("Hello There.");
>
>
>javac HelloWorld.java
FileName.java:1: class HelloThere is public, should be declared
in a file named HelloThere.java
public class HelloThere ^
1 error
Java lets us know that it won’t compile until we rename the file appropriately (according to its rules.)
So let’s rename the file. Let’s call it HelloThere.javasource. Seems a bit more explicit than just .java, right? Let’s run the compiler:
>javac HelloThere.javasource
error: Class names, 'HelloThere.javasource', are only accepted
if annotation processing is explicitly requested
1 error
Java’s still not happy with us. Annotation processing? That’s when we include extra information in the program about the program itself. We’re not bothering with that just now. So we should just name the file HelloThere.java, and not get fancy with our file names.
But, under the right circumstances, javac does allow file name extensions other than .java. That’s why we always type in the full file name, including .java, when we use javac. We say ‘javac HelloThere.java’, not just ‘javac HelloThere’. Javac can’t assume that we mean a .java file, though that’s what it will usually be.
Once we make javac happy with a proper file name, and a program with no errors, javac produces a new file. This file will have the original file name, but with .java replaced with .class. This is your bytecode file, the file that the Java Virtual Machine can run.
When we run the program with Java, we’re running the .class file. In the case of HelloThere, we’re running the HelloThere.class file. But we don’t type in the full file name. Why?
Unlike javac, java requires a .class file. That’s all it will work with. There’s no opportunity to have a different extension to the file name. So it assumes the .class part of the file name. But that’s not the whole story.
If you add .class yourself, here’s what you’ll get:
>java HelloThere.class
Exception in thread "main" java.lang.NoClassDefFoundError:
HelloThere/class
Caused by: java.lang.ClassNotFoundException: HelloThere.class
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
Pretty ugly. What we’re actually doing when we type «java HelloThere» is telling Java to run the class HelloThere. Java assumes that it will find this in a file called «HelloThere.class«, so that’s what it’s looking for first.
We’re not telling Java to run the file HelloThere.class, we’re telling it to run the class HelloThere, which it expects to find in the file HelloThere.class.
But what if we ask for another class that doesn’t have its own .class file?
Just for fun, let’s change HelloThere.java like this, and see what happens:
public class HelloThere public static void main(String[] arg) System.out.println("Hello.");
>
>
class HelloZoik public static void main(String[] arg) System.out.println("Zoiks!");
>
>
After we edit it, we compile with ‘javac HelloThere.java‘ and hold our breath.
Now we have a second class, HelloZoik, in the HelloThere.class file. Can Java find it?
It worked! Java found our class inside HelloThere.class.
This shows it’s not the file name that we’re calling with the ‘java’ command, it’s the class name.
If Java doesn’t find the class inside a file with the same name as the class followed by .class, it’ll look in the other .class files available.
Managing Source and Class Files
Many implementations of the Java platform rely on hierarchical file systems to manage source and class files, although The Java Language Specification does not require this. The strategy is as follows.
Put the source code for a class, interface, enumeration, or annotation type in a text file whose name is the simple name of the type and whose extension is .java . For example:
//in the Rectangle.java file package graphics; public class Rectangle
Then, put the source file in a directory whose name reflects the name of the package to which the type belongs:
The qualified name of the package member and the path name to the file are parallel, assuming the Microsoft Windows file name separator backslash (for UNIX, use the forward slash).
- class name – graphics.Rectangle
- pathname to file – graphics\Rectangle.java
As you should recall, by convention a company uses its reversed Internet domain name for its package names. The Example company, whose Internet domain name is example.com , would precede all its package names with com.example . Each component of the package name corresponds to a subdirectory. So, if the Example company had a com.example.graphics package that contained a Rectangle.java source file, it would be contained in a series of subdirectories like this:
. \com\example\graphics\Rectangle.java
When you compile a source file, the compiler creates a different output file for each type defined in it. The base name of the output file is the name of the type, and its extension is .class . For example, if the source file is like this
//in the Rectangle.java file package com.example.graphics; public class Rectangle < . . . >class Helper
then the compiled files will be located at:
\com\example\graphics\Rectangle.class \com\example\graphics\Helper.class
Like the .java source files, the compiled .class files should be in a series of directories that reflect the package name. However, the path to the .class files does not have to be the same as the path to the .java source files. You can arrange your source and class directories separately, as:
\sources\com\example\graphics\Rectangle.java \classes\com\example\graphics\Rectangle.class
By doing this, you can give the classes directory to other programmers without revealing your sources. You also need to manage source and class files in this manner so that the compiler and the Java Virtual Machine (JVM) can find all the types your program uses.
The full path to the classes directory, \classes , is called the class path, and is set with the CLASSPATH system variable. Both the compiler and the JVM construct the path to your .class files by adding the package name to the class path. For example, if
is your class path, and the package name is
then the compiler and JVM look for .class files in
\classes\com\example\graphics.
A class path may include several paths, separated by a semicolon (Windows) or colon (UNIX). By default, the compiler and the JVM search the current directory and the JAR file containing the Java platform classes so that these directories are automatically in your class path.
Setting the CLASSPATH System Variable
To display the current CLASSPATH variable, use these commands in Windows and UNIX (Bourne shell):
In Windows: C:\> set CLASSPATH In UNIX: % echo $CLASSPATH
To delete the current contents of the CLASSPATH variable, use these commands:
In Windows: C:\> set CLASSPATH= In UNIX: % unset CLASSPATH; export CLASSPATH
To set the CLASSPATH variable, use these commands (for example):
In Windows: C:\> set CLASSPATH=C:\users\george\java\classes In UNIX: % CLASSPATH=/home/george/java/classes; export CLASSPATH