Content deleted Content added
m →Syntax: {{nowrap}} |
|||
(27 intermediate revisions by 11 users not shown) | |||
Line 8:
{{ProgLangCompare}}
[[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 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
|-
| [[Write once, compile anywhere]] (WOCA).
Line 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]]
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
|-
| 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 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 179 ⟶ 180:
|-
| <syntaxhighlight lang="cpp">
std::
// outputs 0, because b is
// some object other than a
</syntaxhighlight>
| <syntaxhighlight lang="java">
Line 234 ⟶ 232:
|-
| <syntaxhighlight lang="cpp">
std::
// outputs 5, because d references the
// same object to which c points
</syntaxhighlight>
| <syntaxhighlight lang="java">
Line 287 ⟶ 282:
|}
* C++ supports <code>[[goto]]</code> 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 [[Control flow#Early exit from loops|break and continue]] statements to provide some <code>goto</code>-like functions. Some commenters point out that these labelled flow control statements break the single point-of-exit property of structured programming.<ref name="Martin">{{cite web|url=http://www.objectmentor.com/resources/articles/javacpp.pdf|title=Java vs. C++: A Critical Comparison|date=January 1997|author=Robert C. Martin|access-date=15 December 2007|archive-url=https://web.archive.org/web/20080511205821/http://www.objectmentor.com/resources/articles/javacpp.pdf|archive-date=11 May 2008|url-status=dead}}</ref>
* C++ provides low-level features which Java mostly lacks (one notable exception being the <code>sun.misc.Unsafe</code> 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]]. Assembly language code can be imported to a C/C++ program and vice versa. This makes C/C++ language even faster. 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.
=== Semantics ===
* C++ allows default values for arguments of a function/method. Java does not. However, [[method overloading]] can be used to obtain similar results in Java but generate redundant stub code.
* The minimum of code needed to compile for C++ is a function, for Java is a class. However, since Java 21 with the introduction of the unnamed class, it is possible to write a Java program consisting only of a main function.
* C++ allows a range of implicit conversions between native types (including some narrowing conversions), and also allows defining implicit conversions involving user-defined types. In Java, only widening conversions between native types are implicit; other conversions require explicit cast syntax.
** A result of this is that although loop conditions (<code>if</code>, <code>while</code> and the exit condition in <code>for</code>) in Java and C++ both expect a boolean expression, code such as <code>if(a = 5)</code> 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 <code>if(a == 5)</code> 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. <code>a==5;</code>, without a side effect usually lead to a warning.
Line 311 ⟶ 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.
* 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 323 ⟶ 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 394 ⟶ 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, [[Modules (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
** 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 <
* 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 [[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>using</code> in C++). This is because all classes are handled as needed during runtime by the [[Java class loader]] on demand, and 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.
|