Comparison of Java and C++

This is a comparison of the Java programming language with the C++ programming language.

Design aims

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

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
Extension of C with object-oriented programming, still able to run C code. Strongly influenced by C++/C syntax.
Compatible with C source code, except for a few corner cases. Provides the Java Native Interface and recently Java Native Access as a way to directly call C/C++ code.
Write once, compile anywhere (WOCA). Write once, run anywhere / everywhere (WORA / WORE).
Allows procedural programming, functional programming, object-oriented programming, generic programming, and template metaprogramming. Favors a mix of paradigms. Allows procedural programming, functional programming (since Java 8) and generic programming (since Java 5), but strongly encourages the object-oriented programming paradigm. Includes support for the creation of scripting languages.
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.
Pointers, references, and pass-by-value are supported for all types (primitive or user-defined). All types (primitive types and reference types) are always passed by value.[1]
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]
Resource management can be done manually or by automatic lifetime-based resource management (RAII). Resource management must be done manually, or automatically via finalizers, though this is generally discouraged. Has try-with-resources for automatic scope-based resource management (version 7 onwards).
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.

The standard library has grown with each release. By version 1.6, the library included support for locales, logging, containers and iterators, algorithms, GUI programming (but not using the system GUI), graphics, multi-threading, networking, platform security, introspection, dynamic class loading, blocking and non-blocking I/O. It provided interfaces or support classes for XML, XSLT, MIDI, database connectivity, naming services (e.g. LDAP), cryptography, security services (e.g. Kerberos), print services, and web services. SWT offers an abstraction for platform-specific GUIs.
Operator overloading for most operators. Preserving meaning (semantics) is highly recommended. Operators are not overridable. The language overrides + and += for the String class.
Single and Multiple inheritance of classes, including virtual inheritance. Single inheritance of classes. Supports multiple inheritance via the Interfaces construct, which is equivalent to a C++ class composed of abstract methods.
Compile-time templates. Allows for Turing complete meta-programming. Generics are used to achieve basic type-parametrization, but they do not translate from source code to byte code due to the use of type erasure by the compiler.
Function pointers, function objects, lambdas (in C++11), and interfaces. References to functions achieved via the reflection API. OOP idioms using Interfaces, such as Adapter, Observer, and Listener are generally preferred over direct references to methods.
No standard inline documentation mechanism. Third-party software (e.g. Doxygen) exists. Extensive Javadoc documentation standard on all system classes and methods.
const keyword for defining immutable variables and member functions that do not change the object. Const-ness is propagated as a means to enforce, at compile-time, correctness of the code with respect to mutability of objects (see const-correctness). final provides a version of const, equivalent to type* const pointers for objects and const for primitive types. Immutability of object members achieved through read-only interfaces and object encapsulation.
Supports the goto statement. Supports labels with loops and statement blocks.
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

Syntax

See also: Java syntax and C++ syntax
C++ Java
class Foo {          // Declares class Foo
    int x;           //  Private Member variable
public:
    Foo() : x(0)     //  Constructor for Foo; initializes
    {}               //  x to 0. If the initializer were
                     //  omitted, the variable would not
                     //  be initialized to a specific
                     //  value.
 
    int bar(int i) { // Member function bar()
        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
    }
 
    public int bar(int i) {// Member method bar()
        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;
// copies the contents of a to a new Foo object b;
// 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;
// sets the reference b to point to this new 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
System.out.println(b.x);
// 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
// object (initially null if c is a class member;
// 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;
// modifies the object referenced by c
a.bar(5);  // invokes Foo::bar() for a
c->bar(5); // invokes Foo::bar() for *c
a.bar(5); // invokes Foo.bar() for a
c.bar(5); // invokes Foo.bar() for c
cout << d->x << endl;
// outputs 5, because d references the
// same object as c
System.out.println(d.x);
// outputs 5, because d references the
// same object as c
C++ Java
const Foo *a; // it is not possible to modify the object
              // pointed to by a through a
final Foo a; // a declaration of a "final" reference:
             // 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;
// ILLEGAL
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();
//ILLEGAL, it is not allowed to re-bind it
b = new Foo();
// ILLEGAL, it is not allowed to re-bind it
b->x = 5;
// LEGAL, the object can still be modified
b.x = 5;
// LEGAL, the object can still be modified

Semantics

Resource management

Libraries

Runtime

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

Both C++ and Java provide facilities for generic programming, templates and generics, respectively. Although they were created to solve similar kinds of problems, and have similar syntax, they are actually quite different.

C++ Templates Java Generics
Classes, functions and variables[16] can be templated. Classes and methods can be genericized.
Parameters can be any type, integral value, character literal, or a class template. Parameters can be any reference type, including boxed primitive types (i.e. Integer, Boolean...).
Separate instantiations of the class or function will be generated for each parameter-set when compiled. For class templates, only the member functions that are used will be instantiated. One version of the class or function is compiled, works for all type parameters (through type-erasure).
Objects of a class template instantiated with different parameters will have different types at run time (i.e., distinct template instantiations are distinct classes). Type parameters are erased when compiled; objects of a class with different type parameters are the same type at run time. It just causes a different constructor. Because of this type erasure, it is not possible to overload methods using different instantiations of the generic class.
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.
Templates can be specialized—a separate implementation could be provided for a particular template parameter. Generics cannot be specialized.
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[17] 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).
Type parameter of class template can be used for static methods and variables. Type parameter of generic class cannot be used for static methods and variables.
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.
Templates are Turing-complete (see template metaprogramming). Generics are probably not Turing-complete.

Miscellaneous

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

Performance

In addition to running a compiled Java program, computers running Java applications generally must also run the Java virtual machine (JVM), while compiled C++ programs can be run without external applications. Early versions of Java were significantly outperformed by statically compiled languages such as C++. This is because the program statements of these two closely related languages may compile to a few machine instructions with C++, while compiling into several byte codes involving several machine instructions each when interpreted by a JVM. For example:

Java/C++ statement C++ generated code (x86) Java generated byte code
vector[i]++; mov edx,[ebp+4h]

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

aload_1

iload_2
dup2
iaload
iconst_1
iadd
iastore

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:

However, there are a number of benefits to Java's design, some realized, some only theorized:

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

Official standard and reference of the language

Language specification

The C++ language is defined by ISO/IEC 14882, an ISO standard, which is published by the ISO/IEC JTC1/SC22/WG21 committee. The latest, post-standardization draft of C++11 is available as well.[28]

The C++ language evolves through an open steering committee called the C++ Standards Committee. The committee is composed of the creator of C++ Bjarne Stroustrup, the convener Herb Sutter, and other prominent figures, including many representatives of industries and user-groups (i.e., the stake-holders). Being an open committee, anyone is free to join, participate, and contribute proposals for upcoming releases of the standard and technical specifications. The committee now aims to release a new standard every few years, although in the past strict review processes and discussions have meant longer delays between publication of new standards (1998, 2003, and 2011).

The Java language is defined by the Java Language Specification,[29] 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[30]—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.

Trademarks

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

References

