How I passed the SCJP / OCPJP

After procrastinating for many years (4 to be precise), I finally sat and passed the SCJP exam. The exam itself wasn’t particularly difficult, but theres a lot of things you can get tested on that you’ll rarely use in everyday development. Having been developing in Java for around 4 years now, I’ve never needed to do any serialisation or do any fancy concurrency work other than starting a thread for an asynchrnous task.

So to iterate, theres a lot in there that you may not use, but the test expects you to know it well, so be sure to practice and write a lot of code.

Anyways, the reason for this post was to discuss some of the tactics I used to get through.

The study part

The first thing you need to do, is to get hold of the study guide and start reading through it. If you’re relatively new to Java, such as a student or someone transitioning from another background, then you can get Head First Java which will give you a fantastic intro to the Java programming language in an easy to digest read. You should be able to get through HFJ in a few weeks as it has a relatively informal style, but you should certainly allow a month or two to read the study guide, as its around 800 pages and you need to keep focus!

Write code

I can’t stress how important this is! My memory is pretty useless, I can read a book and then a month or two later I’ll have forgotten most of it. I found the best way to remember things is to practice them, so when I’ve read a chapter (or even a few pages on a specific topic) I’d start experimenting with some code. It just helps the knowledge stay in.

My advice here, just download an IDE and start writing, you can also post your code up onto Github too, it makes a great reference point, and may help others. You can also blog using your study notes, which is pretty much the main reason I setup this blog in the first place.

 

