2.13. Differences Between C and Java
If you are a C or C++ programmer, you should
have found much of the syntax of Javaparticularly at the level
of operators and statementsto be familiar. Because Java and C
are so similar in some ways, it is important for C and C++
programmers to understand where the similarities end. C and Java
differ in important ways, as summarized in the following list:
- 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
static final 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 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 Java has no global variables,
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 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.
|