  1. "The Java Tutorials: Passing Information to a Method or a Constructor". Oracle. Retrieved 17 February 2013.
  2. "The Java Tutorials: Object as a Superclass". Oracle. Retrieved 17 February 2013..
  3. "XMPP Software » Libraries". xmpp.org. Retrieved 13 June 2013.
  4. Robert C. Martin (January 1997). "Java vs. C++: A Critical Comparison" (PDF).
  5. "Reference Types and Values". The Java Language Specification, Third Edition. Retrieved 9 December 2010.
  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.
  7. Deitel, Paul; Deitel, Harvey (2009). Java for Programmers. Prentice Hall. p. 223. ISBN 978-0-13-700129-3. Unlike some other languages, Java does not allow programmers to choose pass-by-value or pass-by-referenceall arguments are passed by value. A method call can pass two types of values to a methodcopies of primitive values (e.g., values of type int and double) and copies of references to objects (including references to arrays). Objects themselves cannot be passed to methods.
  8. "Semantics of Floating Point Math in GCC". GNU Foundation. Retrieved 20 April 2013.
  9. "Microsoft c++ compiler, /fp (Specify Floating-Point Behavior)". Microsoft Corporation. Retrieved 19 March 2013.
  10. "Java Language Specification 4.3.1: Objects". Sun Microsystems. Retrieved 9 December 2010.
  11. Standard for Programming Language C++ '11, 5.3.2 Increment and decrement [expr.pre.incr].
  12. The Java™ Language Specification, Java SE 7 Edition, Chapters 15.14.2 , 15.14.3, 15.15.1, 15.15.2, http://docs.oracle.com/javase/specs/
  13. Satish Chandra Gupta, Rajeev Palanki (16 August 2005). "Java memory leaks -- Catch me if you can". IBM DeveloperWorks. Archived from the original on 2012-07-22. Retrieved 2015-04-02.
  14. How to Fix Memory Leaks in Java by Veljko Krunic (Mar 10, 2009)
  15. Creating a memory leak with Java on stackoverflow.com
  16. http://en.cppreference.com/w/cpp/language/variable_template
  17. Boost type traits library
  18. Clark, Nathan; Amir Hormati; Sami Yehia; Scott Mahlke (2007). "Liquid SIMD: Abstracting SIMD hardware using lightweight dynamic mapping". HPCA’07: 216–227.
  19. Hundt, Robert (2011-04-27). "Loop Recognition in C++/Java/Go/Scala" (PDF; 318&NBSP;KB). Stanford, California: Scala Days 2011. Retrieved 2012-11-17. Java shows a large GC component, but a good code performance. [...] We find that in regards to performance, C++ wins out by a large margin. [...] The Java version was probably the simplest to implement, but the hardest to analyze for performance. Specifically the effects around garbage collection were complicated and very hard to tune
  20. Matthew Hertz, Emery D. Berger (2005). "Quantifying the Performance of Garbage Collection vs. Explicit Memory Management" (PDF). OOPSLA 2005. Retrieved 2015-03-15. In particular, when garbage collection has five times as much memory as required, its runtime performance matches or slightly exceeds that of explicit memory management. However, garbage collection’s performance degrades substantially when it must use smaller heaps. With three times as much memory, it runs 17% slower on average, and with twice as much memory, it runs 70% slower.
  21. Alexandrescu, Andrei (2001). Addison-Wesley, ed. Modern C++ Design: Generic Programming and Design Patterns Applied. Chapter 4. pp. 77–96. ISBN 978-0-201-70431-0.
  22. "Boost Pool library". Boost. Retrieved 19 April 2013.
  23. Targeting IA-32 Architecture Processors for Run-time Performance Checking
  24. Fixing The Inlining “Problem” by Dr. Cliff Click | Azul Systems: Blogs
  25. Oracle Technology Network for Java Developers
  26. Oracle Technology Network for Java Developers
  27. Understanding Strict Aliasing - CellPerformance
  28. "Working Draft, Standard for Programming Language C++" (PDF).
  29. The Java Language Specification
  30. The Java Community Process(SM) Program - Participation - JCP Members
  31. Bjarne Stroustrup's FAQ: Do you own C++?
  32. ZDNet: Oracle buys Sun; Now owns Java.

External links

The Wikibook C++ Programming has a page on the topic of: Programming Languages/Comparisons/Java