Resources, things to buy, free stuff

  1. Head First Java
  2. SCJP Study Guide
  3. SCJP Practice exam book
  4. A set of blank flash/record cards, these will be around £4 from your local stationary shop, use them to write important points and revise when you can spare the odd 5 minutes here and there.
  5. Evernote.com – Get signed up on there, its a great way to store your study notes. You can also get the mobile app to revise your notes when on a train / plane etc.
  6. JavaRanch.com – Post up here in the certification section any questions that you may have, very useful community
  7. StackOverflow.com – I used this a lot for finding answers that were not always obvious in the study guides. If your questions are well defined, you’ll get great help here
  8. Colleagues – Don’t underestimate your peers, if you don’t understand areas of the syllabus, chat to people!
  9. Whizlabs – Great testing kit, but make sure you use it. I wasn’t aware that the software expires after 1 year, so unfortunately I didn’t get to use it for my exam :(
  10. Enthuware – This is much better than whizlabs as it doesn’t require being online, and you get to select how many questions. Often I didn’t want to do all 60 in one go

 

Suggested schedule

When booking my exam, I gave myself around 3 months, considering I’d already been over the book a few times it was plenty enough to recap the important chapters and squeeze in some mock tests. If you’re sitting this for the first time, I’d suggest a preparation schedule like below, assuming you will have 8 months to prepare. Of course, if you’ve been developing for a while you can probably skip the first 2 weeks, read the study guide in a condensed amount of time, and take less practice tests.

 

Week 1 Read Head First Java
Week 2 Read Head First Java
Week 3 Take a week off
Week 4 Study guide chapter 1
Week 5 Experiment with code relating to chapter, then do chapter quiz
Week 6 Study guide chapter 2
Week 7 Experiment with code relating to chapter, then do chapter quiz
Week 8 Study guide chapter 3
Week 9 Experiment with code relating to chapter, then do chapter quiz
Week 10 Study guide chapter 4
Week 11 Experiment with code relating to chapter, then do chapter quiz
Week 12 Study guide chapter 5
Week 13 Experiment with code relating to chapter, then do chapter quiz
Week 14 Study guide chapter 6
Week 15 Experiment with code relating to chapter, then do chapter quiz
Week 16 Study guide chapter 7
Week 17 Experiment with code relating to chapter, then do chapter quiz
Week 18 Study guide chapter 8
Week 19 Experiment with code relating to chapter, then do chapter quiz
Week 20 Study guide chapter 9
Week 21 Experiment with code relating to chapter, then do chapter quiz
Week 22 Study guide chapter 10
Week 23 Take a week off
Week 24 Whizlabs Tests
Week 25 Whizlabs Tests
Week 26 Whizlabs Tests
Week 27 Take a week off
Week 28 enthuware tests
Week 29 enthuware tests
Week 30 enthuware tests
Week 31 Take a week off
Week 32 Self assessment 1, then brush up on any key areas you really missed on
Week 33 Self assessment 2, then brush up on any key areas you really missed on
Week 34 Practice test 1 & 2
Week 35 Practice test 3 & 4

Tips for the exam:

  • Get there early, my train got cancelled so I was running/stressing to the exam room, which didn’t help.
  • Don’t stress! Thats the worst thing you can do!
  • The actual exam will say how many answers you need to select, so don’t worry about the “select all that apply” that you often see in mock tests.
  • You can “strikeout” answers on the real exam, which means you can eliminate the answers you think are wrong, very useful for those questions that are a complete guess.
  • You don’t get your results immediately, you have to login to Oracle Certview about an hour after completing the exam to see your score card.

 

Basics of the switch statement in Java

If statements are great, but sometimes they are just not very practical when you have to test for more than a handful of conditions, have a look at this very poor example of how you build up a long set of if-else statements, its fine for a few checks, but if you’re doing multiple equality checks on a value, its best to use a switch statement for flexibility and readability:


public class PoorIfStatement
{
    public static void main(String[] args)
    {
        int myInt = 5;

        if (myInt == 1)
        {
            System.out.println(myInt);
        }
        else if (myInt == 2)
        {
            System.out.println(myInt);
        }
        else if (myInt == 3)
        {
            System.out.println(myInt);
        }
        else if (myInt == 4)
        {
            System.out.println(myInt);
        }
        else if (myInt == 5)
        {
            System.out.println(myInt);
        }
        else
        {
            System.out.println("Unexpected number...");
        }
    }
}

Now, lets have a look at the same example, but using a switch statement instead, looks cleaner huh?

public class CaseStatements
{
    static int myInt ;

    public static void main(String[] args)
    {

        myInt = 2;

        switch(myInt)
        {
            case 1:
                System.out.println("first");
                break;
            case 2:
                System.out.println("second");
                break;
            case 3:
                System.out.println("third");
                break;
            case 4:
                System.out.println("fourth");
                break;
            case 5:
                System.out.println("fifth");
                break;
            default :
                System.out.println("Unexpected number...");
        }

    }
}

Before we grab our coats and get ready to run, there is a lot more to the switch statement than a mere alternative to a set of ifs, the switch statement can execute more than one case statement! The program will read down from the top of the switch block, and as soon as it finds a suitable match, it will drop in and start processing whatever it finds. Think of it a little bit like a penny machine, the program is looking down the switch block, trying to find one which its penny will fit in, once it does, it pushes the penny in and it drops all the way down. That’s a little strange analogy of it, but its a good one to remember.

It is important to note, that like the above example, if you put in a break statement, then the program will exit out at that point, and not execute any further statements, this is great for if you need to one case statement and not “this case statement and then everything else below me”.

A lot nicer to read isn’t it? And what is better, it is much more flexible. If you need to check for additional conditions, you just need to add a case statement and specify what to do.

Don’t forget, that you can use the default block to catch conditions that don’t specifically match any of the cases, typically you’d put this at the bottom.

Here is another set of examples, that are available up on my SCJP code snippets on Github:

package com.jameselsey.demo.scjp.flow_control;

/**
 * Author:  JElsey
 * Date:    07/08/2012
 *
 * Toying around with the Switch statement a little, running on Java 1.6 so not using switch on Strings yet.
 */
public class SwitchStatement
{
    enum Animals
    {
        CAT, DOG, FISH
    }

    public static void main(String... args)
    {
        switchOnInt(5);
        switchOnInt(0);
        switchOnInt(2);
        switchOnInt(3);

        switchOnChar('a');
        switchOnChar('b');
        switchOnChar('c');
        switchOnChar('d');
        switchOnChar('A');
        switchOnChar('g');

        switchOnEnum(Animals.CAT);
        switchOnEnum(Animals.DOG);
        switchOnEnum(Animals.FISH);
    }

    /**
     * This method switches on an int, notice the (1+2) which is evaluated to 3. Also note no appearance
     * of the break statement in the 3rd block, so default will be execute in addition to 3
     *
     * @param theInt int
     */
    public static void switchOnInt(int theInt)
    {
        System.out.println("\n\nAssessing int :" + theInt);
        switch (theInt)
        {
            case 1:
            {
                System.out.println("The int was 1");
                break;
            }
            case 2:
            {
                System.out.println("The int was 2");
                break;
            }
            case (1 + 2):
            {
                System.out.println("The int was 3, and we're not going to break here either");
                //break;
            }
            default:
            {
                System.out.println("This is the default");
            }
        }
    }

    public static void switchOnChar(char theChar)
    {
        System.out.println("\n\nAssessing char : " + theChar);
        switch (theChar)
        {
            case 'a':
            {
                System.out.println("The char was a");
                break;
            }
            case 'b':
            {
                System.out.println("The char was b");
                break;
            }
            case ('c' | 'd'):
            {
                System.out.println("The char bitwised to make g");
                break;
            }
            default:
            {
                System.out.println("The char didn't match anything, must be something else");
            }
        }
    }

    public static void switchOnEnum(Animals theAnimal)
    {
        System.out.println("\n\nAssessing Animal :" + theAnimal);
        switch (theAnimal)
        {
            case CAT:
            {
                System.out.println("The Animal was CAT");
                break;
            }
            case DOG:
            {
                System.out.println("The Animal was DOG");
                break;
            }
            default:
            {
                System.out.println("The animal was something other than CAT or DOG");
            }
        }
    }
}

String concatenation operator

The string concatenation operator is a bit like a hedgehog, it looks cute and sweet, but try to grab hold of it quickly and you’ll soon know about it…

It’s actually quite simple, however there are some traps that are very easily overlooked (just got caught out with it on a mock test, so I’m here to rant).

The rule of thumb is, that if either one of the operands being “+” is a String, then concatenation will occur, but if they are both numbers, arithmetic addition will occur. Sounds simple right? What do you think the following equate to?

package operators;
public class MockTest
{
    public static void main(String[] args)
    {
        System.out.println(3 + 2);
        System.out.println(3 + "s");
        System.out.println("s" + 2);
        System.out.println("hello " + "world");
    }
}

Think you know it? Well its going to be : 5, 3s, s2. The first one is an arithmetic addition, since both sides of the operator are numeric. The second and third are String concatenation, because at least one of them is a String. The fourth one are both Strings, so concatenation once again.

those are the simple ones, however it can get a lot more tricky, have a look at these common ones that those exam creators try to catch you with!

package operators;

public class MockTest
{
    public static void main(String[] args)
    {
        // Inside brackets are evaluated first, so it'll be 7String
        System.out.println( (3 + 4) + "String");

        /* This is the little bugger that caught me, I vouched for 34String, but its actually 7String.
         Concatenation happens from left to right, one at a time, so it'll break it down to:
            3 + 4 then...
            <thing on left> + "String"

         Careful on these ones!
        */
        System.out.println(3 + 4 + "String");

    }
}


So remember, it’ll evaluate from left to right, one “+” operator at a time. Brackets are always evaluated first however.

Take my examples and have a play!

Happy coding (or raging at the screen if the mock tests catch you out…)

The instanceof Operator

The instanceof operator is a great way for checking if a reference variable is of a given type, in other words, does it pass the IS-A inheritance test. Ask yourself, is a Cat a Dog? A Dog a Cat? Or is a Cat an Animal and a Dog an Animal? In true Harry Hill style, there is only one way to decide….FIGHT!!!!

Have a look at my following example :

package operators;

public class InstanceOfOperatorDemo
{
    public static String myString = "James";

    public static void main(String[] args)
    {
        // myString variable is of type String, so returns true
        System.out.println("myString instanceof String : " + (myString instanceof String));
        // Even though myString is a String, a String is actually an Object (extends from Object), so the below is also true
        System.out.println("myString instanceof Object : " + (myString instanceof Object));

        B b = new B();
        // B is technically an instance of the implemented interface, so this should return true
        System.out.println("B instance of Foo : " + (b instanceof Foo));
        // This should return true also for the same reasons as above
        System.out.println("A new A() instance of Foo : " + (new A() instanceof Foo));
        // An A isn't an instance of a B, its the other way around; a B IS-A A, so returns false
        System.out.println("A new A() instance of B : " + (new A() instanceof B));

        // Any checks with null always return false, since null isn't an instance of anything
        System.out.println("null instanceof Object : " + (null instanceof Object));

        int[] myInts = new int[10];
        // Even though this array contains primitives, the array itself is still an Object at heart..
        System.out.println("myInts instanceof Object : " + (myInts instanceof Object));
    }
}

interface Foo {}
class A implements Foo {}
class B extends A {}

As we can see, a String IS-A Object, so that will pass the instanceof test. It is also important to note, that interfaces are also included in the instanceof check, so by checking if a class or a subclass is an instanceof an interface will return true.

Arrays, no matter what they hold, are always objects themselves, so they can be checked for instanceof too, of which they are Objects, as shown above.

It is important to note, that you can’t use instanceof across class hierarchies, this is something they’ll try to trick you out of in the exam, such as comparing a cat against a dog, you can compare up the hierarchy, but not across it, have a look at this example :

package operators;

public class InstanceOfOperatorCrossHierarchyDemo
{
    public static void main(String[] args)
    {
        // a Cat IS-A Dog, plain and simple
        System.out.println("Is cat an instanceof Animal? : " + (new Cat() instanceof Animal));

        // This will fail to compile, since we are not allowed to instanceof check across the
        // object hierarchy, a Cat is not an instance of Dog, so compiler fails
        System.out.println("Is cat an instanceof Dog? : " + (new Cat() instanceof Dog));
    }
}

class Animal {}
class Dog extends Animal {}
class Cat extends Animal {}

That’s it! A nice and easy one, please leave me comments if you can suggest improvements!

Happy coding.

Compound Assignment Operators

There are various compound assignment operators, however it is only necessary to know the 4 basic compound assignment operators for the exam, being as follows:

  1. += (Addition compound)
  2. -= (Subtraction compound)
  3. *= (Multiplication compound)
  4. /= (Division compound)

Essentially, they’re just a lazy way for developers to cut down on a few key strokes when typing their assignments. Consider the following examples that I’ve created to demonstrate this:

package operators;

public class AssignmentsOperator
{
    public static void main(String[] args)
    {
        int x = 5;

        // This is the "longhand" way of adding 5 to x
        x = x + 5;
        // You could use the compound assingment as follows, to achieve the same outcome
        x += 5;


        // Lets look at the other 3...
        // This...
        x = x - 1;
        // ...is the same as
        x -= 1;

        // This...
        x = x * 10;
        // ...is the same as
        x *= 10;

        // This...
        x = x / 10;
        // ...is the same as
        x /= 10;

    }
}

That is it! Any suggestions, please let me know!

Happy coding.

Static members…

Statics are a rather strange beast, they belong to no instance of a class, they have no fixed abode, other than their class..

Consider the following example :

package declarations;

public class StaticMembers
{
    private static String message = "hello";
    private String instanceMessage = "hello from the instance!";
    
    
    public static void main(String[] args)
    {
        // You "can" create a new instances and call the static member, but its a bit redundant....
        StaticMembers staticMembers = new StaticMembers();
        System.out.println(staticMembers.message);

        // ..Since you can just call it directly, as statics don't belong to any instances
        System.out.println(StaticMembers.message);
        
        // You can't do this, since how would the static know which "copy" of the instance method to get?
        System.out.println(instanceMessage);
        
        // ..But you can do this, since you have an instance..
        System.out.println(staticMembers.instanceMessage);
        
    }
}

Statics don’t belong to any instance, they belong to the class itself. So there is only ever one copy of a static member (method or variable). Statics can’t ever access an instance variable directly, why not? Think about it, if a static wants to obtain an instance member variable, there may be hundreds, how would it know which one to get? You can however, declare and initialise an instance member from a static, and then access its members, as we’ve done in the example above.

Take my example, and have a play with it, statics are actually quite straightforward once you understand how they behave, but be careful, the exam will try and trick you out with statics accessing instance members directly!

Happy coding!

Local Variables, as far as the SCJP is concerned

Local variables are variables that are declared locally, funny that eh? This one should be nice and easy, lets have a look at a quick example :

package scope.localvariables;

public class LocalVariables
{
    private String instanceString;

    public void doSomething()
    {
        // local variable called 'localS', initialised
        String localS = "hello";
        // Another initialised local variable, with the final modifier so it can't be changed once initialised
        final String localS2 = "hello again";

        localS = "I've changed, since I'm not final";

        System.out.println(localS);
        System.out.println(localS2);
    }

    public void doSomethingElse()
    {
        String localS;
        // Compiler won't like this, since you haven't initialised 's' with anything
        System.out.println(localS);
    }
}

Some really easy things to remember, local variables don’t ever get initialised automatically, so you have to do that yourself. The method above, doSomethingElse, the variable gets declared, but never assigned a value. The compiler won’t assign a default value like it does for an instance varible, so the compiler will complain on the line which tries to print the value to system out. So whatever you do, if you declare a local variable but don’t assign it a value, make sure that you DO assign it a value before you try to use it.

Since variables are declared within a method, they can only be accessed, and actually only live for the duration that method is executing. So if you declare a variable inside a method, but try to access it elsewhere, your code will fail to compile since its scope is only available to the method the declaration resides in. Careful of this one, there are a lot of questions in the exam which will try to catch you out with this!

Local variables can take the final modifier if required, so that once assigned a value it can’t be changed.

Also note, that local variables live on the stack, and not the heap.

Lastly, it is possible to have local variables with the same names as instance variables, this is known as shadowing. You’ve probably seen this countless times before without actually realising, since its quite popular with constructors (with may also have local variables)

package scope.localvariables;

public class MyClass
{
    private String name;
    private int age;

    // Overridden constructor, with 2 local variables that shadow instance variables
    public MyClass(String name, int age)
    {
        this.name = name;
        this.age = age;
    }

    public static void main(String[] args)
    {
        MyClass myClass = new MyClass("James", 25);
        System.out.println("Name is : " + myClass.name + " Age is : " + myClass.age);
    }
}

Thats it, hope you’ve enjoyed the show folks, please leave comments or improvement suggestions!

Thanks!

Other modifiers, for members…

We’ve already touched upon various modifiers, for classes (both access and non-access), but there are also some more modifiers for members, as detailed here.

We have the following modifiers for members :

  • final – Can’t be overridden
  • abstract – No implementation specified, subclass must implement
  • synchronized – Only a single thread of execution can pass through at a given time
  • native – Implemented by a 3rd party piece of code (C++ for example)
  • strictfp – Enforces foating point precision and doesn’t let the JVM do its own way

To make things easier, you don’t actually need to know how the strictfp or native work for the exam, but you’ll need to be aware of them. Strictfp guarantees precision on floating point calculations (otherwise the JVM implements precision however it feels), and the native is used for external implementations, such as implementing methods in C++.
All you must remember with these, is that the native modifier applies only to methods, but the strictfp modifier applies to both classes and methods. So lets have a look at a brief example then pass aside on these two and focus on the ones that matter.

package modifiers;

// The class can be marked as strictfp too!
public strictfp class NativeAndStrictfp
{
    // A normal method
    public String giveMeAString()
    {
        return "hello";
    }
    
    // strictfp method
    public float giveMeAFloat()
    {
        return 123.123f;
    }
    
    // pretend its abstract, we don't provide implementation so use a semi colon not braces!
    public native String doSomeNativeCodingAndReturnAString();
}

As with classes, the final modifier does the same thing, it states that the particular method can’t ever be overridden in a subclass, simple as that.

The same applies to the abstract modifier, abstract methods are declared with a signature, a return type, an optional throws clause, but are not actually implemented. The first concrete subclass to extend from the class has to override that method and provide its implementation.

Consider the following example :

package modifiers;

// Don't forget, that since we have one abstract method, the whole class must be marked abstract!
public abstract class OtherMemberModifiers
{
    // I'll get inherited, since I'm public, but I can't be overridden.
    public final String giveMeAString()
    {
        return "hello";
    }

    // Remember, semi colon, no braces!!
    public abstract String giveMeAnotherString();
}

class ClassThatExtends extends OtherMemberModifiers
{
    // I'm the overridden abstract method above!
    @Override
    public String giveMeAnotherString()
    {
        return "another string";
    }
}

Remember, abstract methods can’t be private or final, otherwise how would it ever be overridden? Think about it!

Lets cover the synchronized modifiers. Synchronized means that only one thread of execution can pass through that method at a given time, and you can use the modifier just like any other, they can also be marked as final, to prevent subclasses from overriding your implementation. Lets have a look :

package modifiers;


public class SyncModifiers
{
    // Just a synchronized method ;)
    public synchronized String giveMeAString()
    {
        return "hello";
    }

    // I can't be overridden by a subclass
    public final synchronized String giveMeAnotherString()
    {
        return "hello again!";
    }
}

The synchronized modifier can also be used on code blocks, but we’ll cover that more in the threading posts.

Well thats it! I hope I’ve explained things well, if you find any mistakes or want to suggest improvements, please let me know!

Happy coding!

Class Modifiers (non-access)

In addition to class access modifiers, classes can also be marked with non-access modifiers. These modifiers imply rules on a class, but are not necessarily linked to access rights.

The following non-access modifiers are available:

  • final – The class can’t be extended.
  • abstract – The class has to be extended, and can’t be instantiated on its own.
  • strictfp – Ensures that you always get exactly the same results from your floating point calculations on every platform your application runs on. If you don’t use strictfp, the JVM implementation is free to use extra precision where available.

Lets make things easier, its worth knowing what strictfp is, but its not on the SCJP exam so you don’t need to know how to use it, so you can almost brush that aside after remembering the information above.

Final classes can’t be extended / subclassed. Thats great, for those times when you don’t want people extending your classes, mark them private. Take the String class for example, that is private, as they didn’t want developers extending it and altering the way Strings behave, that would cause nightmares for all sorts of applications!

The other non-access modifier is the abstract modifier. There may be times when you don’t want people to instantiate your class. Say that you had a class Car, but you didn’t want people to start creating Car objects all over the place, you want them to extend your Car class and create their own functionality, you might choose to make Car abstract, like the following example:

package declarations;

public abstract class Car
{
    public void doSomething()
    {
        
    }
}

class SportsCar extends Car
{
    public static void main(String[] args)
    {
        // do SportsCar stuff here
    }
}

Don’t forget, that a class can’t be both final and abstract, as the contradict each other, one can’t be subclassed, yet the other must be subclassed, it just won’t work!

We’ll touch more upon abstract classes in the interfaces sections, as interfaces are essentially 100% abstract classes, but more about that later :)

