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