OCA and OCP certifications: are they worth it?

Let's be honest. The number one reason why I am writing this blog is so that I can sneak in a Robocop pun. You know, because the evil organisation is called Omni Consumer Products which is shortened to OC... okay okay, I'll take your unimpressed silence as an indication to move swiftly onto the main content...

Earlier this year, I passed my OCA (Oracle Certified Associate) exam and I am currently in the midst of my OCP (Oracle Certified Professional) preparations. Typically when graduates join Black Pepper Software, they are encouraged to obtain an OCA qualification. This somewhat prepares them for the menacing yet wonderful world of "real-life" Java development. However my background is slightly different in that prior to joining Black Pepper Software, I had worked 3 years as a Java developer for a financial software company, so I already had some experience in enterprise software development. Given this I thought it would be interesting to share my own exam preparation experiences, give some insight in a few areas I found interesting and perhaps attempt to answer the question: does being OCA and OCP qualified make you a better software developer? 

Failing early

When I joined Black Pepper last year, I was given the opportunity to study for these qualifications whereby the company would pay for any resources and exam fees. Since I wanted to learn more and was curious to see if studying for the OCA would make me a better Java developer in practice, I decided to grab some flash-cards and coloured pens left over from my university days, and hit the books.

From initially glancing at the OCA exam topics, I felt reasonably comfortable. I was familiar with words like "Classes", "Inheritance", "Polymorphism" and "Exceptions" so I thought it would be a good idea to kick start my studies with a mock exam (I suppose that's called Test Driven Learning). 

Well, undertaking the first mock exam was an incredibly humbling experience. I had scored a substantial amount below the pass margin and gaps in my Java knowledge, which were wider than the Mariana Trench, became very apparent. Though this didn't discourage me in the slightest so I began to delve into the topics which needed work.  

Depth and Abstractions 

Whilst going through the exam material, I noticed that the depth of understanding you were expected to have of the language was...well, deep. When I first started working as a Java developer I was exposed to libraries and frameworks such as Spring, Jemmy and Maven. I learnt that these things existed as layers of abstraction whereby they would deal with tedious functionality which the developer didn't need to worry about (or that much about at least). Additionally, I was also taught the art of writing clean code and writing tests up front as a way of design. However, I didn't really learn anything more about Java itself; the depth of my knowledge remained pretty much the same since graduating from University.

The holy Mala Gupta OCA preparation book opened up new facets and intricacies of Java for me to explore. I will briefly go through some of these features which I found particularly interesting. This gets a little bit technical so feel free to skip ahead to the "Are the certifications worth it then?" section if this is likely to send you to sleep. 

Equality checking

The difference between == and .equals was something that I had overlooked prior to my OCA studies. I knew they were different but I didn't know how they were different.

== checks if two objects have the same object reference i.e. the same memory location whereas the equals method checks if objects have the same value(s). 

Take a gander at this example: 

14       String stringOne = new String("Hello");
15       String stringTwo = new String("Hello");
16       String stringThree = stringOne;
17
18       System.out.println(stringOne == stringTwo);
19       System.out.println(stringOne.equals(stringTwo));
20       System.out.println(stringOne == stringThree);
21       System.out.println(stringOne.equals(stringThree));

Line 18 prints "false" because both stringOne and stringTwo have different references in memory; object constructors will always create new references even if the object content is the same. However, line 19 prints "true" because both strings have the same sequence of characters. 

On line 16, stringThree is assigned the reference (and object content) of  stringOne which therefore means that lines 20 and 21 will both print "true".

String Initialisation 

There is a sneaky difference (besides the new operator) between

String hello = "Hello";

and

String hello = new String("Hello");
  

The first example is known as a String literal whereas the latter is a String object. Let's illustrate the difference by using modifying the example slightly in the "Equality checking" section above. 

14       String stringOne = "Hello";
15       String stringTwo = "Hello";
16       String stringThree = new String("Hello");
17
18       System.out.println(stringOne == stringTwo);
19       System.out.println(stringOne == stringThree);

Interestingly, line 18 will print "true" whereas line 19 will print "false". What magic is going on here? 

When a string literal is initialised a new object is created in what is called the "String Pool". On line 14, the JVM (Java Virtual Machine) checks if an object with the value "Hello" already exists in the string pool. Since it doesn't, a new object with value "Hello" is created by implicitly invoking the intern() method on the String class. When stringTwo is created on the following line, the object with value "Hello" already exists in pool, so stringTwo's reference is set to point to that object. Therefore knowing that stringOne and stringTwo both have the same object references, it now makes sense that using the == equality check will return true.

When a string object is created (using the new operator), the string pool area is not used at all and a new object is just created in the heap area. 

If we were to illustrate this in a MS Paint-esque diagram, it will look something like this where the arrows represent the references between the instances (yellow boxes) and the objects in memory (orange boxes):

String Pool

The purpose of the string pool is to save space during runtime. Performance-wise, initialising a string literal could be faster than initialising a string object because the JVM doesn't need to create a new object reference every time.

Autoboxing and Unboxing

Autoboxing occurs when the compiler converts a primitive value into an object of its corresponding wrapper class. For example, the primitive int value, 5, is autoboxed to an Integer object like below: 

Integer five = 5;
  

Unboxing is the process vice-versa whereby an object of a wrapper is converted to a primitive value. 

int four = new Integer(4);

I suppose it can be thought of putting a primitive value into a box which represents an object, and taking it out again. 

The benefit of this is so developers can use objects and primitives interchangeably where no explicit typecasting is required. This is particularly useful when we want to have a collection of "primitive" values since collections in Java can only store objects, not primitives.  

However, I did learn that autoboxing introduces a few pitfalls:

Nulls, Nulls everywhere!

Take the following code: 

65     private void doSomethingWithBoolean(final Boolean isTrue) {
66            if (isTrue) {
67                //do something 
68            }
69    }

The compiler flags no issues and it seems very benign at first. However, the isTrue parameter could be null since it is an object not a primitive. If it was null then a NullPointerException would get thrown on line 66, because at runtime the booleanValue() method is implicitly called on isTrue but the JVM cannot call a method on a null reference so it spits out an exception. To mitigate this problem, the method declaration could be changed to use a primitive boolean parameter type or the if statement could be changed to:

if (Boolean.TRUE.equals(isTrue)) {

This is something to be wary of when using wrapper objects. Some folks may argue that there is not much point in using Boolean objects, besides for keeping a collection of booleans. But I am sure that would make a riveting talking point for another blog! 

Integer Caching 

Check out this weirdness below:

60        List<Integer> listOfIntegers = new ArrayList();
61        listOfIntegers.add(1000);
62        listOfIntegers.add(1000);
63        listOfIntegers.add(127);
64        listOfIntegers.add(127);
65
66        System.out.println(listOfIntegers.get(0) == listOfIntegers.get(1));
67        System.out.println(listOfIntegers.get(2) == listOfIntegers.get(3));

Now anyone with some common sense would expect lines 66 and 67 to print out true right? Well, Java likes to challenge your intuition since line 66 will print out "false" but line 67 will print "true". This is because the Integer class caches numbers between -128 and 127 meaning any numbers outside this range are assigned new object references and therefore the reference equality check will return false even if both of the numbers are identical. However using the equals method on line 66 will return true. 

That wasn't the method I was looking for

During compilation widening takes precedence over autoboxing. Widening is when a primitive data type is converted to a bigger primitive type such as an int to double. This is illustrated below:

public class WideningVsBoxing {
    public static void main(String [] args) {
        doSomething(10);
    }
    private static void doSomething(double someDouble) {
        System.out.println("This is a double!");
    }
    private static void doSomething(Integer someInteger) {
        System.out.println("This is an integer!");
    }
}

The code above actually prints "This is a double!", even though we are invoking the method with an int parameter. Wacky, huh?

Are the certifications worth it then?

Now having outlined a handful of quirks that I learnt about Java whilst preparing for the OCA, I feel like I am in a good enough position to answer: does being OCA and OCP qualified make you a better software developer?

The worth of having the certification itself is arguable. Some companies might require developers to have at least an OCA certificate whereas some might not care and would regard experience as a good enough indicator. However I think the worth of preparing for the exam and learning new details in the process is incredibly valuable because it broadens your perspective of the language. Being a relatively experienced Java developer, I found that there was a lot that I didn't know but paradoxically the more I learnt, the more I realised I don't yet know - but that is all part of the fun! 

The OCA/ OCP courses will not directly teach you how to write cleaner code or how to design the best architecture for your needs; they are there to take your understanding of Java to a much deeper level. They also teach you new language features with the latest Java version (for example, in the Java 8 exams there are topics on lambdas, streams and the LocalDate API). Also your CV won't look too bad with a certification which corroborates your Java skillage. 

Therefore, if you are willing to launch your Java knowledge to the next level I highly recommend studying for the OCA and OCP. It doesn't matter if you are a beginner or have many years experience, you will still learn something and what you learn may surprise you!

This site uses cookies. Continue to use the site as normal if you are happy with this, or read more about cookies and how to manage them here.

X