Ben Chuanlong Du's Blog

It is never too late to learn.

Misc Tips on Java

Tips and Traps

  1. Use == (instead of the method Object.equals) to compare objects is a common and tricky mistake for beginner.

  2. You cannot define an abstract static method. This is because "abstract" means that no functionality is implemented while "static" means that functionality exists even there is no object. The two conflict in concept.

  3. Currently there is no way to make subclass level access but no package level access in Java.

  4. If there is broken references (e.g. a imported jar file has been deleted or moved to another place), eclipse cannot build proejects. When you run code, you will probably get error message that some class does not exist.

  5. The hasNextInt() method of Scanner class test whether the next parsed word is integer or not. Even if there is integer in the string the method returns false if it is not the first parsed word.

  6. When a double number is casted to an integer, only the integer part is kept, i.e. the number will be rounded towards 0. When we use method Math.round(), we get the same result. However, the first method is preferred, though it uses cast. Usually this kind of type cast is very fast.

  7. There is no power operator in Java, instead, the method Math.power should be used. If you want the square or cubic of a number [] x, you can use x * x or x * x * x, which is faster than invoking the Math.power.

  8. In Java (and also C++), you can access the instance variables of objects with the same class in the definition of a class.

  9. When a return a result in method using key word return, the parentheses are not required.

  10. Unlike C/C++, we can only give if statement a boolean expression in Java, which means that if(x=2) (which works in C/C++) will not work in Java.

  11. In C/C++, we can convert integer values to boolean values, vice versa. While in Java, we cannot do this.

  12. To quit a program when error occurs in Java, we can use System.err.println(). This will print out the error message and then quit the running program. !!!!!!!!!!! It will not stop running, just print error message.

  13. We can not call a non-static method inside a static method. So all methods in the class which contains function main (the start place of all code) should be static. Similarly all instance variable in this kind of classes must be static and (usually final).

  14. Be careful when you use switch in Java. Do not forget to add code break; at the end of each branch.

  15. Do not use == to check whether two objects are equal or not, instead, use method equals.

  16. By default, the elements of an array of objects in Java have value null. So we must either instantiate the elements or point them to objects with the same type.

  17. The index of arrays in Java must start from 0, however, it does not have to be a regular array, i.e. the elements of the array do not have to have the same length.

  18. We know that many programming languages use lazy evaluation to evaluate boolean expressions. However, sometimes we might want to evaluate all conditions of an expression, which is mainly for side effect and parallelism maintain concern.

  19. In java, "\r" stands for return (i.e. put the cursor to the first column) and "\n" stand for new line, which is different from some programming languages. For example, some programming language use "\n" to stand for return and new line.

  20. When overriding an existing method in a class, you must provide different arguments for the overriding method. This is because the name of a method and the number and type of arguments is how Java can distinguish different methods. Notice that before executing a method, Java does not know the type of return result, which means that the return type of methods is not used to distinguish different methods. For this reason, we cannot define two methods with the same name and the same number and type of arguments with different return types. And when we overwrite a method in a super class, we must keep the same return type or a return type that is compatible with the return type of the corresponding method in the super class.

  21. There can be both public and static method in a class in Java. To call a public class, you must invoke a public method through an object of the class; to call a static method, you can either invoke it through an object of the class or we can invoke it using the name of the class, however, the latter way is prefer for invoking a static method, because it does not have to create a new object.

  22. When you invoke the constructor of a super class in a sub class, it must be the first line in the constructor of the sub class.

  23. You can only extend a subclass from only one super class in Java while you can implement class from more than one interface in Java.

  24. Cast has lower priority than . in Java, which means that you have to use two pairs[^2] of parentheses when you want to first cast an object and then invoke some method of the casted object.

  25. After reading or writing a file in Java, you have to close it in order for Java to release the resource. If you use Scanner to read a file, you should also close it after reading. But if you use Scanner to read data from other place, e.g. a string or System.in, then you do not have to close it.

  26. If a sub class extends from a super class which implements an interface, then the sub class implements the interface automatically.

  27. For parameter (some type) of generic types, we cannot use primitive types.

  28. For a state that is unique to an object of a class, you want to use key word new to create an object for the state (if the state is a not a primitive type). For a state that is shared among all objects of a class (e.g. random number generators in a class usually should be shared among all its object), never use key word new to create an object for the state. Just point it to an object passed as argument of the constructor of the class.

  29. For statistical simulations involving generating random numbers, you'd better use a single base random number generator (RNG) for generating random numbers. To do this in Java, you just need to create a single random number generator and pass it by reference (which is the default way) to objects that require a RNG. Also to make your work repeatable, you'd better set seed(s) for your simulations.

  30. String and Enum are immutable classes in Java ....

  31. Be careful if an object is initialized based on another object of the type, i.e. when some object is passed to the constructor for initializing an object of the class. Be aware about whether you want the state object to be shared or not.

  32. For an object whose states might be changed by itself (i.e. states can be changed by some other methods (either public or private) rather than its setters), you'd better make it immutable. Generally speaking, you do not have track of the inner states of this object, and thus you might mis-predict its inner states. If you allow setter methods to mutate the object, it can happen that you think you have changed the states of the object to these you expect, but rather they are not.

On Array

  1. Array is mutable in Java. If an array is define as a member of a class is intend to change inside the class only, you have to make defensive copies of the array. Please refer to Defensive Copying for more details.

