Differences Between Java and C/C++
CONTENTS • • • • • • • • • • •
The Preprocessor Pointers Structures and Unions Functions Multiple Inheritance Strings The goto Statement Operator Overloading Automatic Coercions Variable Arguments Command-Line Arguments
It is no secret that the Java language is highly derived from the C and C++ languages. Because C++ is currently considered the language of choice for professional software developers, it's important to understand what aspects of C++ Java inherits. Of possibly even more importance are 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 Because C++ backwardl backwardly y suppor supports ts C, many many of the differ differenc ences es pointe pointed d out in this this appendix refer to C++, but inherently apply to C as well.
The Preprocessor All C/C++ compilers implement implement a stage of compilation compilation known as the preprocessor. preprocessor. The C++ preprocessor basically performs an intelligent search and replace on identifiers that have been declared using the #define or #typedef directives. Although most advocates of C++ discourage the use of the preprocessor, which was inherited from C, it is still widely used by most C++ programmers. Most of the processor definitions in C++ are stored in header files, which complement the actual source code files. The The probl problem em with with the the prep prepro roce cess ssor or appr approa oach ch is that that it provi provide dess an easy easy way way for for programmers to inadvertently add unnecessary complexity to a program. What happens is that many programmers using the #define and #typedef directives 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 and #typedef 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 validation.
Java does not have a preprocessor. It provides similar functionality (#define , #typedef , and so on) to that provided by the C++ preprocessor, but with far more control. Constant data members are used in place of the #define directive, and class definitions are used in lieu lieu of the the #typedef dire direct ctiv ive. e. The The resu result lt is that that Java Java sour source ce code code is much much more 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.
Pointers 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++ progra programme mmers rs regula regularly rly use comple complex x pointe pointerr arithm arithmeti eticc to create create and mainta maintain in dynamic data structures. In return, C++ programmers spend a lot of time hunting down complex bugs caused by their complex pointer arithmetic. 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 appro approac ach h prev preven ents ts comm common on erro errors rs due due to point pointer er mism mismana anagem gemen ent. t. It also also make makess programming easier in a lot of ways simply because the correct usage of pointers is easily misunderstood by all but the most seasoned programmers. p rogrammers. 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 operations.
Structures and Unions There are three types of complex data types in C++: classes, structures, and unions. Java only implements 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 lang languag uagee simp simple le,, so it only only made made sens sensee to elim elimin inat atee aspe aspect ctss of the the langu languag agee that that overlapped.
Functions 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 that are connected to classes. C++ class methods are very similar to Java class methods. However, because C++ still supports C, there is nothing discouraging C++ programmers from using functions. This results in a mixture of function and method use that makes for confusing programs. 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 forc forcin ing g prog progra ramm mmer erss to use use meth method odss inst instea ead d of funct functio ions ns.. As a matt matter er of fact fact,,
implementi implementing ng routines routines as methods methods encourages encourages programmers programmers to organize 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.
Multiple Inheritance 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 many 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.
Strings C and C++ have no built-in support for text strings. The standard technique adopted among C and C++ programmers is that of using 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 The Java Java stri string ng clas classe sess perf perfor orm m exten extensi sive ve runt runtim imee check checkin ing, g, whic which h help helpss eliminate troublesome runtime errors
The goto Statement The dreaded goto statement is pretty much a relic these days even in C and C++, but 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 usage of the goto statement has merely been as a convenience to substitute not thinking through an alternative, more structured branching technique. For all these reasons and more, Java does not provide a goto statement. statement. The Java language specifies goto as a keyword, but its usage 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
Operator overloading, which is considered a prominent feature in C++, is not supported in Java. 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, operato operatorr overloa overloadin ding g can someti sometimes mes get very very tricky. tricky. No doubt doubt the Java Java develop developers ers decided not to support operator overloading to keep the Java language as simple as possible.
Automatic Coercions 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 coercion will result in a loss of data, you must always explicitly cast the data element to the new type.
Variable Arguments 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 you knowing. Again Java takes the high road and doesn't support variable arguments at all.
Command-Line Arguments 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 ever 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 only passes the arguments following the name that invoked the program.