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++.

Design aims 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. Supports a non-deterministic java.lang.Object::finalize() method, use of which is not recommended.. 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 sun.misc.Unsafe but that usage is highly discouraged and will be replaced by a public API in an upcoming Java version. 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 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 ^^X (of type std::meta::info), which represents a type metadata. Functions references, function objects and lambdas were added in Java 8. Classes (and interfaces, which are classes) can be passed as references.

Java denotes a type metadata with X.class (of type java.lang.Class<X>) or X::getClass() (which returns java.lang.Class<?>). No standard inline documentation mechanism. Third-party software (e.g. Doxygen) exists. Standard library vendors may provide documentation comments, though it is not guaranteed. is often seen as the "premier public reference site" for C++ documentation. Extensive Javadoc documentation standard on all system classes and methods. Official documentation available at . 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.

Language features

Syntax

Java syntax has a context-free grammar that can be parsed by a simple LALR parser. Parsing C++ is more complicated. For example, is a sequence of comparisons if Foo is a variable, but creates an object if Foo is the name of a class template. C++ allows namespace-level constants, variables, and functions. In Java, such entities must belong to some given type, and therefore must be defined inside a type definition, either a class or an interface. In Java, all types belong to a namespace (Java package), and there is no such thing as a "global namespace" (even in compact source files where code seemingly does not reside in any class, such code belongs to a final top-level class in the unnamed package), unlike C++ where any code not part of a namespace is part of the global namespace. In Java, the "unnamed package" is not a global namespace, and classes in it cannot be imported by code in named packages. Java has a strict global inheritance tree such that all classes (implicitly) extend the top type, 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. In C++, objects are values, while in Java they are not. C++ uses value semantics by default, while Java always uses reference semantics. To opt for reference semantics in C++, either a pointer or a reference can be used.

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) {