Common problems and how to avoid them
1. Problem: Null pointer exception – this kind of exception occurs when we are trying to use null when we actually need an object.
STAY TUNED!
Learn more about JAX London
Solution: If it is possible at some point your object to become null, you should think of adding null checks to your code, especially when you did not create the object yourself. Also, it is better to return empty collections instead of nulls. Adding validations to set and get methods is also a good idea.
2. Problem: Confusing the comparison operator ( == ) with the assignment operator ( = ).
Solution: You will need some time to adapt, if you are coming from another language. An easy trick I have used for remembering this is: if you know that you are interested in only one of the values (you are assigning the one to the other), you use single “ = ”, otherwise if you care about both variables and values (you are comparing them) you need the double “ == ”
3. Problem: Using comparison operator ( == ) instead of the .equals() for checking equal strings.
Solution: All Java objects are not being checked for equality with the comparison operator ( == ). Instead we use .equals() method. In Java the String is an immutable object instead of a primitive type.
4. Problem: Not properly using access modifiers (private, protected, public and default)
Solution: Try to think in a more object-oriented way. Think a little more before implementing. “Should I be able to call the method from outside the class? Do I have the right to do so?” Learn more about information hiding, loose coupling and creating layers of your application.
5. Problem: Trying to reinvent the wheel, by implementing an already existing libraries and tools.
Solution: Learn the Java standard library. Do more pair programming with other programmers. Read the section with all of the recommended Java tools in this article. Try to find tools by yourself. Learn to use google and stackoverflow.
6. Problem: Changing an object’s state through a reference to the object. This usually happens when a get method returns a mutable object. This is very unsafe!
Solution: Learn to use access modifiers properly. In the get methods return immutable objects. When creating a get method always think if it is possible to be realized an undesirable change in the state of the object after returning it. Learn about how objects are located and referenced in the memory in Java. Don’t get confused over passing by value, and passing by reference!
7. Problem: Syntax errors, misspellings, using wrong overloaded functions, spending too much time for clicking on the menus in the IDE in order to achieve what you want.
Solution: Get a decent IDE. The syntax errors will be detected earlier and you will be able to fix them. Learn the functionalities of the IDE. Get to know the most common shortcuts in order to save time while developing. Format your code correctly. Do not change your IDE often, or if you can at all. Learn it by heart. It will become your best self-extension. Use meaningful variable names.
8. Problem: Resources are not being freed. You open some connection / file / resource and not closing it afterwards.
Solution: Here comes the “Try-with-resources” statement for any class which implements the java.lang.Autocloseable interface. After the execution of the try block all opened resources in the try() part are being automatically closed (example in Listing 1).
public class TryWithResources { public static void main(String[] args) { try (BufferedReader br = new BufferedReader( new FileReader( System. getProperty ( "user.home" ) + "/Downloads/text.txt" ))) { System. out .println(br.readLine()); } catch (IOException e) { e.printStackTrace(); } } }
Listing 1
9. Problem: Concatenating strings in a loop. Don’t try this at home. Permitted only under parental advisory. On each string concatenation a new String object gets created (strings are immutable). At some point you will run out of memory or it will start taking too much time to execute.
Solution: Use StringBuilder instead of String when concatenating content in loops.
10. Problem: Executing SQL queries in a loop.
Solution: Optimize queries to the database as much as possible as the execution of queries is quite an expensive operation. Try to get all of the necessary information with a single query and iterate over the results.
11. Problem: Empty catch blocks/ignoring exceptions
Solution: The least you can do is to print the stack trace of the exception to the default output. Usually you can use some loggers as Log4j and make the logging of information easier.
12. Problem: Calling run() instead of start() for starting a thread.
Solution: It is wrong to call run() directly. It is a very common bug. Always use start()! Also it is recommended to implement the Runnable interface instead of inheriting the Thread class.
13. Problem: Implementing without thinking enough. Some of the results can be: Deadlock , Calling non-static methods from a static context, removing items in an incorrect way while iterating a collection and all kind of logical errors.
Solution: Think. Design. Observe. If you have an hour to solve the problem, spend fifty minutes considering the solution and ten minutes in the actual execution.
Main Java infrastructural components
The Java Development Kit (JDK) consists of the following components: Java Runtime Environment, tools and tool APIs and the Java language. The Java Runtime Environment itself consists of Java Virtual Machine, lang and util base libraries,other base libraries. We have also integration libraries, user interface toolkits and deployment. All of this without the deployment represents the Java SE API. The architecture of the HotSpot JVM is being represented from the class loader subsystem, the runtime data areas and the execution engine. We also have native method libraries.
Execution of a Java Program flow
How exactly does a computer understand code? It’s a fairly standard order of operations.
1. The command line arguments are parsed
2. The required memory is allocated
3. The environment variables are loaded
4. The class with the main method to be executed is located
5. Creation and initialization of the VM
6. The class with the main method is loaded
7. The main method is executed
8. After the execution has finished, the result is returned
9. The VM is destructed
Hello World example
First you need to add the following text in a file with the name PatsovHelloWorldExample.java:
public class PatsovHelloWorldExample { public static void main( String[] args ) { System. out .println( "Hello World!" ); } }
Depending on your preference you may choose to do so with an IDE or with a text editor. If you have used an IDE, the next step is just to run the program. If you have created the file with a text editor, you need to compile the file with javac PatsovHelloWorldExample.java in the terminal and run in with java PatsovHelloWorldExample in the terminal again. The expected result is to be seen in figure 1.
Command-line options
While starting the JVM we are able to pass some additional arguments in order to control the execution of the application and some of the environment variables. The syntax is the following:
java [here we add some options] -jar filToBeExecuted.jar [here we pass some arguments to our application]
An actual example with real parameters would be:
java -classpath MyApplication.jar the.package.ClassWithMainMethod
Some of the options are server, client, classpath and help. In the arguments we can pass whatever we need, depending on how we have developed our application and what we want to achieve.
The primitive types
Here we have the byte, represented by an 8 bit integer, with values between [-128, 127], also the short data type with 16 bit integer and respectively values between [-32 768, 32 767]. We have the int data type which is a 32 bit integer with values between [-2 31 , 2 31 -1], the long which is a 64 bit integer along with the floating point float and double, where the float is a single-precision 32-bit IEEE 754 floating point and the double which is a double-recision 64-bit IEEE 754 floating point. We have also the boolean which is either true or false and the char which is a single 16-bit Unicode character. For currencies you will need to use the java.math.BigDecimal class and for the really big integers you will need the java.math.BigInteger class.
The collections
All collections actually represent a container, which is grouping some logically connected components in a single whole. They are generally separated in three different types:
- for general purpose (for example the ArrayList, LinkedList, TreeMap, TreeSet, HashMap and HashSet)
- the concurrent ones (like the ConcurrentMap, ArrayBlockingQueue, Vector, LinkedBlockingQueue and PriorityBlockingQueue)
- the specialized ones (as the EnumSet, CopyOnWriteArraySet and WeakHashMap)
The collections are best for:
- sorting
- searching
- shuffling
- manipulating – reverse, fill, copy, swap, bulk add
- finding max/min values
Regular expressions
For best learning results is recommended solving of RegEx crosswords. Some of the most famous pattern matching expressions are:
- ^ – for matching beginning of line
- $ – for matching the end of a line
- . – for matching any character except the new line
- [somecharactershere] – for specifying a group of characters,
from which only a single one is enough to be matched - [^asd] – for matching any character not in the listed ones
(exclusion) - * – for matching 0 or more occurrences of the expression
before that (ex. asd* matches ‘as’ and ‘asd’) - + – matches 1 or more occurrences of the expression before
that - ? – matches 0 or 1 occurrences of the expression before
that
Recommendations
There are a lot of resources available online for beginners and experts alike. While these are some of my favorites, there are many more libraries, tools and frameworks available. These are my recommendations to help anyone get started:
• Spring
• Angular
• Tomcat
• Maven
• Git