Lesson 6.5 Console Apps
Because this course is being conducted over the Internet, we've spent most of our time looking at Internet-delivered Java programs--applets.
There is another side to Java, however. A Java program can be written to run on your local machine as an application, just like programs written in C, Basic, or Pascal.
In this short side trip, you'll:
- learn the differences between applets and applications.
- learn how to compile and run a Java application.
- learn about the "glass-teletype" object: System.out.
- learn how to write simple console-mode applications.
Why Console I/O?
When learning a new feature in a new programming language, what you really, really want is the simplest possible example. Most language features have numerous subtleties and idioms associated with using the feature. Such complications are best delayed until the basic elements of a feature are clear.
Learning how to program loops is one of those core concepts that is best learned in a stripped-down, bare-bones environment. Java has such an environment, which, while not modern or flashy, provides a quick way to test the execution of a loop or the correctness of a complicated calculation.
Traditional I/O
Getting information into and out of your program is called I/O. Information can come into your program from different places; these are called data sources or just sources. For instance, your program could open a file and read some data from the file, or it could open a network connection and read its information from the network connection.
Information can also flow out of your program. When you send information out of your program, it eventually ends up at its destination, which is called a sink. As with a data source, a sink may be a local file, a printer, or a network connection. While you read data from a source, you write data to a sink.
When data travels from a data source into your program, and out to a data sink, it uses a general mechanism called a stream. This entire view of I/O is generically called stream I/O; you'll take an in-depth look at Java's stream classes in Lesson 12.
The Glass Teletype
In traditional programs, this same, stream-oriented view of I/O is used to program the console. The console is the name given to the keyboard and monitor that you are sitting at right now. In early computer systems, the computer [CPU] and the device used to communicate with the CPU were distinct.
One early console device that was used was the Teletype. The Teletype had a keyboard for talking to the CPU, but, instead of a video display screen like we use now, it contained a built-in line printer for displaying the output returned from the CPU.
This built-in printer was not page-oriented, like our modern laser printers, but printed its output on an endless roll of fan-fold computer paper. In a sense, the computer returned to the days before the invention of the codex. Computers wrote their output on scrolls little different than those used in ancient times. Perhaps this, subconsciously, contributed to the reverence afforded early computer output.
When CRT VDTs [Cathode-Ray-Tube Video-Display-Terminals] replaced the Teletype, the scrolling model of output remained. We still communicated with the computer a line at a time and the CPU replied in like manner. If anything, however, the replies from the computer became even more ephemeral.
In the past, you could always retrieve the CPU utterances of moments or hours or days ago, because they were recorded, permanently, on the green-bar scroll used for output. When the VDT replaced the teletype, the endless scroll was replaced by a window, 22 lines high. When the 23rd line was received from the CPU, the first line was simply discarded.
The Glass Teletype Objects
Today, the GUI [Graphical User Interface] has almost completely supplanted traditional stream I/O for communicating with the user. Instead of reading and writing lines of text on the console, most Java programs use Labels, Buttons, TextFields and TextAreas. That's as it should be.
The traditional console hasn't entirely disappeared from Java, however. It's just taken on a somewhat object-orient flavor. Instead of having built-in, line-oriented console I/O like Pascal or Basic, Java has three predefined objects that manage traditional console I/O:
- System.out: the standard console output object
- System.err: the standard console error object
- System.in: the standard console input object
|
What about the Mac?
|
| One of the problems with console I/O is that your operating system must have a console [command-line] to support it. The Mac O/S, [prior to MacOSX], has no concept of a console; it is pure GUI.
To use console mode programs on a Mac, you must use the JBindery tool. JBindery, which is part of the MRJ SDK, allows you to create double-clickable Mac applications which work with System.out and System.in.
[File redirection, however, is still a problem on the Mac. We'll cover that in Lesson 14] |
Using System.out
The two standard ouput objects--System.out and System.err--support two methods for sending output to the console: print() and println(). These two methods work a little like the built-in Write and Writeln procedures in Pascal.
To use either print() or println(), you pass the method as a single argument of any type. The argument you pass is converted to a String and displayed on the console. You can use print() and println() in both applications and in applets.
Here's an example:
int age = 50;
System.out.print("I am ");
System.out.print(age);
System.out.println(" years old."); |
System.out converts its single argument to a String [if it is not a String already], and then displays it on the console. Its println() method adds an additional newline character to the end of the String it displays; the print() method does not.
When combined, print() and println() can produce a single line of output that contains values of different types. You can usually do the same thing, with less code, however, by using String concatenation to build a single String first. Thus you could replace the four lines above with this:
int age = 50;
System.out.println("I am " + age +
" years old."); |
Where's the Output?
Beginning programmers are often surprised when using System.out in an applet. When used in an applet, [or in a GUI application, for that matter], System.out does not display its output on the surface of your applet. Instead the output is displayed on the console that was used to start the applet in the first place.
If you are running your applet in appletviewer, this will be the DOS [or shell] window where you launched appletviewer. If your applet is being viewed in your Web browser, the output will be displayed in your browser's Java Console window. [Look at Lesson 4.1, "Writing Simple Methods", for detailed instructions about how to access the Java console on your browser.]
Java Applications
Java applications are organized a little different than Java applets. Here's a simple, console-mode application that uses System.out to display the three lines shown.
|
ConsoleApp.java
|
public class ConsoleApp
{
public static void main(String[] args)
{
System.out.print("I am ");
System.out.print(50);
System.out.println(" years old.");
}
} |
Compiling and Running
Compiling ConsoleApp.java is no different than compiling an applet. You use the javac compiler and it produces a .class file named ConsoleApp.class. Running the program, however, is a little bit different.
Instead of creating an HTML file, adding an APPLET tag, and then loading the HTML file using appletviewer or your Web browser, a Java application is run directly from the command line, using the Java interpreter program, named java.
[Note: this is just the same as javac, but there is no c at the end of it. As mentioned earlier, Mac folk will run their Java applications through JBindery, which will launch the Java interpreter for you.]
The argument to java is the name of your class file, but without the .class extension. This can get confusing, but the rules are pretty simple:
- Compile? Extension required:
- Run? No extension required:
Application Structure
Looking at ConsoleApp.java, there are several obvious differences from the applets we've been using so far:
- No java.awt or java.applet import statements. This is not a GUI app, so we don't need the AWT toolkit, and it's obviously not an applet.
- No extends Applet statement. This is not an applet.
- No init() method. The init() method is part of the Applet life-cycle. Of course you can add an init() method to your application; it just won't be called automatically like it is in an applet.
The main() Method
All of these differences, however, are minor. The main difference between an applet and an application is the presence of a main() method. All applications have a main() method.
The main() method has the following, somewhat complex, signature, which must be followed exactly:
public static void main(String[] args)
{
// Statements appear here
} |
Notice that the method is:
- public: It is called by the Java interpreter
- static: It does not require an object to call the method
- void: It does not return any value
Because the main() method is static, you cannot reference any object attributes inside the method. To reference object attributes, you must create an instance [object] of the class that contains the method.
|
Objects and the main() Method
|
| The implications of a static main() method can quickly become very complex and confusing, even for very experienced programmers familiar with other OO languages such as C++.
The main() method in a class does not have to create an instance of the class where the main() method is located. It can create instances of other classes, or create several instances of its own class.
Every class in a Java application can have its ownmain() method, but the only one main() method can be active when a program is running. Which main() method will be active, if every class in your application has its own main() method? The only main() method that will be active is the main() method in the class that was launched with the Java interpreter.
By this point, you probably feel that there is enough confusion in the world and that you don't need any more. I agree, and so I'll refrain from elaborating any further on the weird and wacky world of Java main() methods. |
The single argument to main(), args, is an array [linear collection] of Strings which allows you to pass arguments to a Java application in much the same way that the getParameter() method allows you to pass arguments to a Java applet. We'll cover String arrays in Lesson 9, "Arrays". You don't have to use the name args-you can choose your own name--but everything else must be written exactly as shown.
Here's a simple chart which should help keep the differences between Java applets and applications straight in your mind. You can click on the image to enlarge it.
Something to Talk About
This is deceptively difficult to get right. How would you write a simple console mode program that prints the even numbers from 1 to 100 on the display, printing 8 numbers on each line like this:
2 4 6 8 10 12 14 16
18 20 22 24 26 28 30 32
...
Don't worry about trying to line up the numbers in columns. You can use a counter to keep track of how many numbers are on each line.
Please continue to the next section of this lesson.
|