-
No preprocessor
-
Java does not include a preprocessor and does not define
any analogs of the #define,
#include, and #ifdef
directives. Constant definitions are replaced with
staticfinal fields in
Java. (See the java.lang.Math.PI field
for an example.) Macro definitions are not available in
Java, but advanced compiler technology and inlining has made
them less useful. Java does not require an
#include directive because Java has no
header files. Java class files contain both the class API
and the class implementation, and the compiler reads API
information from class files as necessary. Java lacks
any form of conditional compilation, but its cross-platform
portability means that this feature is very rarely needed.
-
No global variables
-
Java defines a very clean namespace. Packages contain
classes, classes contain fields and methods, and methods
contain local variables. But there are no global
variables in Java, and, thus, there is
no possibility of namespace collisions
among those variables.
-
Well-defined primitive type sizes
-
All the primitive types in Java have well-defined sizes. In
C, the size of short,
int, and long types is
platform-dependent, which hampers portability.
-
No pointers
-
Java classes and arrays are reference types, and references
to objects and arrays are akin to pointers in C. Unlike C
pointers, however, references in Java are entirely opaque. There is no way to convert a reference to a primitive type,
and a reference cannot be incremented or decremented. There
is no address-of operator like &,
dereference operator like * or
−>, or
sizeof operator. Pointers are a
notorious source of bugs. Eliminating them simplifies the
language and makes Java programs more robust and secure.
-
Garbage collection
-
The Java Virtual Machine performs garbage collection so that
Java programmers do not have to explicitly manage the memory
used by all objects and arrays. This feature eliminates
another entire category of common bugs and all but
eliminates memory leaks from Java programs.
-
No goto statement
-
Java doesn't support a goto
statement. Use of goto except in
certain well-defined circumstances is regarded as
poor programming practice. Java adds exception handling
and labeled break and
continue statements to the flow-control
statements offered by C. These are a good
substitute for goto.
-
Variable declarations anywhere
-
C requires local variable declarations to be made at the
beginning of a method or block, while Java allows them anywhere
in a method or block. Many programmers prefer to keep all their
variable declarations grouped together at the top of a
method, however.
-
Forward references
-
The Java compiler is smarter than the C compiler, in that it
allows methods to be invoked before they are defined. This
eliminates the need to declare functions in a header file
before defining them in a program file, as is done in C.
-
Method overloading
-
Java programs can define multiple methods with the same
name, as long as the methods have different parameter lists.
-
No struct and union types
-
Java doesn't support C struct and
union types. A Java
class can be thought of as an enhanced
struct, however.
-
No enumerated types
-
Java doesn't support the enum keyword
used in C to define types that consist of fixed sets of named
values. This is surprising for a strongly typed language
like Java, but there are ways to simulate this feature with
object constants.
-
No bitfields
-
Java doesn't support the (infrequently used) ability of C
to specify the number of individual bits occupied by fields
of a struct.
-
No typedef
-
Java doesn't support the typedef keyword
used in C to define aliases for type names. Java's lack of
pointers makes its type-naming scheme simpler and more
consistent than C's, however, so many of the common uses of
typedef are not really necessary in Java.
-
No method pointers
-
C allows you to store the address of a function in a
variable and pass this function pointer to other
functions. You cannot do this with Java methods, but you
can often achieve similar results by passing an object
that implements a particular interface. Also, a Java method
can be represented and invoked through a
java.lang.reflect.Method object.
-
No variable-length argument lists
-
Java doesn't allow you to define methods such as C's
printf() that take a variable number of
arguments. Method overloading allows you to simulate C
varargs functions for simple cases, but there's no
general replacement for this feature.