Comparison of Java and C++: Difference between revisions

Content deleted Content added
 
(21 intermediate revisions by 9 users not shown)
Line 7:
{{Use dmy dates|date=January 2021}}
{{ProgLangCompare}}
{{merge to|Comparison of programming languages|discuss=Talk:Comparison of programming languages#Merge proposal|date=February 2025}}
 
[[Java (programming language)|Java]] and [[C++]] are two prominent [[Object-oriented programming|object-oriented]] [[programming language]]s. 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 [[Java (software platform)#History|was based on C/C++]].
 
== Design aims ==
Line 28 ⟶ 27:
|-
| Compatible with [[C (programming language)|C]] source code, except for a few [[corner case]]s.
| Provides the [[Java Native Interface]] as well as [[Java Native Access]] and more recently [[Java Native AccessInterface#Foreign Function and Memory API|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.{{sfn|Bloch|2018|loc=Chapter §11 Item 66: Use native methods judiciously|p=285}} 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.{{sfn|Bloch|2018|loc=Chapter §11 Item 66: Use native methods judiciously|p=285}}
|-
| [[Write once, compile anywhere]] (WOCA).
Line 61 ⟶ 60:
|-
| [[Resource management (computing)|Resource management]] can be done manually or by automatic lifetime-based resource management ([[Resource Acquisition Is Initialization|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 <code>sun.misc.Unsafe</code> 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 [[Dynamic memory allocation|heap]] or the [[Stack-based memory allocation|stack]].
| Classes are allocated on the [[Dynamic memory allocation|heap]]. [[Java version history#Java SE 6|Java SE 6]] optimizes with [[escape analysis]] to allocate some objects on the [[Stack-based memory allocation|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, [[Iterator#C++|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 (C++ libraries)|Boost library]] offersand more[[POCO functionsC++ includingLibraries]] networkoffer more I/Oabilities.
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,<ref name="XMPP Software » Libraries">{{cite web|title=XMPP Software » Libraries|url=http://xmpp.org/xmpp-software/libraries/|publisher=xmpp.org|access-date=13 June 2013}}</ref> [[OpenLDAP]], [[Qt (software)|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 (protocol)|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 <code>String</code> class.
|-
| Single and [[multiple inheritance]] of classes, including virtual inheritance.
| Only supports single inheritance of classes,{{sfn|Bloch|2018|loc=Foreword|pp=xi-xii}}, however interfaces may multiply extend other interfaces and classes may implement multiple interfaces.
|-
| Compile-time templates. Allows for [[Turing complete]] meta-programming.
| [[Generics in Java|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 (<code>Object</code> if no such bound exists, otherwise <code>? extends T</code> is casted to <code>T</code>).
|-
| Function pointers, function objects, lambdas (in [[C++11]]), and interfaces (using abstract classes).
| Functions references, function objects and lambdas were added in [[Java 8]]. Classes (and interfaces, which are classes) can be passed as references as well through <code>SomeClass.class</code> and <code>someObject.getClass()</code>.
|-
| No standard inline documentation mechanism. Third-party software (e.g. [[Doxygen]]) exists. Standard library vendors may provide documentation comments, though it is not guaranteed.
| Extensive [[Javadoc]] documentation standard on all system classes and methods.
|-
Line 114 ⟶ 113:
| <syntaxhighlight lang="cpp">
class Foo { // Declares class Foo
private:
int x = 0; // Private Member variable. It will
// be initialized to 0, if the
Line 306:
* Java has both language and standard library support for [[Thread (computer science)|multi-threading]]. The <code>synchronized</code> [[Java keywords|keyword in Java]] provides [[mutual exclusion|mutex locks]] to support multi-threaded applications.{{sfn|Goetz|Peierls|Bloch|Bowbeer|2006|loc=§2.3.1 Intrinsic locks|pp=25-26}}{{sfn|Bloch|2018|loc=Chapter §11 Item 78: Synchronize access to shared mutable data|pp=126-129}} 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. There are also many third-party libraries for this.
* C++ member functions can be declared as [[virtual function]]s, which means the method to be called is determined by the run-time type of the object (a.k.a. dynamic dispatching). By default, methods in C++ are not virtual (i.e., ''opt-in virtual''). In Java, methods are virtual by default, but can be made non-virtual by using the <code>[[final (Java)|final]]</code> keyword (i.e., ''opt-out virtual'').
* C and C++ enumerations are primitive types. andC enumerations (<code>enum</code>) support implicit conversion to integer types (but not from integer types), while C++ enumerations (<code>enum class</code>) do not. Java enumerations can be {{code|public static enum { enumName1, enumName2 }|java}} and are used like classes. Another way is to make another class that extends <code>java.lang.Enum<E></code>) and may therefore define constructors, fields, and methods as any other class. As of [[C++11]], C++ supports [[C++11#Strongly typed enumerations|strongly-typed enumerations]] which provide more type-safety and explicit specification of the storage type.
* Unary operators {{code|++}} and {{code|--}}: in C++ "The operand shall be a modifiable [[Value (computer science)|lvalue]]. [skipped] The result is the updated operand; it is an lvalue...",<ref>Standard for Programming Language C++ '11, 5.3.2 Increment and decrement [expr.pre.incr].</ref> 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.",<ref>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/</ref> i.e. in Java, after the initialization {{code|1=Integer i=2; ++i;|2=java}} changes the reference {{code|i}} by assigning new object, while in C++ the object is still the same.
 
Line 318:
** In C++, it is possible to have a [[dangling pointer]], a stale [[Reference (computer science)|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.
** In C++, it is possible to have uninitialized primitive objects. Java enforces default initialization.
** In C++, it is possible to have an allocated object to which there is no valid reference. Such an [[unreachable object]] cannot be destroyed (deallocated), and results in a [[memory leak]]. In contrast, in Java an object will not be deallocated by the garbage collector ''until'' it becomes unreachable (by the user program). (''[[Weak reference]]s'' are supported, which work with the Java garbage collector to allow for different ''strengths'' of reachability.) Garbage collection in Java prevents many memory leaks, but leaks are still possible under some circumstances.<ref>{{cite web|url=http://www-128.ibm.com/developerworks/rational/library/05/0816_GuptaPalanki/ |title=Java memory leaks – Catch me if you can |author1=Satish Chandra Gupta |author2=Rajeev Palanki |publisher=IBM DeveloperWorks |date=16 August 2005 |access-date=2015-04-02|archive-url=https://web.archive.org/web/20120722095536/http://www.ibm.com/developerworks/rational/library/05/0816_GuptaPalanki/ |archive-date=2012-07-22}}</ref><ref>[https://web.archive.org/web/20140205030750/http://www.openlogic.com/wazi/bid/188158 How to Fix Memory Leaks in Java] by Veljko Krunic (10 Mar 2009)</ref><ref>[https://stackoverflow.com/questions/6470651/creating-a-memory-leak-with-java Creating a memory leak with Java] on [[stackoverflow]].com</ref> The automatic garbage collector may give the false impression that in Java one does not need to think about memory management.{{sfn|Bloch|2018|loc=Chapter §2 Item 7: Eliminate obsolete references|pp=123-125}} However this is not quite true.{{sfn|Bloch|2018|loc=Chapter §2 Item 7: Eliminate obsolete references|pp=123-125}} Loosely speaking, this is because a program can have "memory leaks", more formally known as "unintentional object retentions".{{sfn|Bloch|2018|loc=Chapter §2 Item 7: Eliminate obsolete references|pp=123-125}} An example of a memory leak that may occur is for a program that has been written without any logical errors, except that it did not eliminate obsolete references.{{sfn|Bloch|2018|loc=Chapter §2 Item 7: Eliminate obsolete references|pp=123-125}} This results in higher use of garbage collector activity, higher [[memory footprint]].{{sfn|Bloch|2018|loc=Chapter §2 Item 7: Eliminate obsolete references|pp=123-125}} In extreme circumstances, this problem can lead to an <code>OutOfMemoryError</code>, but this rarely happens.
{{sfn|Bloch|2018|loc=Chapter §2 Item 7: Eliminate obsolete references|pp=123-125}} The solution to this is to null out object references. {{sfn|Bloch|2018|loc=Chapter §2 Item 7: Eliminate obsolete references|pp=123-125}} 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 <code>WeakHashMap</code>.
 
=== Libraries ===
* C++ provides [[cross-platform]] access to many features typically available in platform-specific libraries. Direct access from Java to native operating system and hardware functions requires the use of the [[Java Native Interface]], or since Java 21, the Foreign Function and Memory API, which allow for allocating and managing memory outside of the Java Virtual Machine, as well as calling native (i.e. C/C++) functions.
* The [[C++ standard library]] is designed to be minimalistic, providing only a standardised set of general use features, while the [[Java Class Library]] and [[Java Platform Module System]] (the Java standard library) is much more extensive, providing a much larger comprehensive standardised set of features, such as graphics, UI creation, and more.
 
=== Runtime ===
Line 389 ⟶ 390:
* Java and C++ use different means to divide code into multiple source files.
** Java uses a [[Java package|package system]] that dictates the file name and path for all program definitions. Its compiler imports the executable [[class (file format)|class files]].
** Prior to [[C++20]], C++ used a [[header file]] [[source code]] inclusion system to share declarations between source files. Since C++20, however, [[precompiledModules header#Module(C++)|modules]] were introduced offering similar functionality to Java packages, however C++ modules do not have the same granularity of Java packages which allowing for importing individual functions or classes - rather, in C++, only all symbols marked <code>export</code> are accessible after importing a module., making it akin to a wildcard import in Java.
** Since [[C++23]], the C++ standard library can now be imported as a module, but must be imported in its entirety rather than importing specific packages of the library like in Java, with <code>import std;</code>, or optionally if requiring thesyntaxhighlight lang="C++" standard library in the global scope, with <codeinline>import std.compat;</codesyntaxhighlight>. This may change in the future, with proposals to separate the standard library into more modules such as <code>std.fundamentalcore</code>, <code>std.math</code>, and <code>std.io</code>.<ref name="P0581R1">C++ Standards Committee. (2018). ''P0581R1 - Modules for C++''. Retrieved from [https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0581r1.pdf https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0581r1.pdf]</ref><ref name="P2412R0">C++ Standards Committee. (2021). ''P2412R0 - Further refinements to the C++ Modules Design''. Retrieved from [https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2412r0.pdf https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2412r0.pdf]</ref>
* The term "[[modular programming|module]]" refers to different things. In Java, a [[Java package#Modules|module]] is used to group several packages together, meanwhile in C++ a [[precompiled header#Modules (C++)|module]] represents a single [[translation unit]] that is declared as a module.
** <code>import</code> in C++ imports a module by linking it at compilation, however in C++, modules do not dictate the namespace which a symbol belongs to. Meanwhile, <code>import</code> in Java does not actually "import" any code into a file, and is used to alias classes to avoid fully qualifying them. (more similar to <code>importusing</code> in C++). importsThis ais module,because howeverall inclasses C++,are moduleshandled doas notneeded dictateduring runtime by the namespace[[Java whichclass aloader]] symbolon belongsdemand, toand can be invoked even without "importing", simply by fully qualifying the class.
* A Java source file must match the namespace which of the public class it declares (it may be named anything if there are no public classes), and the package it belongs to must match the path it is located in. A package may only declare at most one public class (but may have multiple non-public classes).
* A C++ source file (whether a header or module) may have any arbitrary name, and may contain as many classes as the programmer desires. Modules have no requirement to match the path of its ___location.
* Compiled Java code files are generally smaller than code files in C++ as [[Java bytecode]] is usually more compact than native [[machine code]] and Java programs are never statically linked.
* C++ compiling features an added textual [[preprocessor|preprocessing]] phase, while Java does not. Thus some users add a preprocessing phase to their build process for better support of conditional compiling.