2. Java as a Teaching Language

A good place to start is with the The Java Language: An Overview [14] (previously titled The Java Language: A White Paper), a well-known document from Sun Microsystems that lists eleven properties of Java. Although this document describes the significance of these properties from the standpoint of commercial programming, it might as well have been addressing the academic world, where they are just as important, if not more so. Let's review the properties, considering the relevance of each one to the introductory programming course.

2.1 Simple

Although Java resembles C++, it omits many of C++'s more confusing features, including the ones most likely to cause problems for beginners: pointers, operator overloading, multiple inheritance, and templates. Moreover, Java lacks many of the automatic type conversions that C++ performs.

At the same time, Java adds an important feature that simplifies programming: automatic garbage collection. Having the language handle storage management gives Java a big edge in introductory classes over languages such as C and C++, where releasing memory that's no longer needed requires programmer intervention. Garbage collection not only makes programming easier but also avoids the bugs caused by dangling pointers. In C++ programming, too much effort is spent on problems of memory allocation and deallocation. As Bergin [1] notes, ``some reports from industry are that on large [C++] projects, half of the programming effort is spent in getting memory management right.''

Overall, Java is a small language, closer in size to Pascal or C than Ada or C++. Java's relatively small size is a powerful argument in its favor as a teaching language. As one author puts it, ``Possibly the most attractive feature [of Java] is the relative smallness of the language.'' [5]

2.2 Object-Oriented

