- Explanation of the Example Program
- Where an Application Starts
- Runtime Internals: Stack and Heap
- The Class "Object"
- Some Light Relief
Looking at the signature1 of main(), which is the method in which every application starts execution, we see the following:
public static void
main(String args[]) {
The keywords say that the function is:
-
public, namely visible everywhere.
-
static, namely a class method that can be called using the classname without needing an object of the class. Static methods are often used where you would use a global function in C or C++. That is, you are not doing something to some specific object, you are just doing something that generally needs doing.
-
void, namely the method does not return a value.
That last point is a difference between Java and C/C++. In C, main() is defined to return an int. In Java, main() is defined to return a void, that is "no value." Java has a better way to indicate program failure, namely throwing an exception.
A Common Pitfall
A very common and frustrating pitfall is trying to access an object member from the static method called main(), as we mentioned in chapter 2, "The Story of O: Object-Oriented Programming." There are two ways to get past this. The simplest way is to make a referenced field static, too. If the field has to be non-static because each object needs its own copy, then instantiate an object whose purpose is to be an instance variable allowing you to reference the member or invoke a call on it.
class myframe { ... public static void main(String args[]) { // we want to invoke the instance method setSize() myframe mf = new myframe(); // so declare an instance mf.setSize(200,200); // then use it for the call
It looks weirdly recursive the first time you see it. Think of it this way: The class definition is a datatype. All you are doing is instantiating an object of that type at a point when you need one, which happens to be inside the original datatype definition.
The main() routine where execution starts is a static method. That means it can be invoked before any individual instance objects have been created.
Passing over the modifiers, the actual function is as follows:
void main(String args[]) {
It declares a function called "main" that has no return value, and takes just one argument here called "args" (the parameter name doesn't matter, just its data type) which is an array of Strings. The empty array bracket pair are a reminder that the function is not restricted to any one size of array. The Strings are the command-line arguments with which the program was invoked. "String" is a class in Java, with more to it than just the nul-terminated character array it is in C.
You don't need a separate count of the number of arguments, because all arrays have a length field holding the size of the array. Simply use args.length, which gets the number of Strings in the args array.
The zeroth argument in the args array is the first command-line argument, not the program name as in C and C++. The program name is already known inside the program: It is the name of the class that contains the "main()" function. The name of this class will match the name of the file it is in. This framework is all that is needed to indicate the entry point program where execution will start.
We're working from the middle out here. Having seen our first reasonable Java program, in the next chapter we'll look at the small building blocks of individual tokens that the compiler sees.
For the rest of this chapter we'll mention the stack and the heapwhich are a couple of popular runtime data structures, common to many programming languages, and we'll finish up with some light relief.