1. Main method
- In Java all functions are methods of some class, so there must be a shell class for the main method.
- Unlike C/C++, Java’s main method does not return an “exit code” to the operating system.
public class ClassName { public static void main(String[] args) { // program statements } }
2. Data Types
Strongly typed language
Java is a strongly typed language, which means every variable must have a declared type.
2.1. Numerical Types
- Integer types: Numbers without fractional parts
- Floating-Point types: Numbers with fractional parts
Unsigned integer type
Java DOES NOT have any unsigned versions of the int, long, short,or byte types.
Type | Size | Range | Example |
---|---|---|---|
byte | 1 byte | -128 to 127 | 123 |
short | 2 bytes | -32,768 to 32,767 | 12345 |
int | 4 bytes | -2,147,483,648 to 2,147,483,647 | 1234567 |
long | 8 bytes | -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 | 4000000000l, 4000000000L |
float | 4 bytes | Stores fractional numbers. Sufficient for storing 6 to 7 decimal digits | 3.14f, 3.14F |
double | 8 bytes | Stores fractional numbers. Sufficient for storing 15 decimal digits | 3.14d, 3.14D |
boolean | 1 bit | Stores true or false values | true, false |
char | 2 bytes | Stores a single character/letter or ASCII values |
Double
The name double refers to the fact that these numbers have twice the precision of the float type. (Some people call these double-precision numbers.)
Char & Unicode
In Java, the char type describes a code unit in the UTF-16 encoding.
Roundoff error
Issue: Floating-point numbers are not suitable for financial calculations in which roundoff errors cannot be tolerated. For example, the command System.out.println(2.0 - 1.1)
prints 0.8999999999999999
, not 0.9
as you would expect.
Root cause: Such roundoff errors are caused by the fact that floating-point numbers are represented in the binary number system. There is no precise binary representation of the fraction 1/10, just as there is no accurate representation of the fraction 1/3 in the decimal system.
Solution: Use the BigDecimal class
Machine independent
In Java, the ranges of the integer types do not depend on the machine on which you will be running the Java code. This is different from C/C++.
\u
for Code Escape
Unicode escape sequences are processed before the code is parsed. See examples below
public static void main(String\u005B\u005D args) // Legal. \u005B and \u005D are the encodings for [ and ]
"\u0022+\u0022" // The \u0022 are converted into " before parsing, yielding ""+""
3. Variables and Constants
- Variable: objects used to store values
- Constants: variables whose values don’t change
3.1. Variables
Variable naming facts
- Case sensitive:
hireday
andhireDay
are two different names - Even though $ is a valid Java letter, you should not use it in your own code. It is intended for names that are generated by the Java compiler and other tools.
var: auto type inferring
Starting with Java 10, you do not need to declare the types of local variables if they can be inferred from the initial value. Simply use the keyword var instead of the type:
var vacationDays = 12; // vacationDays is an int
var greeting = "Hello"; // greeting is a String
3.2. Constants
In Java, the keyword final
is used to denote a constant. It indicates that you can only assign to the variable once, and then its value is set once and for all.
final double CM_PER_INCH = 2.54;
4. Enumerated Types
Used when a variable should only hold a restricted set of values.
enum Size { SMALL, MEDIUM, LARGE, EXTRA_LARGE };
Size s = Size.MEDIUM;
== vs equals()
Testing equality of an enum value with equals is perfectly valid because an enum is an Object and every Java developer knows “==” should not be used to compare the content of an Object. At the same time, using “==” on enums:
- provides the same expected comparison (content) as equals
- is more null-safe than equals()
- provides compile-time (static) checking rather than runtime checking
For these reasons, use of “==” should be preferred to equals.
5. Operators
Operators are used to combine values.
5.1. Type conversion & Casts
- Widening: Conversions will not cause information loss.
- Narrowing: Conversions may lose precision. It’s possible by means of casts.
// Cast
double x = 9.997;
int y = (int) x; // y = 9, because casting a floating-point value to an integer discards the fractional part
int z = (int) Math.round(x); // z = 10 as Math.round will round a floating-point number to the nearest integer
What if casting is out of range…
If you try to cast a number of one type to another that is out of range for the target type, the result will be a truncated number that has a different value.
For example, (byte) 300
is actually 44
.
Cast Boolean? No way
You cannot cast between boolean values and any numeric type. This convention prevents common errors. In the rare case when you want to convert a boolean value to a number, you can use a conditional expression such as b ? 1 : 0.
5.2. Bitwise Operators
>>
: extends the sign bit into the top bits>>>
: fills the top bits with zero
Right shift in C/C++
In C/C++, there is no guarantee as to whether >> performs an arithmetic shift (extending the sign bit) or a logical shift (filling in with zeroes). Implementors are free to choose whichever is more efficient. That means the C/C++ >> operator may yield implementation-dependent results for negative numbers. Java removes that uncertainty.
6. Strings
Facts about Java string:
- Java strings are sequences of Unicode characters. For example,
Java\u2122
=J
+a
+v
+a
+™
. - Java does not have a built-in string type. Instead, the standard Java library contains a predefined class called, naturally enough, String.
- Strings are immutable - cannot change the individual characters in a Java string
Immutable Strings
Immutable strings have one great advantage: the compiler can arrange that strings are shared.
A proper analogy to C++ is - a Java string is roughly analogous to a char* pointer rather than an array of characters
// char greeting[] = "Hello"; // No
char* greeting = "Hello"; // Yes
When you replace greeting with another string, i.e. greeting = greeting.substring(0, 3) + "p!"
the Java code does roughly the following:
char* temp = malloc(6);
strncpy(temp, greeting, 3);
strncpy(temp + 3, "p!", 3);
greeting = temp;
6.1. Operations
substring(a, b)
Copy the substring from position a to position b exclusive (position a to position b - 1 inclusive).The string s.substring(a, b) always has length b − a
String greeting = "Hello"; String s = greeting.substring(0, 3); // "Hel"
join(delimiter, strings…)
String all = String.join(" / ", "S", "M", "L", "XL"); // "S / M / L / XL"
equals
equals vs ==
DO NOT use the == operator to test whether two strings are equal! It only determines whether the strings are stored in the same location.
If the virtual machine always arranges for equal strings to be shared, then you could use the == operator for testing equality. But only string literals are shared, not strings that are the result of operations like + or substring.About C/C++:
- The C++ string class does overload the == operator to test for equality of the string contents.
- C programmers never use == to compare strings but use
strcmp
instead. The Java methodcompareTo
is the exact analog ofstrcmp
. You can useif (greeting.compareTo("Hello") == 0)
Empty and Null String
if (str != null && str.length() != 0) if (str != null && str.equals(""))
Concatenation (+)
Java allows you to use+
to join (concatenate) two strings.String expletive = "Expletive"; String PG13 = "deleted"; String message = expletive + PG13;
StringBuilder & StringBuffer
Every time you concatenate strings, a new String object is constructed. This is time-consuming and wastes memory.StringBuilder
is a better option introduced in Java 5.StringBuilder builder = new StringBuilder(); builder.append('A'); // appends a single character builder.append("pple"); // appends a string String completedString = builder.toString();
StringBuffer
isStringBuilder
‘s predecessor, but slower because it’s synchronized.
7. Arrays
Java VS C++
In Java, there is no pointer arithmetic — you can’t increment a to point to the next element in the array.
int[] a = new int[100]; // Java; Heap
int a[100]; // C++; Stack
int* a = new int[100]; // C++; Heap
Command-Line Parameters
The name of the program is not stored in the args array
public class Message {
public static void main(String[] args) {
if (args.length == 0 || args[0].equals("-h"))
System.out.print("Hello,");
else if (args[0].equals("-g"))
System.out.print("Goodbye,");
// print the other command-line arguments
for (int i = 1; i < args.length; i++)
System.out.print(" " + args[i]);
System.out.println("!");
}
}
// Run: java Message -g cruel world
// Output: Goodbye, cruel world!
7.1. Declaration & Initialization
Once you create an array, you cannot change its length
int[] a = new int[100];
int[] smallPrimes = { 2, 3, 5, 7, 11, 13 };
smallPrimes = new int[] { 17, 19, 23, 29, 31, 37 }; // anonymous
7.2. Copy
int[] luckyNumbers = Arrays.copyOf(smallPrimes, smallPrimes.length);
// Increase the size of an array
// The additional elements are filled with 0 if the array contains numbers, false if the array contains boolean values.
luckyNumbers = Arrays.copyOf(luckyNumbers, 2 * luckyNumbers.length);
7.3. Sorting
int[] a = new int[10000];
...
Arrays.sort(a) // Quick Sort
7.4. Multidimensional Array
Java has no multidimensional arrays at all, only one-dimensional arrays. Multidimensional arrays are faked as “arrays of arrays.”
The two are the same:
// Java
double[][] balances = new double[10][6];
// C++
double** balances = new double*[10];
for (i = 0; i < 10; i++)
balances[i] = new double[6];
for-each on multidimensional array
Use double[]
on the outer loop
for (double[] row : a)
for (double value : row)
do something with value
8. Reference
- Enum values should be compared with “==”: https://rules.sonarsource.com/java/RSPEC-4551