This article has multiple issues. Please help improve it or discuss these issues on the talk page. (Learn how and when to remove these messages)
|
Java and C++ are two prominent object-oriented programming languages. By many language popularity metrics, the two languages have dominated object-oriented and high-performance software development for much of the 21st century, and are often directly compared and contrasted. Java's syntax was based on C/C++.
The differences between the programming languages C++ and Java can be traced to their heritage, as they have different design goals.
C++ was designed for systems and applications programming (i.e., infrastructure programming), extending the procedural programming language C, which was designed for efficient execution. To C, C++ added support for object-oriented programming, exception handling, lifetime-based resource management (Resource Acquisition Is Initialization (RAII)), generic programming, template metaprogramming, and the C++ Standard Library which includes generic containers and algorithms (the Standard Template Library or STL), and many other general purpose facilities.
Java is a general-purpose, concurrent, class-based, object-oriented programming language that is designed to minimize implementation dependencies. It relies on a Java virtual machine to be secure and highly portable. It is bundled with an extensive/massive library designed to provide abstraction of the underlying platform. Java is a statically typed object-oriented language that uses a syntax similar to (but incompatible with) C++. It includes a documentation system called Javadoc.
The different goals in the development of C++ and Java resulted in different principles and design trade-offs between the languages. The differences are as follows:
| C++ | Java |
|---|---|
| Extends C with object-oriented programming and generic programming. C code can most properly be used. | Strongly influenced by C++/C syntax. |
| Compatible with C source code, except for a few corner cases. | Provides the Java Native Interface as well as Java Native Access and more recently Foreign Function and Memory API as a way to directly call C/C++ code. However, native languages are not safe and applications using native methods are susceptible to memory corruption. If the code is not carefully written, native methods can lower the performance of the system because the garbage collector is incapable of monitoring or maintaining native memory usage, and there is a cost context-switching between native and non-native 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 creating scripting languages. |
| Runs as native executable machine code for the target instruction set(s). | Runs on a virtual machine. |
Allows run-time type information (RTTI) and static (compile-time) reflection via std::meta (since C++26). |
Is reflective, allowing metaprogramming and dynamic code generation at runtime using java.lang.reflect. |
| Has multiple binary compatibility standards (commonly Microsoft (for MSVC compiler) and Itanium/GNU (for almost all other compilers)). | Has one binary compatibility standard, cross-platform for OS and compiler. |
Optional automated bounds checking (e.g., the at() method in classes like std::vector<T> and std::string). |
All operations are required to be bound-checked by all compliant distributions of Java. HotSpot can remove bounds checking. |
| Native unsigned arithmetic support. | Native unsigned arithmetic unsupported. Java 8 changes some of this, but aspects are unclear. |
Standardized minimum limits for all numerical types, but the actual sizes are implementation-defined. Standardized types are available via 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. |
Memory management can be done manually via new and delete, automatically by scope, or by smart pointers. Supports deterministic destruction of objects.
A garbage collection ABI was standardized in C++11, but was implemented by few compilers and removed from the standard in C++23. |
Automatic garbage collection. java.lang.Object has a non-deterministic finalize() method available for overloading, use of which is not recommended and was deprecated in Java 9. |
| Resource management can be done manually or by automatic lifetime-based resource management (RAII). | Resource management must generally 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). Resources, such as memory, can be managed using Java Native Interface or the Java Foreign Function and Memory API (since Java 22), but requires calling external C/C++ code.
It can also be done using the internal API |
| Supports classes, structs (passive data structure (PDS) 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, and 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 functions, 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. Networking is a planned feature but not finalized yet. The Boost library and POCO C++ Libraries offer more abilities.
A rich amount of third-party libraries exist for GUI and other functions like: Adaptive Communication Environment (ACE), Crypto++, various XMPP Instant Messaging (IM) libraries, 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 offered an abstraction for platform-specific GUIs, but was superseded by JavaFX in the latest releases; allowing for graphics acceleration and CSS-themable UIs. Although it doesn't support any kind of "native platform look" support. |
| Operator overloading for most operators. Preserving meaning (semantics) is highly recommended. | Operators are not overridable. The language overrides + and += for the java.lang.String class. |
| Single and multiple inheritance of classes, including virtual inheritance. | Only supports single inheritance of classes, however interfaces may multiply extend other interfaces and classes may implement multiple interfaces. |
| 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. Java type-casts all generics to their lowest bound (java.lang.Object if no such bound exists, otherwise ? extends T is cast to T). |
| Function pointers, function objects, lambdas (in C++11), and interfaces (using abstract classes).
C++26 introduces |
Functions references, function objects and lambdas were added in Java 8. Classes (and interfaces, which are classes) can be passed as references.
Java has its own |
| No standard inline documentation mechanism. Third-party software (e.g. Doxygen) exists. Standard library vendors may provide documentation comments, though it is not guaranteed. cppreference |
Extensive Javadoc documentation standard on all system classes and methods. Official documentation available at docs |
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 T* const pointers for objects and const for primitive types. Immutability of object members achieved via read-only interfaces and object encapsulation. |
Supports the goto statement. |
Supports labels with loops and statement blocks. goto is a reserved keyword but remains unused as per the Java specification. |
| Source code can be written to be cross-platform (can be compiled for BSD, Linux, macOS, Solaris, Windows, etc., without modification) and written to use platform-specific features. Typically compiled into native machine code, must be recompiled for each target platform. | Compiled into Java bytecode for the JVM. Byte code is dependent on the Java platform, but is typically independent of operating system specific features. |
Foo<1>(3); is a sequence of comparisons if Foo is a variable, but creates an object if Foo is the name of a class template.java.lang.Object. C++ does not have any global inheritance tree. It does have a top type std::any, but is a type-erased runtime object rather than an inherited type.| C++ | Java |
|---|---|
// Declares class Foo
// Foo is declared exported from the module
export class Foo {
private:
// Private member variable. It will be initialized
// to 0, if the constructor would not set it. (from C++11)
int x = 0;
public:
// Constructor for Foo; initializes x to 0.
// If the initializer were omitted, the variable
// would be initialized to the value that has been
// given at declaration of x.
Foo():
x{0} {}
// Member function bar()
int bar(int i) noexcept {
return 3 * i + x;
}
};
|
// Defines class Foo
// Foo is declared public to the package
public class Foo {
// Member variable, normally declared
// as private to enforce encapsulation
// initialized to 0 by default
private int x;
// Constructor for Foo
// no-arg constructor supplied by default
public Foo() {}
// Member method bar()
public int bar(int i) {
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 = Foo(args);
// or, more succinctly,
Foo a(args);
// or (C++11):
Foo a{args};
// with pointers:
Foo* a = new Foo();
|
Foo a = new Foo();
// declares a to be a reference to a new Foo object
// initialized 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;
// would declare b to be reference to the object pointed to by 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
|
std::println("{}", b.x);
// outputs 0, because b is
// some object other than a
|
System.out.println(b.x);
// outputs 0, because b points to
// some object other 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;
// c is set to the value of the address of the Foo object created by operator new
|
c = new Foo();
// binds c to reference a new Foo object
|
Foo& d = *c;
// binds d to reference the same object to which c points
|
Foo d = c;
// binds d to reference the same object as c
|
c->x = 5;
// modifies the object pointed to by c
|
c.x = 5;
// modifies the object referenced by c
|
d.bar(5); // invokes Foo::bar() for a
c->bar(5); // invokes Foo::bar() for *c
|
d.bar(5); // invokes Foo.bar() for a
c.bar(5); // invokes Foo.bar() for c
|
std::println("{}", d.x);
// outputs 5, because d references the
// same object to which c points
|
System.out.println(d.x);
// outputs 5, because d references the
// same object as c
|
It is possible to declare a pointer or reference to a const object in order to prevent client code from modifying it. Functions and methods can also guarantee that they will not modify the object pointed to by a pointer by using the "const" keyword. This enforces const-correctness.
// it is not possible to modify the object
// pointed to by a through a
const Foo* a;
|
The final keyword is similar to the const keyword in C++, but its usage is more limited. For the most part, const-correctness must rely on the semantics of the class' interface, i.e., it is not strongly enforced, except for public data members that are labeled final.
// 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
final Foo a;
|
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
// it is possible to modify the object,
// but the pointer will constantly point
// to the object assigned to it here
|
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
|
goto statements, which may lead to spaghetti code 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 functions. Some commenters point out that these labelled flow control statements break the single point-of-exit property of structured programming.sun.misc.Unsafe API for direct memory access and manipulation). In C++, pointers can be used to manipulate specific memory locations, a task necessary for writing low-level operating system components. Similarly, many C++ compilers support an inline assembler, and assembly functions may be linked in C/C++ programs. In Java, such code must reside in external libraries, and can only be accessed via the Java Native Interface, with a significant overhead for each call.if, while and the exit condition in for) in Java and C++ both expect a Boolean expression, code such as if (a = 5) will cause a compile error in Java because there is no implicit narrowing conversion from int to Boolean, but will compile in C++. This is handy if the code was a typo and if (a == 5) was intended. However, current C++ compilers will usually generate a warning when such an assignment is performed within a conditional expression. Similarly, standalone comparison statements, e.g. a == 5;, without a side effect usually lead to a warning.strictfp) that guarantees more consistent results across platforms, though at the cost of possibly slower run-time performance. However, Java does not comply strictly with the IEEE 754 standard. Most C++ compilers will, by default, comply partly with IEEE 754 (usually excluding strict rounding rules and raise exceptions on NaN results), but provide compliance options of varied strictness, to allow for some optimizing. 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.sun.misc.Unsafe API, however it is deprecated and not recommended.var keyword, while C++ uses the auto keyword (historically, such as back in B and C, auto declared the variable with automatic storage). In C++, if auto is used as a function's parameter type, it denotes an anonymous (unnamed) template, making the parameter generic. If auto is preceded by a concept, it ensures the deduced type satisfies the concept (or halts compilation if not), and if in a context in which auto represents an abbreviated type parameter, constrains the type by that concept.new and left undeleted) it provides an effective means of resource management. Shared resources can be managed using std::shared_ptr<T>, along with std::weak_ptr<T> to break cyclic references. Java supports automatic memory management using garbage collection which can free unreachable objects even in the presence of cyclic references, but other system resources (files, streams, windows, communication ports, threads, etc.) must be explicitly released because garbage collection is not guaranteed to occur immediately after the last object reference is abandoned. Java allows scope resource management through try-with-resources blocks for types that implement java.lang.AutoCloseable, but unlike C++, the object is not disposed from memory, but only owned resources are disposed by the close() method.synchronized keyword in Java provides mutex locks to support multi-threaded applications. Java also provides libraries for more advanced multi-threading synchronizing. C++11 has a defined memory model for multi-threading in C++, and library support for creating threads and for many synchronizing primitives.final keyword (i.e., opt-out virtual).override keyword to indicate overriding a virtual method. Java does not, but features a @Override annotation to indicate overriding, which issues a compiler error if no existing method is being overriden.enum) implicitly convert to integer types (but not from integer types), while C++ enumerations (enum class) are strongly typed and do not implicitly convert. Java enumerations behave like classes and may define constructors and methods.++ and --: in C++ "The operand shall be a modifiable lvalue. [skipped] The result is the updated operand; it is an lvalue...", but in Java "the binary numeric promotion mentioned above may include unboxing conversion and value set conversion. If necessary, value set conversion {and/or [...] boxing conversion} is applied to the sum prior to its being stored in the variable.", i.e. in Java, after the initialization Integer i = 2; ++i; changes the reference i by assigning new object, while in C++ the object is still the same.decltype and are part of the language model. Java lambdas depend on the functional interface which they are assigned to.try-with-resources or try-finally block achieves a more similar purpose as the destructor. One problem with finalizers or cleaners is that it is not guaranteed that they will run immediately. Hence, a finalizer should never be used for tasks that are time-critical. Additionally, finalizers come with severe performance penalties and significantly increase the time it takes for objects to be deallocated, so their use is discouraged and deprecated in Java 9.try-catch-finally construct. Alternatively, the try-with-resources construct, which was introduced in Java 7, should be used in preference to try-finally construct. The try-with-resources construct is more concise and readable. It also provide more helpful diagnostic information, since suppressed exception are not discarded, and will be printed in the stack trace with information saying that they were suppressed.java.lang.OutOfMemoryError, but this rarely happens. The solution to this is to null out object references. A second common reason for memory leak is the use of cache that has become no longer relevant. The solution to memory leaks due to using old cache is to represent the cache using a java.util.WeakHashMap.
| 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. |
std::vector, std::unordered_map, std::deque) to help avoid such errors. In Java, low level errors either cannot occur or are detected by the Java virtual machine (JVM) and reported to the application in the form of an exception.
typeid() which may throw a std::bad_typeid exception, new which may throw std::bad_alloc or std::bad_array_new_length, new which may throw std::bad_alloc, or dynamic_cast which may throw std::bad_cast). Furthermore, in C++, exceptions may be "disabled" (such as with -no-exceptions on GCC or Clang, or /Ehsc on MSVC), which will prevent the compiler from generating code for exception handling, and terminate a program with std::terminate() upon a throw statement.catch block, and can only be allowed to propagate through functions that explicitly declare them with a throws clause. Any exception which does not extend java.lang.RuntimeException is considered a checked exception. Meanwhile, in C++, the concept of "checked exceptions" does not exist, but functions may be specified not to throw with a noexcept specifier. Until C++17 (though first deprecated in C++11), C++ allowed dynamic exception specifications through a throw clause in the function signature, which like Java throws clauses, allowed functions to specify which types may be thrown.java.lang.Throwable to be thrown by a throw statement. In C++, any object, including primitives, may be thrown and caught. Java differentiates between java.lang.Error (representing runtime errors considered unreasonable to catch) and java.lang.Exception (representing possible recoverable errors considered reasonable to catch) while in C++, the usual base exception class is std::exception.std::vector<T>, however, offer optional bounds checking. In summary, Java arrays (T[]) are "usually safe; slightly constrained; often have overhead" while C++ native arrays "have optional overhead; are slightly unconstrained; are possibly unsafe." Java collections like java.util.ArrayList can throw exceptions like java.lang.IndexOutOfBoundsException. C++26 specifies compile-time "bounds hardening" in the standard library, which now define certain undefined behaviors (including out-of-bounds access) to be contract violations.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 quite different.
| C++ Templates | Java Generics |
|---|---|
| Classes, functions, aliases and variables can be templated. | Classes and methods can be genericized. |
| Parameters can be variadic, of any type, integral value, character literal, or a class template. | Parameters can be any reference type, including boxed primitive types (i.e. java.lang.Integer, java.lang.Boolean, etc.). |
| 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 (via 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 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 compiling of some 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. Pre-C++11, this was allowed only for template classes, not functions. | Generic type parameters cannot have default arguments. |
Wildcards unsupported. 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.) Note that C++20 introduces concept which can represent named type restrictions with auto, while general constraints can be represented with requires clauses, similar to wildcards. |
Wildcards supported as type parameter. |
Bounding of type parameters possible using concepts (such as std::derived_from<A, B>); otherwise possible using template metaprogramming in prior versions |
Supports bounding of type parameters with A extends B and A super B 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. | Precludes instantiation of an object with the type of the parameter type (except via 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 unshared between classes and functions of different type parameters. | Static variables shared between instances of classes of different type parameters. |
| Class and function templates do not necessarily enforce type relations for type parameters in their declaration. Use of an incorrect type parameter results in compiling 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 added effort. Since C++20, concepts can be used to provide these features. | 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 also Turing-complete |
java.util.concurrent.ExecutorService, which runs on an operating system multi-threading. For non-blocking I/O, Java offers java.nio.async keyword):
co_await: suspends execution until resumed, analogous to await in other languagesco_yield: suspends execution, returning a value, analogous to yield in other languages' generatorsco_return: completes execution, returning a valuestd::execution library, which is a lazy, composable, zero-overhead framework, while Java's java.util.concurrent.ExecutorService is an eager runtime. Java yields the execution control to the internal task queue, while C++ only starts execution when a receiver connects to a sender and calls start().
std::execution::scheduler<Sch> is an execution engine, analogous to Java's java.util.concurrent.ExecutorService.std::execution::sender<Snd> is an async pipeline, analogous to Java's java.util.concurrent.CompletableFuture.std::execution::receiver<Rcv> is a callback/sink, analogous to Java's internal completion handlers/lambdas.std::execution::task<T, Env>, which represents a unit of asynchronous work, and is a sender that is often used as a coroutine's return type to be co_awaited; Java avoids the need for a task type by using virtual threads, avoiding separating synchronous and asynchronous code entirely.std::async() (introduced in C++11), which receives a unit of work (a lambda) and returns a std::future<T> as a receipt, similar to Java's ExecutorService.submit() which returned a java.util.concurrent.Future.export are accessible after importing a module.import in C++ imports a module by loading its BMI (built module interface) at compilation, however in C++, modules do not dictate the namespace which a symbol belongs to. Meanwhile, import in Java is used to alias classes to avoid fully qualifying them (equivalent to using in C++), and does not "import" definitions during compiilation. This is because all classes are handled as needed during runtime by the Java class loader on demand, and can be used even without an import statement by fully qualifying the class.-3/2 will always be -1 in Java and C++11, but a C++03 compiler may return either -1 or -2, depending on the platform. C99 defines division in the same fashion as Java and C++11. Both languages guarantee (where a and b are integer types) that (a / b) * b + (a % b) == a for all a and b (b non-zero). The C++03 version will sometimes be faster, as it is allowed to pick whichever truncation mode is native to the processor.int is 32-bit, long is 64-bit), while in C++ the size of integers and pointers is compiler and application binary interface (ABI) dependent within given constraints. Thus a Java program will have consistent behavior across platforms, whereas a C++ program may require adapting for some platforms, but may run faster with more natural integer sizes for the local platform. However, C/C++ also have fixed width sizes (such as int32_t for signed 32-bit integers, uint64_t for unsigned 64-bit integers, etc.)This section needs more citations. (September 2010) |
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 |
|---|---|---|
a[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. Given the very different natures of the languages, definitive qualitative differences are also difficult to draw. In a nutshell, there are inherent inefficiencies and hard limits on optimizing 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. In any case, if the inefficiencies of Java are too great, compiled C or C++ code can be called from Java via the JNI.
Some inefficiencies that are inherent to the Java language include, mainly:
sun.misc.Unsafe to gain access to manual resource management and be able to do stack allocation; effectively manipulating pseudo-pointers.However, there are a number of benefits to Java's design, some realized, some only theorized:
std::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.Also, some performance problems occur in C++:
The C++ language is defined by ISO/IEC 14882, an ISO standard, which is published by the ISO/IEC JTC1/SC22/WG21 committee. C++ typically releases on a three-year cycle.
The C++ language evolves via 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, a book which is published by Oracle. Java typically releases on a semiannual cycle, though traditionally released once every two years.
The Java language continuously evolves via 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—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 conservatism in the addition of new language and library features. In contrast, the 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.[citation needed]
"C++" is not a trademark of any company or organization and is not owned by any individual. "Java" is a trademark of Oracle.
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.
Unlike some other languages, Java does not allow programmers to choose pass-by-value or pass-by-reference—all arguments are passed by value. A method call can pass two types of values to a method—copies 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.
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; 318 kB
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.