Comparison of Java and C++

From Wikipedia, the free encyclopedia
Jump to: navigation, search


Design aims[edit]

The differences between the C++ and Java programming languages can be traced to their heritage, as they have different design goals.

  • C++ was designed for systems and applications programming (a.k.a. infrastructure programming), extending the C programming language. To this procedural programming language designed for efficient execution, C++ has added support for statically typed object-oriented programming, exception handling, lifetime-based resource management (RAII), generic programming, and template metaprogramming, in particular. It also added a standard library which includes generic containers and algorithms (STL), as well as many other general purpose facilities.
  • Java is a general-purpose, concurrent, class-based, object-oriented computer programming language that is specifically designed to have as few implementation dependencies as possible. It relies on a java virtual machine to be secure and highly portable. It is bundled with an extensive library designed to provide a complete abstraction of the underlying platform. Java is a statically typed object-oriented language that uses similar (but incompatible) syntax to C++. It includes a documentation system called Javadoc.

The different goals in the development of C++ and Java resulted in different principles and design tradeoffs between the languages. The differences are as follows :

C++ Java
Strongly influenced by C syntax, with Object-Oriented features added. Strongly influenced by C++/C syntax.
Runs as native executable machine code for the target instruction set(s). Runs in a virtual machine.
Provides object types and type names. Allows reflection through RTTI. Is reflective, allowing metaprogramming and dynamic code generation at runtime.
Has multiple binary compatibility standards (commonly Microsoft (for MSVC compiler) and Itanium/GNU (for virtually all other compilers)). Has a single, OS- and compiler-independent binary compatibility standard.
Optional automated bounds checking (e.g., the at() method in vector and string containers). All operations are required to be Bound-checked by all compliant distributions of Java. HotSpot can remove bounds checking.
Supports native unsigned arithmetic. No native support for unsigned arithmetic.
Standardized minimum limits for all numerical types, but the actual sizes are implementation-defined. Standardized types are available through the standard library <cstdint>. Standardized limits and sizes of all primitive types on all platforms.
Memory management can be done manually through new / delete, automatically by scope, or by smart pointers. Supports deterministic destruction of objects. Garbage collection ABI standardized in C++11, though compilers are not required to implement garbage collection. Automatic garbage collection. Supports a non-deterministic finalize() method whose use is not recommended.[2]
Supports classes, structs (POD-types), and unions, and can allocate them on the heap or the stack. Classes are allocated on the heap. Java SE 6 optimizes with escape analysis to allocate some objects on the stack.
Allows explicitly overriding types as well as some implicit narrowing conversions (for compatibility with C). Rigid type safety except for widening conversions.
The C++ Standard Library was designed to have a limited scope and functionality but includes language support, diagnostics, general utilities, strings, locales, containers, algorithms, iterators, numerics, input/output, random number generators, regular expression parsing, threading facilities, type traits (for static type introspection) and Standard C Library. The Boost library offers more functionality including network I/O.

A rich amount of third-party libraries exist for GUI and other functionalities like: ACE, Crypto++, various XMPP Instant Messaging (IM) libraries,[3] OpenLDAP, Qt, gtkmm.

Source code can be written to be platform-independent (can be compiled for Windows, BSD, Linux, Mac OS X, Solaris, etc., without modification) and written to take advantage of platform-specific features. Typically compiled into native machine code, must be re-compiled for each target platform. Compiled into byte code for the JVM. Byte code is dependent on the Java platform, but is typically independent of operating system specific features.

Language features[edit]


