Practice Question to help understand the difference between i++ and ++i

Practice Question, Oracle Certified Associate: Java SE8 Programming (1Z0-808)

In this example, I will be going through an example of a Java SE Programming certification test.
The topic is integer increment- and decrements using i++ and ++i.

Q: What will the output be after code execution?

public class Demo {
    public static void main(String[] args) {
        int i = 0;
        int j = 6;
        do {
            if (i++ > --j) {
        } while (i < 3);
        System.out.println("i: " + i + ", j: " + j);

Choose one answer:

  • a) i: 2, j: 3
  • b) i: 3, j: 2
  • c) i: 3, j: 3
  • d) i: 4, j: 2
  • e) i: 4, j: 3





Click here to view answer

The answer is c).

The difference between i++ and –j when used inside a condition is that i++ increments after the condition has been checked, and –j is decreased before the condition is being checked.

Initial values: int i=0, j=6.
#1 Condition check if(0++ > –6) is the equivalent of if(0 > 5). After the condition, i=1, j=5.
#2 Condition check if(1++ > –5) is the equivalent of if(1 > 4). After the condition, i=2, j=4.’
#3 Condition check if(2++ > –4) is the equivalent of if(2 > 3). After the condition, i=3, j=3.
#3 is when we jump out of the do-while loop, since while(3 < 3) is false, resulting in the final values i=3 and j=3.




A recommended source for material to help you prepare for the certification exam can be found in Oracle’s web-site.

Structural Design Pattern: The Bridge Pattern, using a Java Example

Bridge Design Pattern

The Bridge Pattern is designed for enhanced flexibility – a programming design choice that may cover future uncertainty by decoupling abstraction and implementation of code.
It is part of a structural pattern, as it eases the design by making creating simpler relationships between the entities – allowing you to easily form larger structures using the simple relationships.

To get a better idea …

Imagine the relationship between a client and server. The client only need the interface that the server has implemented in order to know what we can and cannot do with the server.
You may for example choose to do this for security reasons – you wouldn’t want the client to handle all username and password transactions and validate themselves, would you?
Whatever your reasons may be, the Bridge Pattern can be useful in many such situations.

Advantages using the Bridge Pattern

  • By decoupling abstraction from the implementation, we gain greater flexibility as the two are independent.
  • We only need to know the interface, and do not need to know the actual implementation.
  • A great pattern to add cross-platform support (Java is an exception to this).

Disadvantages using the Bridge Pattern

  • Increases code complexity.
  • Hiding details from “client”.
  • Can have performance issues having to send messages along the bridge.


Bridge Pattern Example in Java

The UML Class diagram shows us the basic relationship between the Abstraction and Implementor. The way it could be implemented is demonstrated in the Java code below.

UML Class Diagram for the Bridge Design Pattern

In this Java Example, we have an Abstractor (imagine it to be the client) and the Implementor (imagine it to be the server).

The Abstractor expects an Implementor sent to it in the constructor. We do not know how the implementor intends to implement the operation. We only know what it implements.
As of such, inside the operation() method we run the implementor’s implementedOperation().

We have two different Concrete Implementors that run implementedOperation(), and prints out different strings to the console

The flexibility of the bridge design pattern allows us to easily add more Refined Abstractions from the Abstraction, or more Concrete Implementors as needed – without having to change existing code.

 * Copyright (C) 2017 Ivan Skodje
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * GNU General Public License for more details.
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <>.
public class Main

	/* Abstractor */
	abstract class Abstractor

		protected Implementor impl;

		public Abstractor(Implementor impl)
			this.impl = impl;

		public abstract void operation();

	/* Implementor */
	interface Implementor

		public void implementedOperation();

	/* Refined Abstraction 1*/
	class RefinedAbstraction1 extends Abstractor

		public RefinedAbstraction1(Implementor impl)

		public void operation()

	/* Concrete Implementor 1 */
	class ConcreteImplementor1 implements Implementor

		public void implementedOperation()
			System.out.println("Running implemented operation 1");

	/* Concrete Implementor 2 */
	class ConcreteImplementor2 implements Implementor

		public void implementedOperation()
			System.out.println("Running implemented operation 2");

	 * @param args the command line arguments
	public static void main(String[] args)
		// We create an instance of Main in order to run directly from main.
		// (Otherwise we will get a non-static variable error)
		Main main = new Main();;

	/* Run Demo */
	private void run()
		Implementor concreteImplementor1 = new ConcreteImplementor1();
		Abstractor refinedAbstraction1 = new RefinedAbstraction1(concreteImplementor1);

		Implementor concreteImplementor2 = new ConcreteImplementor2();
		refinedAbstraction1 = new RefinedAbstraction1(concreteImplementor2);


Running implemented operation 1 
Running implemented operation 2

You can find my additional demos on GitHub.