All Categories :
Differences Between Java and C/C++
by Michael Morrison
It is no secret that the Java language is highly derived from
the C and C++ languages. Because C++ is currently considered one
of the languages of choice for professional software developers,
it's important to understand what aspects of C++ Java inherits.
Of possibly even more importance is what aspects of C++ Java doesn't
support. Because Java is an entirely new language, it was possible
for the language architects to pick and choose which features
from C++ to implement in Java and how.
The focus of this appendix is to point out the differences between
Java and C++. If you are a C++ programmer, you will be able to
appreciate the differences between Java and C++. Even if you don't
have any C++ experience, you can gain some insight into the Java
language by understanding what C++ discrepancies it clears up
in its implementation. Because C++ backwardly supports C, many
of the differences pointed out in this appendix refer to C++,
but inherently apply to C as well.
All C/C++ compilers implement a stage of compilation known as
the preprocessor. The C++ preprocessor basically performs
an intelligent search-and-replace on identifiers that have been
declared using the #define
directive. Although most advocates of C++ discourage use of the
preprocessor (which was inherited from C), it is still widely
used by most C++ programmers. Most processor definitions in C++
are stored in header files, which complement the actual source
The problem with the preprocessor approach is that it provides
an easy way for programmers to inadvertently add unnecessary complexity
to a program. What happens is that many programmers using the
#define directive end up
inventing their own sublanguage within the confines of a particular
project. This results in other programmers having to go through
the header files and sort out all the #define
information to understand a program, which makes code maintenance
and reuse almost impossible. An additional problem with the preprocessor
approach is that it is weak when it comes to type checking and
Java does not have a preprocessor. It provides similar functionality
to that provided by the C++ preprocessor, but with far more control:
Java uses constant data members in place of the #define
directive. The result is that Java source code is much more consistent
and easier to read than C++ source code. Additionally, Java programs
don't use header files; the Java compiler builds class definitions
directly from the source code files, which contain both class
definitions and method implementations.
Most developers agree that the misuse of pointers causes the majority
of bugs in C/C++ programming. Put simply, when you have pointers,
you have the ability to trash memory. C++ programmers regularly
use (and misuse) complex pointer arithmetic to create and maintain
dynamic data structures. In return, C++ programmers spend a lot
of time hunting down complex bugs caused by their complex pointer
The Java language does not support pointers. Java provides similar
functionality by making heavy use of references. Java passes all
arrays and objects by reference. This approach prevents common
errors caused by pointer mismanagement. The reference approach
also makes programming easier in a lot of ways simply because
the correct usage of pointers is easily mis-understood by all
but the most seasoned programmers.
You may be thinking that the lack of pointers in Java will keep
you from being able to implement many data structures, such as
dynamic arrays. The reality is that any pointer task can be carried
out just as easily-and more reliably-with objects and arrays of
objects. You then benefit from the security provided by the Java
runtime system; it performs boundary checking on all array indexing
There are three types of complex data types in C++: classes, structures,
and unions. Java implements only one of these data types: classes.
Java forces programmers to use classes when the functionality
of structures and unions is desired. Although this sounds like
more work for the programmer, it actually ends up being more consistent
because classes can imitate structures and unions with ease. The
Java designers really wanted to keep the language simple, so it
made sense to eliminate aspects of the language that overlapped.
By forcing programmers to think in terms of classes instead of
structures and unions, Java enforces a complete object-oriented
approach to problem solving. This not only encourages code reuse,
it also simplifies code maintenance in the long run.
In C, code is organized into functions, which are global
subroutines accessible to a program. C++ added classes
and in doing so provided class methods, which are functions
connected to classes. C++ class methods are very similar to Java
class methods. However, because C++ still supports C, there is
nothing to discourage C++ programmers from using functions. This
results in a mixture of function and method use that makes for
Java has no functions. Being a purer object-oriented language
than C++, Java forces programmers to bundle all routines into
class methods. There is no limitation imposed by forcing programmers
to use methods instead of functions. As a matter of fact, implementing
routines as methods encourages programmers to organize code better.
Keep in mind that, strictly speaking, there is nothing wrong with
the procedural approach of using functions, it just doesn't mix
well with the object-oriented paradigm that defines the core of
Java. However, the Java approach does tend to promote code reuse,
which is a distinct advantage over the procedural approach.
Multiple inheritance is a feature of C++ that allows you to derive
a class from multiple parent classes. Although multiple inheritance
is indeed powerful, it is complicated to use correctly and causes
lots of problems otherwise. It is also very complicated to implement
from the compiler perspective.
Java takes the high road and provides no direct support for multiple
inheritance. You can implement functionality similar to multiple
inheritance by using interfaces in Java. Java interfaces provide
object method descriptions, but contain no implementations.
C and C++ have no built-in support for text strings. The standard
technique adopted by C and C++ programmers is to use null-terminated
arrays of characters to represent strings.
In Java, strings are implemented as first-class objects (String
and StringBuffer), meaning
that they are at the core of the Java language. Java's implementation
of strings as objects provides several advantages:
- The manner in which you create strings
and access the elements of strings is consistent across all strings
on all systems.
- Because the Java string classes are defined
as part of the Java language, and not part of some extraneous
extension, Java strings function predictably every time.
- The Java string classes perform extensive
runtime checking, which helps eliminate troublesome runtime
The dreaded goto statement
is pretty much a relic these days-even in C and C++-even though
it is technically a legal part of the languages. The goto
statement has historically been cited as the cause for messy,
impossible-to-understand, and sometimes even impossible-to-predict
code known as "spaghetti code." The primary use of the
goto statement has merely
been as a convenience to substitute for the programmer's not thinking
through an alternative, more structured branching technique.
For all these reasons and more, Java does not provide a goto
statement. The Java language specifies goto
as a keyword, but its use is not supported. I suppose the Java
designers wanted to eliminate the possibility of even using goto
as an identifier! Not including goto
in the Java language simplifies the language and helps eliminate
the option of writing messy code.
Operator overloading, which is considered a prominent feature
in C++, is not supported in Java. Operator overloading
is a technique of defining different types of functionality for
a fundamental operator, such as the addition operator (+),
based on the types of objects being added. Although roughly the
same functionality can be implemented by classes in Java, the
convenience of operator overloading is still missing. However,
in defense of Java, operator overloading can sometimes get very
tricky. No doubt the Java developers decided not to support operator
overloading to keep the Java language as simple as possible.
Automatic coercion refers to the implicit casting of data
types that sometimes occurs in C and C++. For example, in C++,
you can assign a float value
to an int variable, which
can result in a loss of information. Java does not support C++-style
automatic coercions. In Java, if a co-ercion will result in a
loss of data, you must always explicitly cast the data element
to the new type.
C and C++ let you declare functions, such as printf,
that take a variable number of arguments. Although this is a convenient
feature, it is impossible for the compiler to thoroughly type-check
the arguments, which means problems can arise at runtime without
your knowing about them. Again, Java takes the high road and doesn't
support variable arguments at all.
The command-line arguments passed from the system into a Java
program differ in a couple of ways from the command-line arguments
passed into a C++ program. First, the number of parameters passed
differs between the two languages. In C and C++, the system passes
two arguments to a program: argc
and argv. argc
specifies the number of arguments stored in argv.
argv is a pointer to an array
of characters containing the actual arguments. In Java, the system
passes a single value to a program: args.
args is an array of Strings
that contains the command-line arguments.
In C and C++, the command-line arguments passed into a program
include the name used to invoke the program. This name always
appears as the first argument and is rarely used. In Java, you
already know the name of the program because it is the same name
as the class, so there is no need to pass this information as
a command-line argument. Therefore, the Java runtime system passes
only the arguments following the name that invoked the program.
email@example.com with questions or comments.
EarthWeb Inc., All rights reserved.
PLEASE READ THE ACCEPTABLE USAGE STATEMENT.
Copyright 1998 Macmillan Computer Publishing. All rights reserved.