See also: Java syntax and C++ syntax
C++ Java
class Foo {          // Declares class Foo
    int x;           //  Private Member variable
    {}               //  x to 0. If the initializer were
                     //  omitted, the variable would not
                     //  be initialized to a specific
                     //  value.
        return 3*i + x;
class Foo {               // Defines class Foo
    private int x;         // Member variable, normally variables
                           // are declared as private to
                           // enforce encapsulation
                          //initialized to 0 by default
    public Foo() {        // Constructor for Foo
        return 3*i + x;
Foo a;
// declares a to be a Foo object value,
// initialized using the default constructor.
// Another constructor can be used as
Foo a(args);
// or (C++11):
Foo a{args};
Foo a;
// declares a to be a reference to a Foo object
a = new Foo();
// initializes using the default constructor
// Another constructor can be used as
Foo a = new Foo(args);
Foo b = a;
// alternative syntax is "Foo b(a)"
Foo b = a.clone();
// copies the contents of the object pointed to by a 
//     to a new Foo object;
// the Foo class must implement the Cloneable interface
//     for this code to compile
a.x = 5; // modifies the object a
a.x = 5; // modifies the object referenced by a
cout << b.x << endl;
// outputs 0, because b is
// a different object than a
// outputs 0, because b points to
// a different object than a
Foo *c;
// declares c to be a pointer to a
// Foo object (initially
// undefined; could point anywhere)
Foo c;
// declares c to be a reference to a Foo
// it is necessary to initialize c before use
// if it is a local variable)
c = new Foo;
// binds c to reference a new Foo object
c = new Foo();
// binds c to reference a new Foo object
Foo *d = c;
// binds d to reference the same object as c
Foo d = c;
// binds d to reference the same object as c
c->x = 5;
// modifies the object referenced by c
c.x = 5;
cout << d->x << endl;
// outputs 5, because d references the
// same object as c
// outputs 5, because d references the
// same object as c
C++ Java
              // pointed to by a through a
             // it is possible to modify the object, 
             // but the reference will constantly point 
             // to the first object assigned to it
a = new Foo();
a = new Foo(); // Only in constructor
a->x = 5;
a.x = 5;
// LEGAL, the object's members can still be modified 
// unless explicitly declared final in the declaring class
Foo *const b = new Foo();
// a declaration of a "const" pointer
final Foo b = new Foo();
// a declaration of a "final" reference
b = new Foo();
b = new Foo();
b->x = 5;
// LEGAL, the object can still be modified
b.x = 5;
// LEGAL, the object can still be modified
  • C++ supports goto statements, which may lead to Spaghetti programming. With the exception of the goto statement (which is very rarely seen in real code and highly discouraged), both Java and C++ have basically the same control flow structures, designed to enforce structured control flow, and relies on break and continue statements to provide some goto-like functionality. Some commenters point out that these labelled flow control statements break the single point-of-exit property of structured programming.[4]


  • The minimum of code you need to compile for C++ is a function. The minimum for Java is a class.
  • C++ allows a range of implicit conversions between native types (including some narrowing conversions), and also allows the programmer to define implicit conversions involving user-defined types. In Java, only widening conversions between native types are implicit; other conversions require explicit cast syntax.
    • This also implies that C++ compilers can automatically select the most efficient representation for the target platform (i.e., 64bit integers for a 64bit platform), while the representation is fixed in Java, meaning the values can either be stored in the less-efficient size, or must pad the remaining bits and add code to emulate the reduced-width behavior.
  • The rounding and precision of floating point values and operations in C++ is implementation-defined (although only very exotic or old platforms depart from the IEEE 754 standard). Java provides an optional strict floating-point model that guarantees more consistent results across platforms, though possibly at the cost of slower run-time performance, however, Java does not provide strict compliance to the IEEE 754 standard. Most C++ compilers will, by default, partially comply to IEEE 754 standard (usually excluding strict rounding rules and raise exceptions on NaN results), but provide options for stricter compliance as well as less strict compliance (to allow for some optimizations).[8][9] If we label those options from least compliant to most compliant as fast, consistent (Java's strictfp), near-IEEE, and strict-IEEE, we can say that most C++ implementations default to near-IEEE, with options to switch to fast or strict-IEEE, while Java defaults to fast with an option to switch to consistent.
  • C++ features user-defined operator overloading. Operator overloading allows for user-defined types to support operators (arithmetic, comparisons, etc.) like primitive types via user-defined implementations for these operators. It is generally recommended to preserve the semantics of the operators. Java does not support any form of operator overloading (although its library uses the addition operator for string concatenation).
  • C++ supports static and dynamic linking of binaries.
  • Java has both language and standard library support for multi-threading. The synchronized keyword in Java provides simple and secure mutex locks to support multi-threaded applications. Java also provides robust and complex libraries for more advanced multi-threading synchronization. Only as of C++11 is there a defined memory model for multi-threading in C++, as well as library support for creating threads and for many synchronization primitives. There are also many third-party libraries for this purpose.

Resource management[edit]

  • Java offers automatic garbage collection, which may be bypassed in specific circumstances via the Real time Java specification. Memory management in C++ is usually done through constructors, destructors, and smart pointers. The C++ standard permits garbage collection, but does not require it; garbage collection is rarely used in practice.
  • C++ can allocate arbitrary blocks of memory. Java only allocates memory through object instantiation. Arbitrary memory blocks may be allocated in Java as an array of bytes.
    • C++ has destructors, while Java has finalizers. Both are invoked prior to an object's deallocation, but they differ significantly. A C++ object's destructor must be implicitly (in the case of stack-bound variables) or explicitly invoked to deallocate the object. The destructor executes synchronously just prior to the point in the program at which the object is deallocated. Synchronous, coordinated uninitialization and deallocation in C++ thus satisfy the RAII idiom. In Java, object deallocation is implicitly handled by the garbage collector. A Java object's finalizer is invoked asynchronously some time after it has been accessed for the last time and before it is actually deallocated. Very few objects require finalizers; a finalizer is only required by objects that must guarantee some cleanup of the object state prior to deallocation — typically releasing resources external to the JVM.
    • In C++, it is possible to have a dangling pointer—a stale reference to an object that has already been deallocated. Attempting to use a dangling pointer typically results in program failure. In Java, the garbage collector will not destroy a referenced object.




C++ Java
C++ is compiled directly to machine code which is then executed directly by the central processing unit. Java is compiled to byte-code which the Java virtual machine (JVM) then interprets at runtime. Actual Java implementations do Just-in-time compilation to native machine code. Alternatively, the GNU Compiler for Java can compile directly to machine code.

Templates vs. generics[edit]


C++ Templates Java Generics
Classes and functions can be templated. Classes and methods can be genericized.
Implementation of the class or function template must be visible within a translation unit in order to use it. This usually implies having the definitions in the header files or included in the header file. As of C++11, it is possible to use extern templates to separate the compilation of certain instantiations. Signature of the class or function from a compiled class file is sufficient to use it.
Template parameters can have default arguments. (Prior to C++11, this was allowed only for template classes, not functions.) Generic type parameters cannot have default arguments.
Does not support wildcards. Instead, return types are often available as nested typedefs. (Also, C++11 added keyword auto, which acts as a wildcard for any type that can be determined at compile time.) Supports wildcard as type parameter.
Does not directly support bounding of type parameters, but metaprogramming provides this[14] Supports bounding of type parameters with "extends" and "super" for upper and lower bounds, respectively; allows enforcement of relationships between type parameters.
Allows instantiation of an object with the type of the parameter type. Does not allow instantiation of an object with the type of the parameter type (except through reflection).
Static variables are not shared between classes and functions of different type parameters. Static variables are shared between instances of classes of different type parameters.
Class and function templates do not enforce type relations for type parameters in their declaration. Use of an incorrect type parameter results in compilation failure, often generating an error message within the template code rather than in the user's code that invokes it. Proper use of templated classes and functions is dependent on proper documentation. Metaprogramming provides these features at the cost of additional effort. There was a proposition to solve this problem in C++11, so-called Concepts, it is now planned for the next standard. Generic classes and functions can enforce type relationships for type parameters in their declaration. Use of an incorrect type parameter results in a type error within the code that uses it. Operations on parametrized types in generic code are only allowed in ways that can be guaranteed to be safe by the declaration. This results in greater type safety at the cost of flexibility.


  • C++ compilation features an additional textual preprocessing phase, while Java does not. Thus some users add a preprocessing phase to their build process for better support of conditional compilation.
  • The sizes of integer types are defined in Java (int is 32-bit, long is 64-bit), while in C++ the size of integers and pointers is compiler and ABI dependent within given constraints. Thus, carefully written C++ code can take advantage of the 64-bit processor's capabilities while still functioning properly on 32-bit processors. In contrast, Java's fixed integer sizes may incur a performance penalty since Java code cannot run using an arbitrary processor's word size.

An example comparing C++ and Java exists in Wikibooks.




mov eax,[ebp+1Ch]
inc dword ptr [edx+eax*4]



Since performance optimization is a very complex issue, it is very difficult to quantify the performance difference between C++ and Java in general terms, and most benchmarks are unreliable and biased. And given the very different natures of the languages, definitive qualitative differences are also difficult to draw. In a nutshell, there are inherent inefficiencies as well as hard limitations on optimizations in Java given that it heavily relies on flexible high-level abstractions, however, the use of a powerful JIT compiler (as in modern JVM implementations) can mitigate some issues. And, in any case, if the inefficiencies of Java are too much to bear, compiled C or C++ code can be called from Java by means of the JNI.

Certain inefficiencies that are inherent to the Java language itself include, primarily:

  • All objects are allocated on the heap. For functions using small objects this can result in performance degradation and heap fragmentation, while stack allocation, in contrast, costs essentially zero. However, modern JIT compilers mitigate this problem to some extent with escape analysis or escape detection to allocate objects on the stack, since Oracle JDK 6.
  • Methods are virtual by default (although they can be made final), usually leading to an abuse of virtual methods, adding a level of indirection to every call. This also slightly increases memory usage by adding a single pointer to a virtual table per each object. It also induces a start-up performance penalty, since a JIT compiler must perform additional optimization passes for de-virtualization of small functions.


  • Java garbage collection may have better cache coherence than the usual usage of malloc/new for memory allocation. Nevertheless, arguments exist[weasel words] that both allocators equally fragment the heap and neither exhibits better cache locality. However, in C++, allocation of single objects on the heap is rare, and large quantities of single objects are usually allocated in blocks via an STL container and/or with a small object allocator.[16][17]
  • Run-time compilation can potentially use information about the platform on which the code is being executed to improve code more effectively. However, most state-of-the-art native (C, C++, etc.) compilers generate multiple code paths to employ the full computational abilities of the given system.[18] Additionally, the inverse argument can be made that native compilers can better exploit architecture-specific optimizations and instruction sets than multi-platform JVM distributions.
  • In Java, thread synchronization is built into the language, so the JIT compiler can potentially, through escape analysis, elide locks,[20] significantly improving performance of naive multi-threaded code. This technique was introduced in Sun JDK 6 update 10 and is named biased locking.[21]

Additionally, some performance problems exist in C++ as well:

  • Allowing pointers to point to any address can make optimization difficult due to the possibility of interference between pointers that alias each other. However, the introduction of strict-aliasing rules largely solves this problem.[22]
  • Since the code generated from various instantiations of the same class template in C++ is not shared (as with type-erased generics in Java), excessive use of templates may lead to significant increase of the executable code size (a.k.a. code bloat). However, because function templates are aggressively inlined, they can sometimes reduce code bloat but more importantly allow for more aggressive static analysis and code optimization by the compiler, more often making them more efficient than non-templated code, while, by contrast, Java generics are necessarily less efficient than non-genericized code.
  • Because dynamic linking is performed after code generation and optimization in C++, function calls spanning different dynamic modules cannot be inlined.
  • Because thread support is generally provided by libraries in C++, C++ compilers cannot perform thread-related optimizations. However, since the introduction of multi-threading memory models in C++11, modern compilers have the necessary language features to implement such optimizations. Furthermore, many optimizing compilers, such as the Intel compiler, provide several language extensions and advanced threading facilities for professional multi-threading development.

Official standard and reference of the language[edit]

Language specification[edit]



The Java language is defined by the Java Language Specification,[24] a book which is published by Oracle.

The Java language continuously evolves through a process called the Java Community Process, and the world's programming community is represented by a group of people and organizations - the Java Community members[25]—which is actively engaged into the enhancement of the language, by sending public requests - the Java Specification Requests - which must pass formal and public reviews before they get integrated into the language.

The lack of a firm standard for Java and the somewhat more volatile nature of its specifications have been a constant source of criticism by stake-holders wanting more stability and more conservatism in the addition of new language and library features. On the other hand, C++ committee also receives constant criticism for the opposite reason, i.e., being too strict and conservative, and taking too long to release new versions.


"C++" is not a trademark of any company or organization and is not owned by any individual.[26] "Java" is a trademark of Oracle Corporation.[27]


  3. ^ "XMPP Software » Libraries". Retrieved 13 June 2013. 
  6. ^ Horstmann, Cay; Cornell, Gary (2008). Core Java I (Eighth ed.). Sun Microsystems. pp. 140–141. ISBN 978-0-13-235476-9. "Some programmers (and unfortunately even some book authors) claim that the Java programming language uses call by reference for objects. However, that is false. Because this is such a common misunderstanding, it is worth examining a counterexample in some detail... This discussion demonstrates that the Java programming language does not use call by reference for objects. Instead object references are passed by value." 
  13. ^ "Java memory leaks -- Catch me if you can" by Satish Chandra Gupta, Rajeev Palanki, IBM DeveloperWorks, 16 August 2005
  14. ^ Boost type traits library
  17. ^ "Boost Pool library". Boost. Retrieved 19 April 2013. 
  18. ^ Targeting IA-32 Architecture Processors for Run-time Performance Checking
  20. ^ Oracle Technology Network for Java Developers
  21. ^ Oracle Technology Network for Java Developers
  22. ^ Understanding Strict Aliasing - CellPerformance
  23. ^ "Working Draft, Standard for Programming Language C++". 
  24. ^ The Java Language Specification
  25. ^ The Java Community Process(SM) Program - Participation - JCP Members
  26. ^ Bjarne Stroustrup's FAQ: Do you own C++?
  27. ^ ZDNet: Oracle buys Sun; Now owns Java.

External links[edit]