The importance of introducing the object-oriented paradigm early in a student's program of study is increasingly being recognized. However, there's widespread disagreement over which object-oriented language to use. C++ is the most popular object-oriented language used to teach introductory programming, but it has plenty of critics. Some even argue that no existing object-oriented language (prior to Java, at least) is really suitable for beginners [6]. (This paper describes desirable characteristics for a beginner's object-oriented language. Although the paper predates the release of Java, the authors might just as well have been describing Java.)

Java also supports object-oriented programming, but with significant advantages over C++:

In its support for object-oriented programming, Java is closer to Smalltalk than C++. Smalltalk is even more object-oriented than Java, and it makes a good introductory language as well [17]. However, Smalltalk has a syntax that's difficult for beginners to grasp, among other drawbacks [6].

2.3 Distributed

With the growing importance of networking in general and the Internet in particular, students need experience in writing software that's network-aware. Java is unique among major languages in its support for networking, which includes classes for working with URLs and sockets.

Although most of Java's networking capabilities wouldn't be used in an introductory course, some of the simpler ones could make excellent examples. For example, Java makes it easy for programs to access specific URLs on the Web, allowing students to gain a better understanding of how the Web works as well as being able to write some rather interesting programs. Ambitious instructors could use the more advanced networking features to illustrate how programs cooperate over a network.

If Java is used in the second programming course as well as the first one, its networking support would be more likely to come into play. At one college, students use Java in the first two programming courses. When asked what was the most surprising thing about using Java, the instructor replied, ``For me, the way in which CS2 students so readily adapt to the notion of building reactive, distributed programs on the internet, and how this, as much or more so than the object-oriented aspects of Java programming, so fundamentally governs their attitudes on what programming is all about.'' [8]

2.4 Robust

A number of Java's properties are the result of making the language safe for transmitting executable content over the Internet. These properties, as it turns out, are often the same properties instructors look for in an introductory language. As [14] puts it, ``Java puts a lot of emphasis on early checking for possible problems, later dynamic (runtime) checking, and eliminating situations that are error prone.'' This should be music to the ears of Pascal and Ada instructors who have resisted switching to C or C++ because of their relatively weak abilities to detect errors.

Here are some of the measures that Java uses to achieve robustness:

2.5 Secure

In addition to being robust (resistant to programmer error), Java programs are designed to be secure (safe against malicious attack). Java's run-time system performs checks to make sure that programs transmitted over a network have not been tampered with. The code produced by the Java compiler is checked for validity, and the program is prevented from performing unauthorized actions. For example, an applet that's been downloaded from a Web page can't access files on the local computer. Moreover, the nature of Java makes it hard to write viruses and other kinds of malicious programs. A program that can't access memory locations via pointers will find it hard to do much damage. Instructors who have been stung by viruses in student programs will appreciate the security provided by Java.

2.6 Architecture-Neutral

The Java language is completely architecture-neutral. As a result, programs written in Java will run on any platform that supports the Java run-time system.

The significance of a multiplatform language like Java cannot be overstated. Sun's Java Development Kit is available for a variety of platforms, including Windows 95 and NT, Macintosh, and Sun Solaris, all of which are widely used in education. Colleges can offer Java without having to worry about whether their labs contain enough computers of the same type. Students can easily transport programs from campus to home and vice-versa, even though their home computers may be different from the ones on campus.

2.7 Portable

Java programs are not only architecture-neutral but portable as well. One way in which Java achieves portability is by completely defining all aspects of the language, leaving no decisions to the compiler writer. Consider the issue of types. Most programming languages don't define the exact ranges of types, allowing for variations based on the computer's architecture. Java, on the other hand, completely defines the ranges and properties of all types. Values of the int type are always signed 32-bit integers; float values are stored in 32 bits using the IEEE 754 representation. That's a plus for instructors, who don't have to worry about trying to explain to beginners why a program may not work if compiled with a different compiler.

Other aspects of Java are portable as well. Java's libraries are designed for complete portability. The Java system itself is portable. Sun's Java compiler is written in Java itself; the run-time system is written in Standard C.

2.8 Interpreted

Java is usually an interpreted language. A Java compiler translates a program into bytecodes, which can then be executed by an interpreter. Linking is done at run time, with code loaded dynamically by the run-time system as needed. For students, this means that building a program is simple: there's no linking step to perform. When one part of a program is changed, only that part needs to be recompiled, and there's no linking step to redo.

From the standpoint of the instructor, the fact that Java is interpreted has two primary implications. One is that Java programs won't run at the same speed as programs written in a compiled language such as Pascal, Ada, C, or C++. For most student programs, however, the speed of execution is irrelevant.

A more important implication of interpretation is that students will be able to get excellent feedback when a program fails during execution. A C or C++ program that fails at run time generally doesn't provide any clue as to the problem; students are forced to crank up the debugger. A Java program that fails can print the call stack and describe the exception that caused the program to fail. That information alone is often enough to pinpoint the cause of the error, without the need to use a debugger. This behavior is possible thanks to information about the source program that's embedded into the bytecodes during compilation.

2.9 High-Performance

Programs written in interpreted, garbage-collected languages often don't execute at high speed. In Java, however, the performance penalty isn't as bad as in some languages. One reason for Java's superior performance is that garbage collection is done by a separate low-priority thread. That way, garbage collection takes place primarily when the program has nothing else useful to do--while it's waiting for user input, say.

Greater speed can be achieved by translating Java's bytecodes into native machine instructions. This can be done by translating the entire program to native code prior to execution, or it can be done on the fly by a ``just-in-time'' (JIT) compiler. JIT compilation is becoming a standard feature of commercial Java environments; both Borland C++ 5.0 (which supports Java) and Microsoft J++ 1.0 provide JIT compilers. When translated into native code, Java's performance ``is almost indistinguishable from native C or C++'' [14]. Java's support for translation to machine code is one of the features that gives it an edge over Smalltalk, another interpreted, garbage-collected language.

2.10 Multithreaded

Unlike most major programming languages (with the notable exception of Ada), Java has built-in support for multitasking. A Java program may create any number of threads, which appear to execute in parallel.

For instructors, Java's support for threads provides a golden opportunity to introduce students to the concept of concurrency, a topic that's already important and will only become more so in the future, with multiprocessor PCs soon to be commonplace. It is imperative that students become comfortable with concurrency early in their studies. Java's model of concurrency is simple enough that even beginners can use concurrency effectively.

Instructors teaching concurrency often use Ada, one of the few mainstream languages to provide built-in support for concurrency. However, Ada provides no support for GUI interfaces, without which writing simple concurrent programs is difficult. Ideally, a concurrent program should support multiple input sources and multiple output destinations, to avoid problems of mutual exclusion. Doing this in Ada is not trivial. Java's support for GUI interfaces makes it a snap to write programs that illustrate concurrency. Entering keyboard input into a concurrent program is tricky, because only one task can read from the keyboard. With separate windows for tasks, however, input is easy. Similarly, writing output to the screen becomes an exercise in mutual exclusion in Ada; a Java program simply writes to different windows.

Knowledge of threading isn't required to write Java programs, so instructors who wish to skip it in a first class may easily do so.

2.11 Dynamic

Java is designed to accommodate the fast-paced, modern world of software development, in which components of a system may change on a regular basis. Java's run-time linking guarantees that a program always loads the most recent version of its library modules. (That's good for students, who often forget to relink and end up running older versions of their programs.) It also reduces recompilation by making it possible to add methods and instance variables to a library without having to recompile its clients.

Next section


Permission to make digital or hard copies of part or all of this work for personal or classroom use is granted without fee provided that copies are not made or distributed for profit or commercial advantage and that copies bear this notice and the full citation on the first page. Copyrights for components of this work owned by others than ACM must be honored. Abstracting with credit is permitted. To copy otherwise, to republish, to post on servers or to redistribute to lists, requires prior specific permission and/or a fee.

© 1997 ACM