Misc

  1. If you really care about the performance of a loop, you should avoid heavy computation in test condition as the test condition is rerun every time. Sometimes this can be avoid simplify by switching the initial condition and the test condition.

  2. Backalgorithms are often better than forward algorithms especially for arrays.

  3. Avoid having too many instance variables in a class. This not only keeps your code cleaner but also makes it easy to write copy constructors, setter methods and so on. Sometimes, instance variables intervent with each other making setter methods more complicated. Having fewer instance variables helps to reduce the complexity. If possible, you can encapsulate some coupled instance members into another inner class.

  4. Don't over design. Don't reuse code for reusing code. There is always trade-off.

  5. Integer cast (int) some_number keeps the integer part of the number only and discard the decimal part. It is equivalent to math.floor when positive and equivalent to math.ceiling when negative.

  6. RandomDataImpl.nextInt is badly implemented.

  7. No need to use getter/setter methods for final immutable instance members. Just make them public/protected.

Package Dependency Management

  1. It is suggested that you use Gradle (instead of Maven or sbt) for JVM projects.

Collections

  1. You can use Arrays.fill to set a value to all elements of an array at once.

Code Flow Control

  1. There is not goto statement in Java, however you have several ways to make the program in Java jump to other place.

    • The break and continue statements allow you to jump out of a block in a loop or switch statement.

    • A labeled statement and break label; allow you to jump out of an arbitrary compound statement to any level within a given method (or initializer block).

  2. For multi-threads programs in Java, it is hard to debug the whole program directly. To make sure that the program works, you can test each class in the program by writing a testing class for each of them.

    • Throwing and catching exceptions allows you to (effectively) jump out of many levels of method call. However, exceptions is relatively expensive and are considered to be a bad way to do "ordinary" control flow.)

    • And of course, there is return.

Keyword final

  1. Even if you make an object final, you might still be able to mutate it. This is because final describes the name of the object, which means that the variable cannot point to a new address, but the content of the address (where the variable points to) might still be changed. For example, if you define

      `public final int[] a = new int[10]`
    
    

    you cannot point a to another address, but you are still able to change the elements of a, i.e., you're able to change the value of a[i] for $i=0,\ldots,9`). This is one reason that defensive copy is preferred when you pass around a mutable object. Generally speaking, defensive copy is preferred if it doesn't affect performance badly. Also, if a getter method returns a mutable object, you'd better make a defensive copy.

  2. You can use the final keyword to tell the compiler that an object won't be reassigned value. This guarantees that a primitive variable marked as final is a constant. But there is no guarantee that an object marked as final is a constant. You cannot reassign value to the object but you might still be able to change its internal content. For example, the the object is an ArrayList, you can still change its elements.
    Notice that the const keyword is reserve but not used in Java.

  1. Always print some indicating information to the console when you expect some input from the console. Otherwise, you when you run the application, it waits for your input but you might think that it's not running. Also if you do an intensive computing in Java, you'd better print the progress (if you can) to the console. At least you should print message to the console after the simulation is done!

  2. In many programming languages, you can print out more than one variables (not necessarily the same type) at a time. In Java, the method println() (or other similar methods) of System.out can only accept one parameter. However, you can concatenate different variables as a string and print out the string.

Operators

  1. There are many operators in C/C++ which makes operations faster and calculation faster, e.g. ++, , +=, \*=, and so on. Similarly to C/C++, you can also use them in Java. Specially, for the increase (++) and decrease operator, you can use them both before and after numerical variables in Java.

    you can throw out exceptions, or you can use method System.err.println() to print error information to the console and end the program.

Misc

  1. getClass returns the RUNTIME class of the object not the declared type!

  2. Objects.hash can be used to create hash code for an object easily.

  3. Double.compare is the recommended way to compare whether 2 double values are equal.

  4. Since you do not have to assign the returned value of method to any object in Java, you can use any method as if it is a void method. This means that for any method that is void it does not hurt to declare it as a method that returns some object (or primitive type value). Actually this might be very convenient sometimes, because by doing so you can do the operation you want and at the time you have extra information about the operation. For example, if you want to insert a value to a sorted array, you can make the method return an integer which is the index of the inserted place. This extra information (the index of the inserted place) is highly useful in may cases.

  5. It is expensive to allocating a new block of memory (not only in Java but also in other languages), so you should avoid allocating new block of memory all the time. If it is impossible to avoid allocating memory, you can allocate a bigger memory than needed each time. In this way, you waste some space, but might save much time.

  6. Method getClass can return the class of an object.

  7. If you have an array of objects of some super class, you can cast the whole array to sub class at once. However, usually you cannot cast all elements of an array at a time. For example, if you have an array of double, you cannot cast the whole array into int at a time. Instead, you must cast each element one by one.

  8. If you want let the compiler know that a number you use in your code is a double precision number you can add suffix d to the number. For example if you want to do double precision calculation for 3 / 6, you can write it as 3 / 6d instead of casting integer to double using (double).

  9. Avoid using a local variable which has the same name as an instance variable.

Convert Boolean to Integer

You cannot cast a boolean value to integer using type cast. Instead, you can use the ternary operator.

https://stackoverflow.com/questions/3793650/convert-boolean-to-int-in-java

In [8]:
int x = (int) true;
incompatible types: boolean cannot be converted to int
 int x = (int) true
               ^   ^ 
In [6]:
int binaryInt = true ? 1 : 0;
System.out.print(binaryInt);
1
Out[6]:
null
In [7]:
int binaryInt = false ? 1 : 0;
System.out.print(binaryInt);
0
Out[7]:
null

Ternary Operator

The ternary operator has a very low precedence (similar as equivalent operator/expression in other programming languages), which is easy to cause tricky errors if not careful. It is suggested that you always use parentheses to make precedence clear when you use a ternary expression.

In [ ]:
## Date Time
joda time and java.time

Comments