Class Access Modifiers

Class access modifiers define who can see the class, you use it on a daily basis, have a look at the following :

public class ClassAccessModifierExample
{
    public static void main(String[] args)
    {
        // do something!
    }
}

There you go, you said “public class”, thats you saying that this class is public, and anything can access it.

It is important to note, that even though a class may be declared as public, you can still have private members within that class. The class access modifier merely states who can gain access to the class.

There are 3 class access modifiers, in other words there are 3 keywords that you can use :

  1. public – any class can import and use your class.
  2. protected – any class in the same package as yours can import and use your class, additionally, any class that resides in another package, can extend and use your class. This is only really useful for inner classes.
  3. private – no other top level class can import and use your class. This is a bit of an odd situation but is useful for inner classes, detailed in another post.

Those are your 3 keywords, however there is actually a 4 level of access, called default. The default access level doesn’t use a keywork, so it would be used like follows :

class ClassAccessModifierExample
{
    public static void main(String[] args)
    {
        // do something!
    }
}

So our 4th access level is :

  • (default) – also called “package-private”, this class is only visible to classes in the same package.

So what is all the fuss about visibility about? Well it lets classes do various things,such as :

  1. Create an instance of the class
  2. Extend, sublass that class
  3. Access members of that class

One last thing to remember, is that a source file can only ever have one public or default class, it can’t have more than one of those. Also, private and protected can’t be at the top level.

  • You can’t have a private top level class, its useless.
  • You can’t have a protected top level class, since it goes against the principle of the protected access.

Consider the following valid example

// I'm public, and my name matches that of the source file
public class ClassAccessModifierExample
{
    public static void main(String[] args)
    {
        // do something!
    }


    // You can have as many protected classes as you want, accessible
    // to any classes that extend from the top level class, ClassAccessModifierExample
    protected class MyProtectedClass
    {

    }

    // Have as many private classes as you want, they are only accessible to the top level class,
    // ClassAccessModifierExample
    private class InnerClassThatIsPrivate
    {

    }
    
    // Nothing wrong with having a public inner either!
    public class PublicInner
    {
        
    }
}
// Default class here
class TopLevelDefaultClass
{

}

Thats it! If you’ve got any suggestions on how to improve this, please leave a comment :)