This is the second half of the two-part series on the syntactic comparison of Java and C/C++. Before we begin, I’d like to encourage you to read its first part if by any chance you’ve missed it. It is called “Syntactic Comparison of Java and C/C++” and it’s published right here. You shouldn’t miss it because grasping the basics is crucial.
In my previous article I mentioned that the developers of Java constantly focused on portability (being able to run the code on various platforms). C and C++ are programming languages that allow heavy usage of preprocessors. A preprocessor changes the mechanism of how a program runs; it defines constants, includes additional source files (header files), specifies compilation particulars, and so forth.
Preprocessors are certainly very useful and any C-coder knows that. However, they can be a source of many problems, especially when considering portability. You may be faced with a #define that changes a variable throughout the whole source code, for example, or an #include that adds header files that are required, leaving you with problems if they aren’t reachable, and many other issues.
Therefore, there are absolutely no preprocessors in Java. Developers considered them to be a hit on cross-platform (and -compiler) portability and thus implemented other workarounds. In Java you do not #include a header file to gain access to its constants and functions, because you import what you need.
Imports fold the required constants, functions, etc. into your code instead of the header files as a whole. Should you need to define a constant as you did “#define A 50” in C, you approach the situation differently in Java. There is a Globals class (in Java everything is inside classes, remember?) that holds your public constants and static methods. In that class you’d write: “public static final int A = 50;” (without the quotation marks).
Since there are no preprocessors the usage of #if and #ifdef isn’t allowed either. Conditional compiling is most often used for cross-platform portability and thus isn’t required in Java, but it can be used for debugging or to create particular interfaces for specific platforms. It works a tad bit differently and so it is beyond this article’s scope.
I’ve recently mentioned constants. In Java each variable that’s declared finalis a constant. Let’s consider the following example. We’re going to define Pi as: “public static double PI = 3.14159;”. This type of declaration does not prevent changing its value. Literally we could change its value to 1000. Needless to say, we want a constant and that’s why we’re going to declare Pi as: “public static final double PI = 3.14159;”.
Speaking of Pi we shouldn’t forget that it’s already declared in the java.lang.Math class. By importing that class you will be allowed to use it throughout your code as Math.PI, not necessarily typing its whole name. Allowing shorter names is a really useful feature.
Moving on… another deviation from good old C and C++ is related to goto. In Java goto isn’t allowed. However, it is a reserved name but it is not implemented. The workaround to unconditional jumps is using labeled breaks and continues. The aforementioned two work exactly as they do in C/C++ but additionally you can link them with labels. For example: “break label1;” or “continue label2;”.
Java is a multithreading programming language. Consequently, it has a feature that can be used to prevent simultaneous access to a particular “crucial block of code” from multiple threads; it maintains memory consistency. The keyword is synchronized. Don’t forget that constructors cannot be synchronized (you'd get a syntax error) because it’d be worthless; a constructor is accessed only by the single thread that created it.