Although it is based on C++, Java is more of a pure object-oriented language.
Both C++ and Java are hybrid languages, but in Java the designers felt that the hybridization was not as important as it was in C++. A hybrid language allows multiple programming styles; the reason C++ is hybrid is to support backward compatibility with the C language. Because C++ is a superset of the C language, it includes many of that languages undesirable features, which can make some aspects of C++ overly complicated. Feedback
The Java language assumes that you want to do only object-oriented programming. This means that before you can begin you must shift your mindset into an object-oriented world (unless its already there). The benefit of this initial effort is the ability to program in a language that is simpler to learn and to use than many other OOP languages. In this chapter well see the basic components of a Java program and well learn that everything in Java is an object, even a Java program. Feedback
Each programming language has its own means of manipulating data. Sometimes the programmer must be constantly aware of what type of manipulation is going on. Are you manipulating the object directly, or are you dealing with some kind of indirect representation (a pointer in C or C++) that must be treated with a special syntax? Feedback
All this is simplified in Java. You treat everything as an object, using a single consistent syntax. Although you treat everything as an object, the identifier you manipulate is actually a reference to an object.[10] You might imagine this scene as a television (the object) with your remote control (the reference). As long as youre holding this reference, you have a connection to the television, but when someone says change the channel or lower the volume, what youre manipulating is the reference, which in turn modifies the object. If you want to move around the room and still control the television, you take the remote/reference with you, not the television. Feedback
Also, the remote control can stand on its own, with no television. That is, just because you have a reference doesnt mean theres necessarily an object connected to it. So if you want to hold a word or sentence, you create a String reference: Feedback
String s;
But here youve created only the reference, not an object. If you decided to send a message to s at this point, youll get an error (at run time) because s isnt actually attached to anything (theres no television). A safer practice, then, is always to initialize a reference when you create it: Feedback
String s = "asdf";
However, this uses a special Java feature: strings can be initialized with quoted text. Normally, you must use a more general type of initialization for objects. Feedback
When you create a reference, you want to connect it with a new object. You do so, in general, with the new keyword. The keyword new says, Make me a new one of these objects. So in the preceding example, you can say: Feedback
String s = new String("asdf");
Not only does this mean Make me a new String, but it also gives information about how to make the String by supplying an initial character string. Feedback
Of course, String is not the only type that exists. Java comes with a plethora of ready-made types. Whats more important is that you can create your own types. In fact, thats the fundamental activity in Java programming, and its what youll be learning about in the rest of this book. Feedback
Its useful to visualize some aspects of how things are laid out while the program is runningin particular how memory is arranged. There are six different places to store data: Feedback
One group of types, which youll use quite often in your programming, gets special treatment. You can think of these as primitive types. The reason for the special treatment is that to create an object with newespecially a small, simple variableisnt very efficient, because new places objects on the heap. For these types Java falls back on the approach taken by C and C++. That is, instead of creating the variable by using new, an automatic variable is created that is not a reference. The variable holds the value, and its placed on the stack, so its much more efficient. Feedback
Java determines the size of each primitive type. These sizes dont change from one machine architecture to another as they do in most languages. This size invariance is one reason Java programs are portable. Feedback
Primitive type |
Size |
Minimum |
Maximum |
Wrapper type |
---|---|---|---|---|
boolean |
|
|
|
Boolean |
char |
16-bit |
Unicode 0 |
Unicode 216- 1 |
Character |
byte |
8-bit |
-128 |
+127 |
Byte |
short |
16-bit |
-215 |
+2151 |
Short |
int |
32-bit |
-231 |
+2311 |
Integer |
long |
64-bit |
-263 |
+2631 |
Long |
float |
32-bit |
IEEE754 |
IEEE754 |
Float |
double |
64-bit |
IEEE754 |
IEEE754 |
Double |
void |
|
|
|
Void |
All numeric types are signed, so dont look for unsigned types. Feedback
The size of the boolean type is not explicitly specified; it is only defined to be able to take the literal values true or false. Feedback
The wrapper classes for the primitive data types allow you to make a nonprimitive object on the heap to represent that primitive type. For example: Feedback
char c = 'x'; Character C = new Character(c);
Or you could also use:
Character C = new Character('x');
The reasons for doing this will be shown in a later chapter. Feedback
Java includes two classes for performing high-precision arithmetic: BigInteger and BigDecimal. Although these approximately fit into the same category as the wrapper classes, neither one has a primitive analogue. Feedback
Both classes have methods that provide analogues for the operations that you perform on primitive types. That is, you can do anything with a BigInteger or BigDecimal that you can with an int or float, its just that you must use method calls instead of operators. Also, since theres more involved, the operations will be slower. Youre exchanging speed for accuracy. Feedback
BigInteger supports arbitrary-precision integers. This means that you can accurately represent integral values of any size without losing any information during operations. Feedback
BigDecimal is for arbitrary-precision fixed-point numbers; you can use these for accurate monetary calculations, for example. Feedback
Consult the JDK documentation for details about the constructors and methods you can call for these two classes. Feedback
Virtually all programming languages support arrays. Using arrays in C and C++ is perilous because those arrays are only blocks of memory. If a program accesses the array outside of its memory block or uses the memory before initialization (common programming errors), there will be unpredictable results. Feedback
One of the primary goals of Java is safety, so many of the problems that plague programmers in C and C++ are not repeated in Java. A Java array is guaranteed to be initialized and cannot be accessed outside of its range. The range checking comes at the price of having a small amount of memory overhead on each array as well as verifying the index at run time, but the assumption is that the safety and increased productivity is worth the expense. Feedback
When you create an array of objects, you are really creating an array of references, and each of those references is automatically initialized to a special value with its own keyword: null. When Java sees null, it recognizes that the reference in question isnt pointing to an object. You must assign an object to each reference before you use it, and if you try to use a reference thats still null, the problem will be reported at run time. Thus, typical array errors are prevented in Java. Feedback
You can also create an array of primitives. Again, the compiler guarantees initialization because it zeroes the memory for that array. Feedback
Arrays will be covered in detail in later chapters. Feedback
In most programming languages, the concept of the lifetime of a variable occupies a significant portion of the programming effort. How long does the variable last? If you are supposed to destroy it, when should you? Confusion over variable lifetimes can lead to a lot of bugs, and this section shows how Java greatly simplifies the issue by doing all the cleanup work for you. Feedback
Most procedural languages have the concept of scope. This determines both the visibility and lifetime of the names defined within that scope. In C, C++, and Java, scope is determined by the placement of curly braces {}. So for example: Feedback
{ int x = 12; // Only x available { int q = 96; // Both x & q available } // Only x available // q out of scope }
A variable defined within a scope is available only to the end of that scope. Feedback
Any text after a // to the end of a line is a comment.
Indentation makes Java code easier to read. Since Java is a free-form language, the extra spaces, tabs, and carriage returns do not affect the resulting program. Feedback
Note that you cannot do the following, even though it is legal in C and C++:
{ int x = 12; { int x = 96; // Illegal } }
The compiler will announce that the variable x has already been defined. Thus the C and C++ ability to hide a variable in a larger scope is not allowed, because the Java designers thought that it led to confusing programs. Feedback
Java objects do not have the same lifetimes as primitives. When you create a Java object using new, it hangs around past the end of the scope. Thus if you use:
{ String s = new String("a string"); } // End of scope
the reference s vanishes at the end of the scope. However, the String object that s was pointing to is still occupying memory. In this bit of code, there is no way to access the object, because the only reference to it is out of scope. In later chapters youll see how the reference to the object can be passed around and duplicated during the course of a program. Feedback
It turns out that because objects created with new stay around for as long as you want them, a whole slew of C++ programming problems simply vanish in Java. The hardest problems seem to occur in C++ because you dont get any help from the language in making sure that the objects are available when theyre needed. And more important, in C++ you must make sure that you destroy the objects when youre done with them. Feedback
That brings up an interesting question. If Java leaves the objects lying around, what keeps them from filling up memory and halting your program? This is exactly the kind of problem that would occur in C++. This is where a bit of magic happens. Java has a garbage collector, which looks at all the objects that were created with new and figures out which ones are not being referenced anymore. Then it releases the memory for those objects, so the memory can be used for new objects. This means that you never need to worry about reclaiming memory yourself. You simply create objects, and when you no longer need them, they will go away by themselves. This eliminates a certain class of programming problem: the so-called memory leak, in which a programmer forgets to release memory. Feedback
If everything is an object, what determines how a particular class of object looks and behaves? Put another way, what establishes the type of an object? You might expect there to be a keyword called type, and that certainly would have made sense. Historically, however, most object-oriented languages have used the keyword class to mean Im about to tell you what a new type of object looks like. The class keyword (which is so common that it will not be bold-faced throughout this book) is followed by the name of the new type. For example: Feedback
class ATypeName { /* Class body goes here */ }
This introduces a new type, although the class body consists only of a comment (the stars and slashes and what is inside, which will be discussed later in this chapter), so there is not too much that you can do with it. However, you can create an object of this type using new:
ATypeName a = new ATypeName();
But you cannot tell it to do much of anything (that is, you cannot send it any interesting messages) until you define some methods for it. Feedback
When you define a class (and all you do in Java is define classes, make objects of those classes, and send messages to those objects), you can put two types of elements in your class: fields (sometimes called data members), and methods (sometimes called member functions). A field is an object of any type that you can communicate with via its reference. It can also be one of the primitive types (which isnt a reference). If it is a reference to an object, you must initialize that reference to connect it to an actual object (using new, as seen earlier) in a special method called a constructor (described fully in Chapter 4). If it is a primitive type, you can initialize it directly at the point of definition in the class. (As youll see later, references can also be initialized at the point of definition.) Feedback
Each object keeps its own storage for its fields; the fields are not shared among objects. Here is an example of a class with some fields: Feedback
class DataOnly { int i; float f; boolean b; }
This class doesnt do anything, but you can create an object: Feedback
DataOnly d = new DataOnly();
You can assign values to the fields, but you must first know how to refer to a member of an object. This is accomplished by stating the name of the object reference, followed by a period (dot), followed by the name of the member inside the object: Feedback
objectReference.member
For example: Feedback
d.i = 47; d.f = 1.1f; // f after number indicates float constant d.b = false;
It is also possible that your object might contain other objects that contain data youd like to modify. For this, you just keep connecting the dots. For example: Feedback
myPlane.leftTank.capacity = 100;
The DataOnly class cannot do much of anything except hold data, because it has no methods. To understand how those work, you must first understand arguments and return values, which will be described shortly. Feedback
When a primitive data type is a member of a class, it is guaranteed to get a default value if you do not initialize it:
Primitive type |
Default |
---|---|
boolean |
false |
char |
\u0000 (null) |
byte |
(byte)0 |
short |
(short)0 |
int |
0 |
long |
0L |
float |
0.0f |
double |
0.0d |
Note carefully that the default values are what Java guarantees when the variable is used as a member of a class. This ensures that member variables of primitive types will always be initialized (something C++ doesnt do), reducing a source of bugs. However, this initial value may not be correct or even legal for the program you are writing. Its best to always explicitly initialize your variables. Feedback
This guarantee doesnt apply to local variablesthose that are not fields of a class. Thus, if within a method definition you have:
int x;
Then x will get some arbitrary value (as in C and C++); it will not automatically be initialized to zero. You are responsible for assigning an appropriate value before you use x. If you forget, Java definitely improves on C++: you get a compile-time error telling you the variable might not have been initialized. (Many C++ compilers will warn you about uninitialized variables, but in Java these are errors.) Feedback
In many languages (like C and C++), the term function is used to describe a named subroutine. The term that is more commonly used in Java is method, as in a way to do something. If you want, you can continue thinking in terms of functions. Its really only a syntactic difference, but this book follows the common Java usage of the term method. Feedback
Methods in Java determine the messages an object can receive. In this section you will learn how simple it is to define a method. Feedback
The fundamental parts of a method are the name, the arguments, the return type, and the body. Here is the basic form:
returnType methodName( /* Argument list */ ) { /* Method body */ }
The return type is the type of the value that pops out of the method after you call it. The argument list gives the types and names for the information you want to pass into the method. The method name and argument list together uniquely identify the method. Feedback
Methods in Java can be created only as part of a class. A method can be called only for an object,[11] and that object must be able to perform that method call. If you try to call the wrong method for an object, youll get an error message at compile time. You call a method for an object by naming the object followed by a period (dot), followed by the name of the method and its argument list, like this:
objectName.methodName(arg1, arg2, arg3);
For example, suppose you have a method f( ) that takes no arguments and returns a value of type int. Then, if you have an object called a for which f( ) can be called, you can say this:
int x = a.f();
The type of the return value must be compatible with the type of x. Feedback
This act of calling a method is commonly referred to as sending a message to an object. In the preceding example, the message is f( ) and the object is a. Object-oriented programming is often summarized as simply sending messages to objects. Feedback
The method argument list specifies what information you pass into the method. As you might guess, this informationlike everything else in Javatakes the form of objects. So, what you must specify in the argument list are the types of the objects to pass in and the name to use for each one. As in any situation in Java where you seem to be handing objects around, you are actually passing references.[12] The type of the reference must be correct, however. If the argument is supposed to be a String, you must pass in a String or the compiler will give an error. Feedback
Consider a method that takes a String as its argument. Here is the definition, which must be placed within a class definition for it to be compiled:
int storage(String s) { return s.length() * 2; }
This method tells you how many bytes are required to hold the information in a particular String. (Each char in a String is 16 bits, or two bytes, long, to support Unicode characters.) The argument is of type String and is called s. Once s is passed into the method, you can treat it just like any other object. (You can send messages to it.) Here, the length( ) method is called, which is one of the methods for Strings; it returns the number of characters in a string. Feedback
You can also see the use of the return keyword, which does two things. First, it means leave the method, Im done. Second, if the method produces a value, that value is placed right after the return statement. In this case, the return value is produced by evaluating the expression s.length( ) * 2. Feedback
You can return any type you want, but if you dont want to return anything at all, you do so by indicating that the method returns void. Here are some examples:
boolean flag() { return true; } float naturalLogBase() { return 2.718f; } void nothing() { return; } void nothing2() {}
When the return type is void, then the return keyword is used only to exit the method, and is therefore unnecessary when you reach the end of the method. You can return from a method at any point, but if youve given a non-void return type, then the compiler will force you (with error messages) to return the appropriate type of value regardless of where you return. Feedback
At this point, it can look like a program is just a bunch of objects with methods that take other objects as arguments and send messages to those other objects. That is indeed much of what goes on, but in the following chapter youll learn how to do the detailed low-level work by making decisions within a method. For this chapter, sending messages will suffice. Feedback
There are several other issues you must understand before seeing your first Java program. Feedback
A problem in any programming language is the control of names. If you use a name in one module of the program, and another programmer uses the same name in another module, how do you distinguish one name from another and prevent the two names from clashing? In C this is a particular problem because a program is often an unmanageable sea of names. C++ classes (on which Java classes are based) nest functions within classes so they cannot clash with function names nested within other classes. However, C++ still allows global data and global functions, so clashing is still possible. To solve this problem, C++ introduced namespaces using additional keywords. Feedback
Java was able to avoid all of this by taking a fresh approach. To produce an unambiguous name for a library, the specifier used is not unlike an Internet domain name. In fact, the Java creators want you to use your Internet domain name in reverse since those are guaranteed to be unique. Since my domain name is BruceEckel.com, my utility library of foibles would be named com.bruceeckel.utility.foibles. After your reversed domain name, the dots are intended to represent subdirectories. Feedback
In Java 1.0 and Java 1.1 the domain extensions com, edu, org, net, etc., were capitalized by convention, so the library would appear: COM.bruceeckel.utility.foibles. Partway through the development of Java 2, however, it was discovered that this caused problems, so now the entire package name is lowercase. Feedback
This mechanism means that all of your files automatically live in their own namespaces, and each class within a file must have a unique identifier. So you do not need to learn special language features to solve this problemthe language takes care of it for you. Feedback
Whenever you want to use a predefined class in your program, the compiler must know how to locate it. Of course, the class might already exist in the same source code file that its being called from. In that case, you simply use the classeven if the class doesnt get defined until later in the file (Java eliminates the forward referencing problem, so you dont need to think about it). Feedback
What about a class that exists in some other file? You might think that the compiler should be smart enough to simply go and find it, but there is a problem. Imagine that you want to use a class with a particular name, but more than one definition for that class exists (presumably these are different definitions). Or worse, imagine that youre writing a program, and as youre building it you add a new class to your library that conflicts with the name of an existing class. Feedback
To solve this problem, you must eliminate all potential ambiguities. This is accomplished by telling the Java compiler exactly what classes you want by using the import keyword. import tells the compiler to bring in a package, which is a library of classes. (In other languages, a library could consist of functions and data as well as classes, but remember that all code in Java must be written inside a class.) Feedback
Most of the time youll be using components from the standard Java libraries that come with your compiler. With these, you dont need to worry about long, reversed domain names; you just say, for example:
import java.util.ArrayList;
to tell the compiler that you want to use Javas ArrayList class. However, util contains a number of classes and you might want to use several of them without declaring them all explicitly. This is easily accomplished by using * to indicate a wild card:
import java.util.*;
It is more common to import a collection of classes in this manner than to import classes individually. Feedback
Ordinarily, when you create a class you are describing how objects of that class look and how they will behave. You dont actually get anything until you create an object of that class with new, and at that point data storage is created and methods become available. Feedback
But there are two situations in which this approach is not sufficient. One is if you want to have only one piece of storage for a particular piece of data, regardless of how many objects are created, or even if no objects are created. The other is if you need a method that isnt associated with any particular object of this class. That is, you need a method that you can call even if no objects are created. You can achieve both of these effects with the static keyword. When you say something is static, it means that data or method is not tied to any particular object instance of that class. So even if youve never created an object of that class you can call a static method or access a piece of static data. With ordinary, non-static data and methods, you must create an object and use that object to access the data or method, since non-static data and methods must know the particular object they are working with. Of course, since static methods dont need any objects to be created before they are used, they cannot directly access non-static members or methods by simply calling those other members without referring to a named object (since non-static members and methods must be tied to a particular object). Feedback
Some object-oriented languages use the terms class data and class methods, meaning that the data and methods exist only for the class as a whole, and not for any particular objects of the class. Sometimes the Java literature uses these terms too. Feedback
To make a field or method static, you simply place the keyword before the definition. For example, the following produces a static field and initializes it: Feedback
class StaticTest { static int i = 47; }
Now even if you make two StaticTest objects, there will still be only one piece of storage for StaticTest.i. Both objects will share the same i. Consider: Feedback
StaticTest st1 = new StaticTest(); StaticTest st2 = new StaticTest();
At this point, both st1.i and st2.i have the same value of 47 since they refer to the same piece of memory. Feedback
There are two ways to refer to a static variable. As the preceeding example indicates, you can name it via an object, by saying, for example, st2.i. You can also refer to it directly through its class name, something you cannot do with a non-static member. (This is the preferred way to refer to a static variable since it emphasizes that variables static nature.) Feedback
StaticTest.i++;
The ++ operator increments the variable. At this point, both st1.i and st2.i will have the value 48. Feedback
Similar logic applies to static methods. You can refer to a static method either through an object as you can with any method, or with the special additional syntax ClassName.method( ). You define a static method in a similar way: Feedback
class StaticFun { static void incr() { StaticTest.i++; } }
You can see that the StaticFun method incr( ) increments the static data i using the ++ operator. You can call incr( ) in the typical way, through an object: Feedback
StaticFun sf = new StaticFun(); sf.incr();
Or, because incr( ) is a static method, you can call it directly through its class: Feedback
StaticFun.incr();
Although static, when applied to a field, definitely changes the way the data is created (one for each class versus the non-static one for each object), when applied to a method its not so dramatic. An important use of static for methods is to allow you to call that method without creating an object. This is essential, as we will see, in defining the main( ) method that is the entry point for running an application. Feedback
Like any method, a static method can create or use named objects of its type, so a static method is often used as a shepherd for a flock of instances of its own type. Feedback
Finally, heres the first complete program. It starts by printing a string, and then the date, using the Date class from the Java standard library. Feedback
// HelloDate.java import java.util.*; public class HelloDate { public static void main(String[] args) { System.out.println("Hello, it's: "); System.out.println(new Date()); } }
At the beginning of each program file, you must place the import statement to bring in any extra classes youll need for the code in that file. Note that I say extra. Thats because theres a certain library of classes that are automatically brought into every Java file: java.lang. Start up your Web browser and look at the documentation from Sun. (If you havent downloaded the JDK documentation from java.sun.com, do so now[13]). If you look at the list of the packages, youll see all the different class libraries that come with Java. Select java.lang. This will bring up a list of all the classes that are part of that library. Since java.lang is implicitly included in every Java code file, these classes are automatically available. Theres no Date class listed in java.lang, which means you must import another library to use that. If you dont know the library where a particular class is, or if you want to see all of the classes, you can select Tree in the Java documentation. Now you can find every single class that comes with Java. Then you can use the browsers find function to find Date. When you do youll see it listed as java.util.Date, which lets you know that its in the util library and that you must import java.util.* in order to use Date. Feedback
If you go back to the beginning, select java.lang and then System, youll see that the System class has several fields, and if you select out, youll discover that its a static PrintStream object. Since its static, you dont need to create anything. The out object is always there, and you can just use it. What you can do with this out object is determined by the type it is: a PrintStream. Conveniently, PrintStream is shown in the description as a hyperlink, so if you click on that, youll see a list of all the methods you can call for PrintStream. There are quite a few, and these will be covered later in this book. For now all were interested in is println( ), which in effect means print what Im giving you out to the console and end with a newline. Thus, in any Java program you write you can say System.out.println("things"); whenever you want to print something to the console. Feedback
The name of the class is the same as the name of the file. When youre creating a standalone program such as this one, one of the classes in the file must have the same name as the file. (The compiler complains if you dont do this.) That class must contain a method called main( ) with this signature: Feedback
public static void main(String[] args) {
The public keyword means that the method is available to the outside world (described in detail in Chapter 5). The argument to main( ) is an array of String objects. The args wont be used in this program, but the Java compiler insists that they be there because they hold the arguments from the command line. Feedback
The line that prints the date is quite interesting: Feedback
System.out.println(new Date());
The argument is a Date object that is being created just to send its value (which is automatically converted to a String) to println( ). As soon as this statement is finished, that Date is unnecessary, and the garbage collector can come along and get it anytime. We dont need to worry about cleaning it up. Feedback
To compile and run this program, and all the other programs in this book, you must first have a Java programming environment. There are a number of third-party development environments, but in this book we will assume that you are using the Java Developers Kit (JDK) from Sun, which is free. If you are using another development system,[14] you will need to look in the documentation for that system to determine how to compile and run programs. Feedback
Get on the Internet and go to java.sun.com. There you will find information and links that will lead you through the process of downloading and installing the JDK for your particular platform. Feedback
Once the JDK is installed, and youve set up your computers path information so that it will find javac and java, download and unpack the source code for this book (you can find it at www.BruceEckel.com). This will create a subdirectory for each chapter in this book. Move to subdirectory c02 and type: Feedback
javac HelloDate.java
This command should produce no response. If you get any kind of an error message, it means you havent installed the JDK properly and you need to investigate those problems. Feedback
On the other hand, if you just get your command prompt back, you can type:
java HelloDate
and youll get the message and the date as output. Feedback
This is the process you can use to compile and run each of the programs in this book. However, you will see that the source code for this book also has a file called build.xml in each chapter, and this contains ant commands for automatically building the files for that chapter. Buildfiles and Ant (including where to download it) are described more fully in Chapter 15, but once you have Ant installed (from http://jakarta.apache.org/ant) you can just type ant at the command prompt to compile and run the programs in each chapter. If you havent installed Ant yet, you can just type the javac and java commands by hand. Feedback
There are two types of comments in Java. The first is the traditional C-style comment that was inherited by C++. These comments begin with a /* and continue, possibly across many lines, until a */. Note that many programmers will begin each line of a continued comment with a *, so youll often see:
/* This is a comment * that continues * across lines */
Remember, however, that everything inside the /* and */ is ignored, so theres no difference in saying: Feedback
/* This is a comment that continues across lines */
The second form of comment comes from C++. It is the single-line comment, which starts at a // and continues until the end of the line. This type of comment is convenient and commonly used because its easy. You dont need to hunt on the keyboard to find / and then * (instead, you just press the same key twice), and you dont need to close the comment. So you will often see: Feedback
// This is a one-line comment
One of the better ideas in Java is that writing code isnt the only important activitydocumenting it is at least as important. Possibly the biggest problem with documenting code has been maintaining that documentation. If the documentation and the code are separate, it becomes a hassle to change the documentation every time you change the code. The solution seems simple: link the code to the documentation. The easiest way to do this is to put everything in the same file. To complete the picture, however, you need a special comment syntax to mark the documentation and a tool to extract those comments and put them in a useful form. This is what Java has done. Feedback
The tool to extract the comments is called javadoc, and it is part of the JDK installation. It uses some of the technology from the Java compiler to look for special comment tags that you put in your programs. It not only extracts the information marked by these tags, but it also pulls out the class name or method name that adjoins the comment. This way you can get away with the minimal amount of work to generate decent program documentation. Feedback
The output of javadoc is an HTML file that you can view with your Web browser. Thus, javadoc allows you to create and maintain a single source file and automatically generate useful documentation. Because of javadoc we have a standard for creating documentation, and its easy enough that we can expect or even demand documentation with all Java libraries. Feedback
In addition, you can write your own javadoc handlers, called doclets, if you want to perform special operations on the information processed by javadoc (output in a different format, for example). Doclets are introduced in Chapter 15. Feedback
What follows is only an introduction and overview of the basics of javadoc. A thorough description can be found in the JDK documentation downloadable from java.sun.com (note that this documentation doesnt come packed with the JDK; you have to do a separate download to get it). When you unpack the documentation, look in the tooldocs subdirectory (or follow the tooldocs link). Feedback
All of the javadoc commands occur only within /** comments. The comments end with */ as usual. There are two primary ways to use javadoc: embed HTML or use doc tags. Standalone doc tags are commands that start with a @ and are placed at the beginning of a comment line. (A leading *, however, is ignored.) Inline doc tags can appear anywhere within a javadoc comment and also start with a @ but are surrounded by curly braces. Feedback
There are three types of comment documentation, which correspond to the element the comment precedes: class, variable, or method. That is, a class comment appears right before the definition of a class; a variable comment appears right in front of the definition of a variable, and a method comment appears right in front of the definition of a method. As a simple example: Feedback
/** A class comment */ public class DocTest { /** A variable comment */ public int i; /** A method comment */ public void f() {} }
Note that javadoc will process comment documentation for only public and protected members. Comments for private and package-access members (see Chapter 5) are ignored, and youll see no output. (However, you can use the -private flag to include private members as well.) This makes sense, since only public and protected members are available outside the file, which is the client programmers perspective. However, all class comments are included in the output. Feedback
The output for the preceding code is an HTML file that has the same standard format as all the rest of the Java documentation, so users will be comfortable with the format and can easily navigate your classes. Its worth entering the preceding code, sending it through javadoc, and viewing the resulting HTML file to see the results. Feedback
Javadoc passes HTML commands through to the generated HTML document. This allows you full use of HTML; however, the primary motive is to let you format code, such as: Feedback
/** * <pre> * System.out.println(new Date()); * </pre> */
You can also use HTML just as you would in any other Web document to format the regular text in your descriptions: Feedback
/** * You can <em>even</em> insert a list: * <ol> * <li> Item one * <li> Item two * <li> Item three * </ol> */
Note that within the documentation comment, asterisks at the beginning of a line are thrown away by javadoc, along with leading spaces. Javadoc reformats everything so that it conforms to the standard documentation appearance. Dont use headings such as <h1> or <hr> as embedded HTML, because javadoc inserts its own headings and yours will interfere with them. Feedback
All types of comment documentationclass, variable, and methodcan support embedded HTML. Feedback
Here are some of the javadoc tags available for code documentation. Before trying to do anything serious using javadoc, you should consult the javadoc reference in the downloadable JDK documentation to get full coverage of the way to use javadoc. Feedback
The @see tag allows you to refer to the documentation in other classes. Javadoc will generate HTML with the @see tags hyperlinked to the other documentation. The forms are: Feedback
@see classname @see fully-qualified-classname @see fully-qualified-classname#method-name
Each one adds a hyperlinked See Also entry to the generated documentation. Javadoc will not check the hyperlinks you give it to make sure they are valid. Feedback
Very similar to @see, except that it can be used inline and uses the label as the hyperlink text rather than See Also.
Produces the relative path to the documentation root directory. Useful for explicit hyperlinking to pages in the documentation tree.
Inherits the documentation from the nearest base class of this class into the current doc comment.
@version version-information
in which version-information is any significant information you see fit to include. When the -version flag is placed on the javadoc command line, the version information will be called out specially in the generated HTML documentation. Feedback
@author author-information
in which author-information is, presumably, your name, but it could also include your email address or any other appropriate information. When the -author flag is placed on the javadoc command line, the author information will be called out specially in the generated HTML documentation. Feedback
You can have multiple author tags for a list of authors, but they must be placed consecutively. All the author information will be lumped together into a single paragraph in the generated HTML. Feedback
This tag allows you to indicate the version of this code that began using a particular feature. Youll see it appearing in the HTML Java documentation to indicate what version of the JDK is used. Feedback
This is used for method documentation, and is of the form:
@param parameter-name description
in which parameter-name is the identifier in the method parameter list, and description is text that can continue on subsequent lines. The description is considered finished when a new documentation tag is encountered. You can have any number of these, presumably one for each parameter. Feedback
This is used for method documentation, and looks like this:
@return description
in which description gives you the meaning of the return value. It can continue on subsequent lines. Feedback
Exceptions will be demonstrated in Chapter 9. Briefly, they are objects that can be thrown out of a method if that method fails. Although only one exception object can emerge when you call a method, a particular method might produce any number of different types of exceptions, all of which need descriptions. So the form for the exception tag is:
@throws fully-qualified-class-name description
in which fully-qualified-class-name gives an unambiguous name of an exception class thats defined somewhere, and description (which can continue on subsequent lines) tells you why this particular type of exception can emerge from the method call. Feedback
This is used to indicate features that were superseded by an improved feature. The deprecated tag is a suggestion that you no longer use this particular feature, since sometime in the future it is likely to be removed. A method that is marked @deprecated causes the compiler to issue a warning if it is used. Feedback
Here is the first Java program again, this time with documentation comments added:
//: c02:HelloDate.java import java.util.*; /** The first Thinking in Java example program. * Displays a string and today's date. * @author Bruce Eckel * @author www.BruceEckel.com * @version 2.0 */ public class HelloDate { /** Sole entry point to class & application * @param args array of string arguments * @return No return value * @exception exceptions No exceptions thrown */ public static void main(String[] args) { System.out.println("Hello, it's: "); System.out.println(new Date()); } } ///:~
The first line of the file uses my own technique of putting a //: as a special marker for the comment line containing the source file name. That line contains the path information to the file (in this case, c02 indicates Chapter 2) followed by the file name.[15] The last line also finishes with a comment, and this one (///:~) indicates the end of the source code listing, which allows it to be automatically updated into the text of this book after being checked with a compiler and executed. Feedback
The style described in the Code Conventions for the Java Programming Language[16] is to capitalize the first letter of a class name. If the class name consists of several words, they are run together (that is, you dont use underscores to separate the names), and the first letter of each embedded word is capitalized, such as: Feedback
class AllTheColorsOfTheRainbow { // ...
This is sometimes called camel-casing. For almost everything else: methods, fields (member variables), and object reference names, the accepted style is just as it is for classes except that the first letter of the identifier is lowercase. For example: Feedback
class AllTheColorsOfTheRainbow { int anIntegerRepresentingColors; void changeTheHueOfTheColor(int newHue) { // ... } // ... }
The user must also type all these long names, so be merciful. Feedback
The Java code you will see in the Sun libraries also follows the placement of open-and-close curly braces that you see used in this book. Feedback
The goal of this chapter is just enough Java to understand how to write a simple program. Youve also gotten an overview of the language and some of its basic ideas. However, the examples so far have all been of the form do this, then do that, then do something else. What if you want the program to make choices, such as if the result of doing this is red, do that; if not, then do something else? The support in Java for this fundamental programming activity will be covered in the next chapter. Feedback
Solutions to selected exercises can be found in the electronic document The Thinking in Java Annotated Solution Guide, available for a small fee from www.BruceEckel.com.
[10] This can be a flashpoint. There are those who say clearly, its a pointer, but this presumes an underlying implementation. Also, Java references are much more akin to C++ references than pointers in their syntax. In the first edition of this book, I chose to invent a new term, handle, because C++ references and Java references have some important differences. I was coming out of C++ and did not want to confuse the C++ programmers whom I assumed would be the largest audience for Java. In the 2nd edition, I decided that reference was the more commonly used term, and that anyone changing from C++ would have a lot more to cope with than the terminology of references, so they might as well jump in with both feet. However, there are people who disagree even with the term reference. I read in one book where it was completely wrong to say that Java supports pass by reference, because Java object identifiers (according to that author) are actually object references. And (he goes on) everything is actually pass by value. So youre not passing by reference, youre passing an object reference by value. One could argue for the precision of such convoluted explanations, but I think my approach simplifies the understanding of the concept without hurting anything (well, the language lawyers may claim that Im lying to you, but Ill say that Im providing an appropriate abstraction.)
[11] static methods, which youll learn about soon, can be called for the class, without an object.
[12] With the usual exception of the aforementioned special data types boolean, char, byte, short, int, long, float, and double. In general, though, you pass objects, which really means you pass references to objects.
[13] The Java compiler and documentation from Sun was not included on this books CD because it tends to change regularly. By downloading it yourself, you will get the most recent version.
[14] IBMs jikes compiler is a common alternative, as it is significantly faster than Suns javac.
[15] Originally, I created a tool using Python (see www.Python.org), which uses this information to extract the code files, put them in appropriate subdirectories, and create makefiles. In this edition, all the files are stored in Concurrent Versions System (CVS) and automatically incorporated into this book using a Visual BASIC for Applications (VBA) macro. This new approach seems to work much better in terms of code maintenance, mostly because of CVS.
[16] http://java.sun.com/docs/codeconv/index.html. To preserve space in this book and seminar presentations, not all of these guidelines could be followed.