Java-- GOOD, BAD, and NOT C++

Joseph Bergin
Pace University

Some good things about Java

You don't need to declare something before you use it, so your files can read more naturally. The compiler will find it. Even if it is in a different file that the compiler sees.

Java has a garbage collector so there are no destructors. Memory management is handled by the system, not by each program.

Java catches all array subscript errors and similar. Java never has uninitialized data of any kind. Order of evaluation, etc. is completely defined and natural.

Java arrays know their own length. (a public read-only field named length.)

Java never has dangling references. You still can't derefernce null, however. If you try it will be caught. This is probably the most common run time error.

Java int, float,... are completely defined, so behave the same on all systems supporting Java. Int is 32 bits with modular arithmetic.

In fact the only thing in Java not specified is the effect of the interleaving of threads in a multithreaded program.

All casts are checked, either at compile time or at runtime. A narrowing cast is never applied automatically. You must specify it.

	int x;
	long lo = x; // ok
	x = lo; // error
	x = (int) lo; // ok

Java interfaces define first class types. This gives most of the strength of both C++ templates and multiple inheritance. Interfaces are very important in Java.

Java has threads, so concurrent programs are possible with standard tools. They are simple enough to use so that you can teach simple concurrency in CS1.

Java has a library with lots of common data structures. Therefore, you can use them before you examine implementations in CS 241.

Some bad things about Java (Actually these things are good, but are placed here since they complicate novice learning.)

I/O takes explanation and getting used to. Java standard output is easy. Java standard input is harder. Other input/output is hard. (But its object model is very good.) See Java I/O Explained and Elementary Patterns: Strategy, Decorator, and Composite

Java exceptions must be caught and i/o statements throw exceptions.

Some things about Java that are different from C++

Java classes do not separate the function headers from the bodies. A Java class is written all in one file. Interfaces can be used to achieve separation when necessary.

Class variable members can be initialized when declared, even with function calls. You don't need to do this in the constructor, though you may.

import is like #include, but stronger. It doesn't reread and reparse the text.

Java has no typedefs. They aren't needed as the typing system is simpler.

boolean (small b) is a real type, not confused with int. if(…) must take a boolean. This helps prevent lots of errors--especially those that confuse == with =.

All Java objects are heap based. You must call new to get an object.

Java arrays are always heap based and the [] comes in a different place.

	int [] days = new int(12); // Java
	int days [12]; // C++ but NOT Java

An array of objects of a certain kind has cells initialized to null, not to default objects of the class.

	Foo [] foos = new Foo [10];
	foos[0].bar(); // null pointer exception.
	for(int i = 0; i < 10; ++i) // do this first
	foos[i] = new Foo(...);

Java has no goto, but it has multi level breaks instead. A multilevel break can leave any structured statement, not just loops and switch.

Java has no const keyword, but

	public static final int = 12;

Java has no enum, use class

Java has no struct, use class

Java static inner classes are like c++ nested classes, but non-static inner classes have a more sophisticated semantics. The object of the inner class is associated with a specific outer class objects and has an implicit reference to it. The outer object and the inner object are "friendly" and can reference each others members.

Java has no "free" functions. Every function (and variable) is part of some class.

The main function can appear in any/every class. It has prototype

	public static void main(String [] args)

The args array of strings does not include the name of the program as its first (index zero) arg.

Java String objects are immutable. But you can easily generate new Strings from old. The catenation operator for strings is "+".

All Java objects know how to represent themselves as strings, since they implement toString(). Therefore you can write out a string representation of any object. You may need to override this method to have anything meaningful printed, of course.

Assignment of class type variables is reference assignment, not copying.

When you pass an object as a parameter, it is the reference variable that is "by value". The function can modify the object to which the parameter refers by sending it messages in the usual way. The object itself is NOT copied.

Java has ONLY pass by value and no functions can be passed. Instead pass an object that implements a known interface. This has the same power and stronger semantics since the object passed can carry static state information that a function cannot. (This will be explored in the short course.)

Java doesn't depend on copy constructors. Instead there is a clone method inherited from Object to do something similar.

Java has no default parameter values, but you can override functions to provide the same effect.

Java has no operator overloading yet. (I think this will come, but is not yet officially promised.)

Java does not yet have generics (templates). These ARE promised, but will be different and stronger than C++ templates. For now, interfaces provide most of the same functionality, but not the same efficiency.

Java has a reputation for being slower than C++. This is not inherent in the language, in fact. Java has more opportunities for optimization than C++ since it has stronger semantics that can be exploited by an optimizer. Java may someday be the standard by which we measure other languages (as Fortran --not C-- is now). Java can even now achieve excellent performance on compute bound programs, such as numerical analysis. On many programs, the garbage collector increases rather than decreases efficiency.


You can also consult: ,

which has an example written in both C++ and Java.

Last Updated: September 22, 2000