Everything I learned from studying OCA after two years of Java web development

Everything I learned from studying OCA after two years of Java web development

One of my goals for 2019, is to pass the Oracle Certified Associate Java SE 8 Programmer 1 exam. Let's call it OCA from now on, shall we?

I'll be using the book "OCA: Oracle Certified Associate Java SE 8 Programmer I Study Guide" written by Jeanne Boyarsky and Scott Selikoff to prepare myself for the exam. If you are using the same book, or planning to use the same, I've the following tip: check the list of errata.

Even tough I've used Java for almost two years now—mainly for web development, the book says:

There is a difference between being able to write Java code and being a certified Java developer. For example, you might go years without writing a ternary expression or using an abstract class, but that does not mean they are not important features of the Java language.


There are a number of subtleties to Java that you could easily not encounter even when working with Java, even for years.

So I'm curious about the things I didn't know before studying OCA. I'll share it with you in this article.

main() method's parameters list is represented as an array of Strings

The main() method's parameters list is an array of java.lang.String objects. The compiler accepts any of the following parameters for the main() method: String[] args, String args[] and String....

Initially, I learned that the main() method looks like this:

public static void main(String[] args)

I rarely needed to write a main() method, but when I needed one, I would automatically write it like how I initially learned it. Basically, I never thought about the fact that it's just an array of Strings.

Explicitly importing a class name, takes precedence over any wildcards present

If you explicitly import a class name, the compiler takes precedence over any wildcards present.

A common example of this is the Date class. Java provides implementations of java.util.Date and java.sql.Date. If we want to use the java.util.Date version, you could use either import java.util.* or import java.util.Date. The tricky cases come about when other imports are present:

import java.util.*;
import java.sql.*;

When the class is found in multiple packages, Java gives you the compiler error:

The type Date is ambiguous.

If you can't remove the java.sql.Date import, because you need a whole pile of other classes in that package, you can use:

import java.util.Date;
import java.sql.*;

Import statements is something I don't type myself. Usually my IDE takes care of them. That's the reason that this obvious thing, never came to my attention.

Instance initializer blocks

Code blocks that appear outside a method, are called instance initializers. An instance initializer block is executed each time a new object of the class where it's places is instantiated.

It can be useful if you, for example, have multiple constructors and need a piece of shared code.

Underscores in numbers

Since Java 7, you can have underscores in numbers to make them easier to read.

int million1 = 1000000;
int million2 = 1_000_000;

You can add underscores anywhere except at the beginning of a literal, the end of a literal, right before a decimapl point, or right after a decimal point.

double notAtStart = _1000.00;         // doesn't compile
double notAtEnd = 1000.00_;           // doesn't compile
double notByDecimal = 1000_.00;       // doesn't compile
double annoyingButLegal = 1_00_0.0_0; // compiles, but doesn't look pretty

finalize() might get called, but never a second time

Java allows objects to implement a method called finalize(), which gets called if the garbage collector tries to collect the object. If the garbage collector doesn't run, the method doesn't get called. If the garbage collector fails to collect the object and tries to run it again later, the method doesn't get called a second time.

In practice, this means you are highly unlikely to use it in real projects.