Java logo

Java without OOPs

Introduction

Although Java is an object orientated language, it is still possible to write some applications in Java with minimal knowledge of object orientated progranming (OOP). This might be necessary if Java is the only language available to you and you have no time to learn OOP and Java's implementation of it. If you don't need a graphical user interface you still do quite lot.

This is NOT a tutorial on Java! Rather, it shows a few examples of what you can do without needing to understand OOP.

Software needed for Java

To compile Java code you need install the Java SDK.

To run Java code you need to install the Java runtime - this is automatically installed when you install the Java SDK.

You can download these from Oracle's website

Hello World

First, here is the ususal "Hello World" program:

public class HelloWorld // This line creates the only class you need and you can call it whatever you like
{
	// This is the entry point for the application and is very similar to C
	public static void main(String[] args) // "String[] args" is a an array of strings passed to the program on the command line
	{
		System.out.printf("Hello World\n"); // this printf() works just like the C printf(). You just call it differently
	}
}
    

Compiling and running Java

You can write the code in a text editor and save it as "HelloWorld.java" and compile it using javac:

javac HelloWorld.java
    

This creates a HelloWorld..class file that holds Java code converted into Java bytecode for the Java virtual machine (JVM) to run.

The HelloWorld.class can be run by the JVM like this:

java HelloWorld
    

Adding functions

You can add functions/methods to your Java code like this:

public class Eaxmple1
{
    public static void main(String[] args)
    {
        func1();
        func2();
    }
    
    void func1()
    {
        System.out.printf("func1() called\n");
    }
    
    void func2()
    {
        System.out.printf("func2() called\n");
    }    
}
    

Types

Java has these types:

if, for, while and switch

The "if", "for", "while" and "switch" statements all behave like in C and several other languages with an important exception.

"if" and "while" conditions MUST be Boolen expressions. This C style of code is invalid:

int i = 10;
while(i)
{
    // do something with i
}
    

Classes, instances, constructors and references

Java holds code for methods within classes. Methods are like functions and classes are like libraries in traditional languages.

Some methods/functions can be called directly by using the name of the class/library they are in e.g System.out.printf(). In this case the class that holds the printf() method/function is nested within another class so there are two parts to the class/library name - "System.out".

Other methods require that first you create an "instance" of the class that holds the method using their "constructor". This return a "refernce" to the "instance". Then you can use the "reference" to call the methods.

This is similar to calling library funtion to give you handle (e.g. to file) and then using the handle with the other library functions (e.g. to read or write to the file).

You can think of calling the class "constructor" like calling the library fucntion that creates and returns a handle. The reference is like a handle.

// Java:
// Fred is a class
// ref is a reference
// new Fred() creates and returns the reference
Fred ref = new Fred();
    

To use the reference to call a method, use the format reference.method e.g ref.func1(). This is like calling a library func1(handle). The essential difference is that in Java the reference comes before the name of the function to call instead of calling a library function where the handle is the first parameter to the function.

Arrays

Arrays are created differently from in C. In Java an array must be created using "new" e.g.

int[] arr = new int[10];
    

The "int[] arr" on the left of the = does NOT create an array. It ONLY declares that "arr" can hold a reference to an array.

The "new int[10]" on the right of the = creates the array and returns the reference to it.

Once the array is created it can be used as expected:

arr[5] = 10;
int i = arr[5];
    

ArrayList

There is a more flexible version of an array called ArrayList. A normal array is created with a fixed size that can't be changed once it is created. An ArrayList lets you add and remove eleemts from the array similar to a linked list, but still allows you to read or write values to specific places in the array.

ArrayList<Integer> ar = new ArrayList<Integer>(); // create a new empty array integers
ar.add(10); // add a element to the array and set it to 10
ar.add(20); // add a element to the array and set it to 20
int i = ar.get(0); // retrieve the value of the first element of the array
ar.set(0, 30); // set element 0 of the array to a new value
ar.remove(0); // remove element 0 from the array. All the other elements move down 1
    

What are the benefits?

There are benefits to using Java even without fully exploiting its OOP capabilities:

Using Thread Pools

One of the most powerful classes Java offers allows you to you to:

import java.util.ArrayList; // declares we will use the ArrayList class
import java.util.List; // declares we will use the List class
import java.util.concurrent.*; // declares we will use several classes from the java.util.concurrent set of classes 

// This is the only class we need to write. Call it whatever you like
public class ExecutorServiceExample implements Callable<Integer> // declares we will have a call() method that returns an Integer
{
	// "final static" declares a constant
	final static int NUM_THREADS = 10;	// numbers of threads to use in the thread pool
	final static int NUM_TASKS = 10000; // numbers of tasks we want the thread pool to process
	final static int LOOP_SIZE = 100_000; // used in arbitary code in the task
	
	// the application starts here
	public static void main(String[] args)
	{
		// This creates a pool of threads to do your bidding
		ExecutorService execServ = Executors.newFixedThreadPool(NUM_THREADS);
		
		// This creates an ArrayList to hold references to the to the tasks you want done
		// The ExecutorService requires that the references are "Callable" which means they have a method called "call"
		// which we define below. This is the method that will be called by each thread.
		// The "<Integer>" declares that our call() method will return an Integer result.
		// We can choose a different return type if we wish
		ArrayList<Callable<Integer>> testsArrayList = new ArrayList<Callable<Integer>>();
		
		// We build the array of tasks we want done
		for(int counterInt = 0; counterInt < NUM_TASKS; counterInt++)
		{
			testsArrayList.add(new ExecutorServiceExample()); // this a separate reference to our class for each entry
		}
		
		
		try // This is compulsory exception handling code for errors that might occur
		{
			// Called the ExecutorService to process our array of tasks using the threads in the thread pool
			// It returns when all the tasks have been completed
			// "List<Future<Integer>>" is a List of Integers that will be filled with the results of
			// each task. The List is built up as each task completes
			// The "Future" indicates that this integer does not exist yet but will soon 
			List<Future<Integer>> resultList = execServ.invokeAll(testsArrayList);
			
			// we can process the results of all the tasks
			for(int counterInt = 0; counterInt < NUM_TASKS; counterInt++)
			{
				// retrieve result of each task
				Future<Integer> fut = resultList.get(counterInt);
				int resultInt = fut.get();
				System.out.println("Result of test " + counterInt + " = " + resultInt);
			}
		}
		catch (InterruptedException e) // This is compulsory exception handling code for errors that might occur
		{
			e.printStackTrace();
		}
		catch (ExecutionException e) // This is compulsory exception handling code for errors that might occur
		{
			e.printStackTrace();
		}
		
	}

	// This is the task you want the threads to execute
	// You can't change the name of the method/function, but you can choose the type of the value it returns
	@Override
	public Integer call() throws Exception
	{
		// ARBITARY CODE
		// put whatever calculation you want to here
		int valueInt = ThreadLocalRandom.current().nextInt(1, 1000);
		for(int counterInt = 0; counterInt < LOOP_SIZE; counterInt++)
		{
			valueInt += ThreadLocalRandom.current().nextInt(1, 1000);
			valueInt /= 2;
		}
		
		return valueInt; // return the result of your calculation here
	}
	
}
    

Home page