Introduction
For a developer who wants to switch from one main programming language to another this might seem quite challenging (and depending on the concrete cases, it certainly can be) at first. Fortunately, many programming languages have a lot of commonalities since you won’t redevelop the wheel but rather reuse existing proven concepts from an older language.
This is especially the case, if you compare two programming languages where one serves as a basis of inspiration to the other. Java is such a language, where you find a lot of concepts/structures from C/C++; in several cases even the same.
However, when looking at things in detail, there are also cases where concepts seem to be the same at first glance, but have noticeable differences in detail.
This blog post showcases some of these differences and commonalities between Java and C/C++. The listing is far from being complete and just a subjective selection of items picked by the author which popped up while working through the ‘programming bible’ for Java developers: Java ist auch eine Insel [1].
Java and C++ – Commonalities and Differences
The following table depicts the language features of C/C++ and Java and is meant as a rough overview of noticeable differences and commonalities (in the opinion of the author). It is not meant as a summary for every developer (since what’s important in one’s opinion is obviously different from person to person).
Also it’s beyond the scope of this blog post to explain what each concept means. Therefore, we expect that the reader has a decent knowledge about C++ and we don’t mention anything if there are no important difference other than the name for the listing (f.e. auto in C++ vs. var in Java).
Beyond the author’s own experience/knowledge, the main source for looking details up were the already mentioned Java book as well as posts on Stackoverflow [2] and the cppreference.com-page [3].
Concept | C++ | Java |
auto | keyword: auto (new in C++11) | keyword: var (new in Java 10) |
const | keyword: const | keyword: final final is certainly not a full equivalent to C++’s const keyword. Since there’s no real ‘constness’ in Java, specifying a local variable (or method argument) as final still allows you to modify the object. Only the variable/argument itself cannot be changed (C++ equivalent: const int i = 0;). Note that in Java you can do a ‘delayed initialization’ of a final variable. As long as the variable is only initialized once, that’s still fine if you specify it as final. Example: final int a; […] a = 15 |
namespace | keyword: namespace | keyword: package |
using | keyword: using | keyword: import Java also allows to import static class methods/members, which is not possible in C++. Example: class Foo { public static void bar() {} } Then you can use the bar()-method in a different class simply like: import static [PACKAGE_NAME].Foo.bar; […] class Foo2 { public static void bar2() { bar(); } } |
enums | keyword: enum class/struct (new in C++11) static_cast must be used to convert to int. Normal (pre-C++11) enums are just ‘integers’ without ‘strict’ type safety. | keyword: enum Use Foo.ordinal() to convert to int. |
++/–/%/+=/-=/etc.-operators | These operators are only valid for integer types. | In contrast to C++ the prefix/suffix and modulo operators can also be used on float and double. The same goes for the +=/-=/etc. operators which can mix integer and floating point operands. Example: int i = 0; i += 20.4; // will result in i = 20 |
>>>-operator | n/A | Right-shift operator keeping the sign unchanged. |
size of char type | Usually 1 byte. However, the standard permits a different size, as long as sizeof(char) <= sizeof(short). | 2 bytes |
constant literal types | The type of an integer constant is the smallest type which can keep the integer value (beginning with type ‘int’). | Always int (use suffix-notation to enforce a different type like long) for integer types. Floating point constants are double by default (unless suffix is specified) -> same as with C++. |
byte (Java)/char/short type in operations | Types remain unchanged in operations. | Types are implicitly cast into int-types so that a + b results in an integer, even if a and b are of type short. Note: This even applies to the unary +/- operators! |
shadowing variables | Every variable (local, global, function arguments, or class/object member) can be shadowed. Recent compilers issue a warning though if this happens. | Only allows shadowing object/class members but not method arguments or local variables. |
switch-case-statement | All integer values plus bool and enums are allowed. | Allows int-values (not long though!), enums and strings. Provides extended switch-syntax (4 variants in total. (new in Java 12 / finalized in Java 14) |
break/continue | Valid inside loops – always applies to the inner most loop. | Supports syntax with labels to break out of or continue an outer loop. Break also supported to break out of any block. |
range-based-for loop | available (new in C++11) | Available with same syntax as in C++. |
class/object members and array initialization | Not initialized by default. | Initialized by default with 0/null/false. But: Local variables are NOT initialized by default (same as with C++). |
function parameter evaluation order | right-to-left | left-to-right! |
printf-format string | Current compilers usually validate the format string and passed in arguments at compile time and issue warnings. Note: There is however no runtime check to ensure that passed in arguments match the specified type! Arguments and format specifiers are always mapped one-to-one. There is no way to specify one argument and use it for two format specifiers. | Format specifiers are always checked with their passed in argument at runtime. Note: The compiler won’t issue a warning! Favor %n as new line in format string over \n, since the later won’t be converted to a platform specific line ending. Note: This is different from C++! Further note that %n has an entirely different meaning in C++! Using ‘$x’ (f.e. in ‘%$1f’) allows explicitly specifying a different argument to be used. Using ‘$<‘ specifies that the same argument as used for the previous format specifier is to be used again. |
varargs | varargs of different types are supported. Using special va_list-handling to access and the arguments. | varargs must be of a single type. For example: void foo(double… bar) Simple access to varargs like array access. Can also be passed in an array instead of multiple arguments. |
arrays | Arrays are not objects (in C++11: alternative array class added). Multi-dimensional arrays always have the same size for each dimension. No hard limit for number of elements. | Arrays are objects. Rectangular multi-dimensional arrays supported. For example: int[][] = new int[][]{{1}, {1, 2, 3, 4}, {1, 2}} Results in a multi-dimensional array where the first dimension has 3 elements and the second has varying elements: 1, 4, 2. Hard limit of 2^31 elements within a single dimension. |
main()-function | First argument is the command line used to call the program. Exit code directly through return value. | First argument is the first argument passed in in the command line. No return value. Instead use System.exit(), if exit code must be returned. |
strings | String class is mutable. No hard size limit for strings. | String class is immutable. -> Results in overhead when ‘adjusting’ the string (since new String objects get constructed). Use StringBuffer (thread-safe)/StringBuilder if string needs to be mutable. Hard limit at 2^31 characters. |
class visibility | No class visibility of outer classes. You can define a class within a cpp-file to make it kind of ‘private’ (to the single compilation unit). protected methods/members: only visible in same or derived classes | Classes have their own visibility: public/package Inner classes can also have private/protected visibility. protected methods/members: visible to same class, derived classes or other classes in the same package. Note: There is no visibility to restrict members to (the own and) derived class only! |
default visibility | members/methods/constructors/destructor: private for classes, public for structs | members/methods/classes: package visibility (class/method/member visible in the same package) constructors: same visibility as the class visibility Note: There’s no corresponding C++ construct for package visibility. |
default constructor | default constructor dropped, once first custom constructor defined | same as in C++ |
constructor chaining | n/A | Inside a constructor call: this(xxx, xxx, …) to call a different constructor. Call must be the first line in a constructor. |
class initializers | concept: initialize class members in single cpp-file directly | use static{}-block |
nullptr type deduction | Requires explicit type-cast of nullptr, if casting is ambiguous. F.e. class Foo {}; class Foo2 : Foo { void test(Foo*) {} void test(Foo2*) {} } void main() { test(nullptr); // compile error – could be Foo* or Foo2* } | Type deduced for a null pointer based on the context. If either passed in as an argument of a ctor or as an argument for a reference, null type is deducted to the lowest sub class. F.e. class Foo {}; class Foo2 extends Foo { void test(Foo f) {} void test(Foo2 f) {} }; class Foo3 { void main() { Foo2 f = new Foo2(); f.test(null); // will deduce null to Foo2 -> calls test(Foo2 f) } } |
function range notation convention | usually functions taking a start and end range notation are defined as: [start, end] – aka: start and end element is included in the range | usually functions taking a start and end range notation are defined: [begin, end) – aka: start element included but end element not included For example: java.util.Array.sort(a, 0, 2) -> sorts array a from 0 to 1 (since 2 is exclusive) |
References
[1] – book: “Java ist auch eine Insel, 15. aktualisierte und überarbeitete Auflage” – 2020 (1. Nachdruck 2020) – Author: Christian Ullenboom – Distributor: Rheinwerk Computing (Germany) – ISBN: 978-3-8362-7737-2
[2] – https://stackoverflow.com/
[3] – https://en.cppreference.com/
Updates
2021-09-15: Added enums and strings as switch-case-aruments to Java (and for consistency also added enums to C++, even though these are practically integer values).
2021-09-20: Added following new entries:
- class initializers
- class visibility
- constructor chaining
- default constructor
- default visibility
- enum
- nullptr type deduction
- shadowing variables