Skip navigation
1 2 Previous Next

hellofadude

18 posts
hellofadude

Java arrays in depth Blog

Posted by hellofadude Sep 26, 2014

Arrays in Java are a particular type of data structure that comprise of a fixed sized linear sequence conceptually similar in functionality to generic containers, a type from which they are easily distinguished by their characteristic ability to hold primitive as well as non-primitive types. Arrays ]]>

ints to hold a list of numbers, you could write the following expression like so:- int[] numList = new int[10];
The identifier numList holds a reference to an actual object that has space for up to ten references. It is worth mention that Java automatically initialises primitive arrays to zero and non-primitive arrays to null such that if you were to make a print of the above numList array you will be presented with zero values numbering 10. The most common way to initialise an array is within a for loop like so:- package arrays.java; import java.util.Arrays; import java.util.Random; public class InitialiseArray { static Random random = new Random(); public static int[] arrayInit(int[] array) { for(int i = 0; i < array.length; i++) array[i] = random.nextInt(array.length); return array; } public static void main(String[] args) { int[] numList = new int[10]; System.out.println(Arrays.toString(arrayInit(numList))); } } /** Output [3, 7, 2, 7, 8, 3, 3, 0, 9, 0] **/ Here, the arrayInit() method accepts an array of ints and initialises it with int values in a for loop using a random generator. The public interface of an array consists only of a length method that returns the number of elements within the array or more precisely, the size of the array. Arrays also provide you the means to return a more complex object from a method as opposed to single valued objects. It is also possible to create arrays implicitly by combining creation and initialisation into one step like so:- String[] greeting = { new String("Hello"), new String("Goodbye") }; //Aggregate initialisation int[] numbers = new int[]{ 4, 7, 10, 3, 5, 9, 14, 18, 30, 8, }; //Dynamic aggregate initialisation

Multidimensional arrays

Multidimensional arrays are arrays that have a multiple dimensions allowing the programmer to make use of a more complex data structure. To declare a multidimensional array you only need supply additional angle brackets to represent the number of dimensions. For instance, to create a two and three dimensional array of int, you would simply append the desired number of angle brackets:- int[][] ListA = new int[1][3]; // 2-D array int[][][] Listb = new int[2][3][2]; // 3-D array The idea is that each angle bracket represents a single dimension and in theory you can have as many of those as you want, though I suspect at a certain point the level of complexity might become somewhat intractable. For instance the 3-D array above can be read to mean the first dimension consists of two elements, each of which contain three elements in the second dimension. In the third dimension, each of these three elements in turn comprise of a further two elements. If you are new to multidimensional arrays, it is easy become confused. Initialising a multidimentional array with values in a for loop requires a certain level of finesse as it is not quite as straightforward a a 1-D array. The following code demonstrates how to initialises a 3-D array using nested loops:- package arrays.java; import java.util.Arrays; import java.util.Random; public class Initialising3DArray { static double[][][] a; static void init3DArray(int size, double start, double end) { Random rand = new Random(12); a = new double[rand.nextInt(size)][][]; if(start > end) throw new IllegalArgumentException("Start range should be less than end Range"); // Unchecked exception! double value = end - start; for(int i = 0; i < a.length; i++) { a[i] = new double[rand.nextInt(size)][]; for(int j = 0; j < a[i].length; j++) { a[i][j] = new double[rand.nextInt(size)]; for(int k = 0; k < a[i][j].length; k++) a[i][j][k] = rand.nextInt((int)value); } } } static void print() { System.out.println(Arrays.deepToString(a)); } public static void main(String[] args) { init3DArray(8,5,9); print(); } } In this example, a 3-D array of double is initialised with a random length first element. The second and third elements are initialised in a for and nested for loop respectively, again using random values. The result is a 'ragged' array where each vector in the array is of a different length. The final nested loop is used to add values into all elements of the array. Notice how Java automatically promotes int values to double expected by the init3DArray()method. The same effect can be observed in the last line of the method where the array is initialised with random values. In general, when two primitives are combined in a computation, Java will promote the smaller primitive to the same type as the larger primitive.

Arrays and generics

Because of erasure it is not possible to instantiate an array of parameterised types because arrays need to know about types to enforce type safety. You can nevertheless create an array of generic types, by creating an array of non-generified type and then casting back to an array of generic type:- package arrays.java; class GenericType<T> {} public class ArrayOfGenerics { public static void main(String[] args) { GenericType[] nonGenerifiedArray = new GenericType[6]; // "Unchecked" warning for array of generics - ok GenericType<Integer>[] generifiedArray = (GenericType<Integer>[])nonGenerifiedArray; for(int i = 0; i < generifiedArray.length; i++) generifiedArray[i] = new GenericType<Integer>(); // Array of generics } } Note that an array of generics will only hold other arrays of other generics and this is not the same thing as an array of parameterised type which is impossible because of the effects of erasure. However, you may parameterise the type of an array within a class or method:- package arrays.java; public class ParameterisedArrayTypes<T> { public T[] classParameterisedType(T[] type) { return type; } static <E> E[] methodParameterisedType(E[] type) { return type; } public static void main(String[] args) { ParameterisedArrayTypes<Integer> para = new ParameterisedArrayTypes<Integer>(); Integer[] iArray = para.classParameterisedType(new Integer[5]); Double[] dArray = methodParameterisedType(new Double[5]); String[] sArray = methodParameterisedType(new String[10]); } } The above example has two methods. The first method uses a class parameter to parameterise the type of the array, while the second method uses a method parameterto achieve the same effect. The advantage of a parameterised method is that it can be used independently of and in parallel with a parameterised class.

Generating data

Arrays are only as useful as how quickly and efficiently one might be able to populate them with data, perhaps for testing purposes. There are a number of ways to quickly generate data for arrays one of the most common of which is the overloaded fill() method in the Arrays class, which simply copies a value to each element in an array:- package arrays.java; import java.util.Arrays; class Start { public static void main(String[] args) { int[] a = new int[args.length]; Arrays.fill(a, 20); System.out.println(Arrays.toString(a)); } } public class FillingArrays { public static void main(String[] args) { Start.main(new String[8]); } } /** Output [20, 20, 20, 20, 20, 20, 20, 20] **/ The fill() method is overloaded for all primitive types as well as objects. Unfortunately it is severely limited because it can only fill an array with one value when most times you might need a range of values for your tests to come anywhere near realistic. One way to overcome this limitation is to use an object based data generator. By assigning responsibility for generating data to an interface, it becomes possible to share that functionality among a number of types. For instance, we might define an interface of a parameterised type that can be used to generate any type. We can call this Generator:- package arrays.java; public interface Generator<T> { T next(); } The interface has only one method next() that must be implemented by any subtype implementing this interface. It is now possible to quickly generate a variety of objects that can be used to initialise arrays For instance to create an array of unique string objects, we could implement a string generator like so:- package arrays.java; import java.util.Random; public class StringGenerator implements Generator<String> { private int length = 8; Random random = new Random(); char[] pickOne = ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ").toCharArray(); public String next() { char[] string = new char[length]; for(int i = 0; i < length; i++) string[i] = pickOne[random.nextInt(pickOne.length)]; return new String(string); } public static void main(String[] args) { StringGenerator gen = new StringGenerator(); String[] array = new String[10]; for(int i = 0; i < array.length; i++) array[i] = gen.next(); System.out.println(Arrays.toString(array)); } } /** output [grpvpNAr, nnbEbQHW, lQJxvspb, ObCuoabu, lUkcPEhY, KXIpGxbj, MsdcESuf, AtyDyITF, HIbWUszp, HfbsstMc] **/ The StringGeneratorclass implements the next() method within which a pseudo- randomised algorithm is used to generate unique string objects that are then used in the main() to initialise a String array. As opposed to implementing a generator for every object you might want to create, it might be more efficient to create a generic method capable of creating an array from any type:- package arrays.java; import java.lang.reflect.Array; import java.util.Arrays; public class ArrayGenerator { static String[] stringArray; static Integer[] intArray; private static int size = 10; @SuppressWarnings("unchecked") public static <T> T[] generateArray(Class<T> type) throws InstantiationException, IllegalAccessException { return (T[])Array.newInstance(type, size); } public static int length() { return size; } public static void main(String[] args) { StringGenerator gen = new StringGenerator(); try { stringArray = generateArray(String.class); intArray = generateArray(Integer.class); } catch (InstantiationException | IllegalAccessException e) { e.printStackTrace(); } for(int i = 0; i < ArrayGenerator.length(); i++) { stringArray[i] = gen.next(); intArray[i] = i; } System.out.println(Arrays.toString(stringArray)); System.out.println(Arrays.toString(intArray)); } } /** Output [AwOYakKc, UgciOWsH, ERRgKqqI, gmrzNtRc, TgzbxYAN, HiudPPOo, BtEMuHuL, yybvAeph, vVsriPrq, yyNKkMJd] [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] **/ The parameterised method generateArray()uses reflection to create an array of specified type and size. The decision of whether to use generics or object generators to quickly generate test data for use with arrays will be one of personal choice and know-how.

Array utilities

The Arrays class in the java.util package has a number of methods for manipulating arrays like sorting and searching operations. It also has an overloaded equals() method for comparing primitive and non-primitive arrays. For any two arrays to be equal, they must possess the same number of elements and each element in one must be equivalent to the corresponding element in the other array on the basis of the equals() method for each element. package arrays.java; import java.lang.reflect.Array; import java.util.Arrays; public class ArrayEquality { public static void main(String[] args) { //Non-primitive arrays Integer[] one = (Integer[])Array.newInstance(Integer.class, 4); Integer[] two = { new Integer(20), new Integer(20), new Integer(20), new Integer(20) }; Arrays.fill(one, 20); System.out.println("1: " + Arrays.equals(one,two)); one[3] = 21; System.out.println("2: " + Arrays.equals(one,two)); //Primitives arrays double[] pOne = new double[4]; Arrays.fill(pOne, 5); double[] pTwo = new double[5]; Arrays.fill(pTwo, 5); System.out.println("4: " + Arrays.equals(pOne, pTwo)); double[] pThree = new double[] {new Double(5), new Double(5), new Double(5), new Double(5)}; System.out.println("5: " + Arrays.equals(pOne, pThree)); } } /** Output 1: true 2: false 4: false 5: true */ In the main() two non-primitive arrays are created, first using reflection and the second is created implicitly. Both arrays have four elements and contain the number 20. The Arrays.equals() method agrees these two to be equivalent. When an element in one array is change, this is reflected in the array comparison. The equals() works the same way in an array of primitives The Arrays.sort() method allows you to sort through an array of elements that implement the Comparable interface or that has an associated Comparator:- The following code sorts through an array of ints and non primitive Strings package arrays.java; import java.lang.reflect.Array; import java.util.*; @SuppressWarnings("serial") class ArrayData<T> extends ArrayList<T> { public ArrayData(Generator<T> generator, int size) { for(int i = 0; i < size; i++) add(generator.next()); } } public class AllSorts { @SuppressWarnings("unchecked") public static <T> T[] createArray(Class<T> aType, Generator<T> generator, int size) { T[] array = (T[]) Array.newInstance(aType, size); return new ArrayData<T>(generator, size).toArray(array); } public static void main(String[] args) { Random generator = new Random(); int[] one = new int[8]; for(int i = 0; i < one.length; i++) one[i] = generator.nextInt(200); System.out.print("Before sort: " + Arrays.toString(one) + "\n"); Arrays.sort(one); System.out.print("After sort: " + Arrays.toString(one) + "\n"); System.out.println(); String[] two = createArray(String.class, new StringGenerator(), 5); System.out.print("Before sort: " + Arrays.toString(two) + "\n"); Arrays.sort(two); System.out.print("After sort: " + Arrays.toString(two) + "\n"); Arrays.sort(two, String.CASE_INSENSITIVE_ORDER); System.out.print("Case sensitive order: " + Arrays.toString(two) + "\n"); } } /** Output Before sort: [194, 152, 65, 72, 175, 162, 23, 196] After sort: [23, 65, 72, 152, 162, 175, 194, 196] Before sort: [iFrPcQus, APvoBpaN, pJGKftOz, eVKaFVYz, pgOxbHCq] After sort: [APvoBpaN, eVKaFVYz, iFrPcQus, pJGKftOz, pgOxbHCq] Case sensitive order: [APvoBpaN, eVKaFVYz, iFrPcQus, pgOxbHCq, pJGKftOz] **// The static createArray() method returns an array of any type from an ArrayList by accepting a Class type, generator object and a size argument. Note the compiler uses it's autoboxing mechanism to represent the int primitive type as an Integer object on the heap, which as it happens implements the Comparable interface. The same is true of the String class. The final sort() method uses the CASE_INSENSITIVE_ORDER attribute of the String class to group strings together regardless of case. The Collections class provides a static reverseOrder() method that returns a Comparator that imposes the reverse of the natural ordering of a collection of objects that implement the Comparable interface:- package arrays.java; import java.util.Arrays; import java.util.Collections; import java.util.Random; public class TestReverseOrder { static Random random = new Random(); static Generator<Integer> generator() { return new Generator<Integer>() { public Integer next() { return random.nextInt(200); } }; } public static void main(String[] args) { Generator<Integer> generator = generator(); Integer[] reversed = AllSorts.array(Integer.class, generator, 20); Arrays.sort(reversed); System.out.println("Sorted array: " + Arrays.toString(reversed)); Arrays.sort(reversed, Collections.reverseOrder()); System.out.println("Reversed array: " + Arrays.toString(reversed)); } } /** Output Sorted array: [13, 19, 32, 36, 43, 48, 68, 74, 75, 89, 99, 121, 121, 146, 150, 155, 171, 173, 177, 183] Reversed array: [183, 177, 173, 171, 155, 150, 146, 121, 121, 99, 89, 75, 74, 68, 48, 43, 36, 32, 19, 13] **/ In this example, the generator() method uses an anonymous class to return an integer generator. In the main(), the second version of the sort() method sorts the specified array using the supplied Comparator object. The Arrays class has quite a number of other useful methods that are worth checking out, for instance the overloaded binarySearch(). method can be used to search through a specified array for a specific value. The java.lang.reflect.Array API is another useful class that provides methods to dynamically create and access arrays. An example of this is the newInstance() method which is used in several previous examples.

In part two of this series, I demonstrated the effect of erasure on type parameters within the body of a class. I used examples to show how type parameters were limited to accessing methods of the rootObject class irrespective of the actual type with which it was replaced at a later time. I also demonstrated how to specify a bound with which one may constrain the type parameter so as to have access to methods other than those available toObject within the body of a class. Here is another example code to emphasize the point; in this instance we have an oversimplified parameterised Converter class, whose type parameter is constrained to the Currency class and it's subtypes. The Converter class has only one method - convert() - that checks the equivalence of the name of the type parameter as returned by thegetCurrency() method in another class, and returns a simple string on that basis. Here is the code:- package generics.java.erasure; abstract class Currency { public String getCurrency() { return this.getClass().getSimpleName(); } } class Dollar extends Currency { } public class Converter<T extends Currency> { private T type; static int GBP; public Converter(T aType) { type = aType; } public String convert(int amt) { if(type.getCurrency().equals("Dollar")) return "Value of $" + amt + " is " + "

Java's generics is implemented using erasure which is a mechanism that removes specific type information within the body of a generic class or method. Essentially, when you instantiate a generic class with an actual type, the syntax within the generic class would suggest that every occurrence of th ]]>

package generics.java.erasure; class Shrub { void grow(){ System.out.println("growing"); } } public class ErasedType<T> { private T type; void set(T aType) { type = aType; } void fertilise() { //! type.grow(); Compiler error } public static void main(String[] args) { ErasedType<Shrub> plant = new ErasedType<Shrub>(); plant.set(new Shrub()); plant.fertilise(); } } ErasedType<T> is a class that uses an unbounded type parameter which the compiler erases to Object within the body of the class. Effectively, the only methods available to the generic type reference are those methods available to Object and this is inspite of the replacement in the main() of the type parameter with an actual type Shrub. Because of this, the compiler is unable to map the requirement to make a call grow(). If you want the compiler to be able to call methods other than those available to Object, or in other words methods from within other classes, then you must include a bound that restricts the type parameter to conform to subtypes of a particular type. You do this by reusing the extends keyword in relation to the type parameter:- package generics.java.erasure; public class ErasedType2<T extends Shrub> { private T type; void set(T aType) { type = aType; } void fertilise() { type.grow(); //ok } public static void main(String[] args) { ErasedType2<Shrub> plant = new ErasedType2<Shrub>(); plant.set(new Shrub()); plant.fertilise(); } } /* Output growing *// By specifying a bound you in effect give the compiler a hint of context because in those circumstances the type parameter is erased to the specified bound. As you can see with this technique, it is now possible to call the grow() method. You might notice that this is exactly the same thing as replacing the type parameter with the actual class in a non-generic class:- package generics.java.erasure; public class ErasedType3 { private Shrub type; void set(Shrub aType) { type = aType; } void fertilise() { type.grow(); } public static void main(String[] args) { ErasedType3 plant = new ErasedType3(); plant.set(new Shrub()); plant.fertilise(); } } /* Output growing *// The above code inevitably leads to the question - "so what's the point of generics?". The power of generics become apparent when there is usually a degree of complexity in it's application in terms of classes that cut across types as opposed to being limited to a specific type and it's subtypes. Regardless of how one may feel about it, the fact is erasure has substantial implication for the way generics operate and having an understanding of the circumstances surrounding it's implementation and it's limitations, might serve as a useful precept if you want to be able to effectively cope with some of it's peculiarities. Far from being just another convenient language feature, erasure may be seen from the perspective of being the result of a compromise that became necessary following the requirement to ensure that the implementation of generics, which were not made a part of the Java language from the beginning (an oversight perhaps?), did not compromise backward compatibility with contemporary libraries - i.e classes continued to mean what they meant as before - and provided a safe path to migration - migration compatibility - for developers who wanted to migrate to generics. The solution was to make it such that each library and application was independent of all others regarding whether generics was being used or not. Hence, by erasing all evidence that a particular library or application is using generics at runtime, it was possible for generified clients to coexist with non-generified libraries. You can certainly get a sense of this compromise from the fact that generics is not so tightly enforced in Java:- package generics.java.erasure; class GenericType<T> { private T type; public void set(T anyType) { type = anyType; } public T get() { return type; } } class DerivedOne<T> extends GenericType<T> {} // ok - parameterised class DerivedTwo extends GenericType {} // Warning, but will compile! public class UnenforcedGenerics { public static void main(String[] args) { DerivedTwo dt = new DerivedTwo(); dt.set("erased"); // Warning only! String anObject = (String)dt.get(); // cast needed } } From the example, it is clear that a non-parameterised type may inherit from a parameterised type, albeit with a warning! The only difference will be the need to perform a cast when retrieving the stored object. Furthermore, according to official JDK documentation, you should be able to return an array of "type variable" objects using the Class.getTypeParameters() method; if we try this, the result is certainly not what you would expect given it's 'extraordinary' description:- package generics.java.erasure; import java.util.*; class Flat {} class Building<X> extends ArrayList<X> {} public class LostTypeInformation { public static void main(String[] args) { List<Double> decimals = new ArrayList<Double>(); Map<Integer, String> var = new HashMap<Integer, String>(); Building<Flat> estate = new Building<Flat>(); for(int i = 0; i < 10; i++) estate.add(new Flat()); System.out.println(Arrays.toString(decimal.getClass().getTypeParameters())); System.out.println(Arrays.toString(var.getClass().getTypeParameters())); System.out.println(Arrays.toString(estate.getClass().getTypeParameters())); } } /* Output [E] [K, V] [X] *// The output returns something that looks more like parameter type identifiers, and whatever it is, it is certainly nothing to do with actual types. To get your mind around what is possibly a lot of confusion it helps to consider the motivations behind generics and the choices that were available to early Java designers in order to understand why it works the way it does in Java. The initial the motivation behind generics was to loosen in a significant way, the constraints on the types your classes and methods work with i.e. allow you the programmer to write more generalised code. Early Java designers realised they could achieve this by allowing the compiler to undertake type checking and casting only at the 'boundaries' - i.e. the points in your program where objects enter and leave a method - to ensure internal consistency in the way types are used. This made it possible for the compiler to use it's erasure to remove all type information in the body of a method or class thereby solving the backward compatibility problem. For instance, observe the methods in the following class. The first method returns a generic array of the specified size while the second method returns a Collection of the specified type and size. Note that there is no specific type information inside either method:- package generics.java.erasure; import java.lang.reflect.Array; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; public class BoundaryTypeChecking<T> { private Class<T> type; public BoundaryTypeChecking(Class<T> aType) { this.type = aType; } @SuppressWarnings("unchecked") T[] createArray(int size) { return (T[])Array.newInstance(type, size); // Warning Unchecked cast } Collection<T> create(T type, int size) { // Boundary Collection<T> list = new ArrayList<T>(); for(int i = 0; i < size; i++) list.add(type); return list; } public static void main(String[] args) { BoundaryTypeChecking<String> s = new BoundaryTypeChecking<String>(String.class); System.out.println(Arrays.toString(s.createArray(10))); System.out.println(s.create("Boo", 10)); } } /* Output [null, null, null, null, null, null, null, null, null, null] [Boo, Boo, Boo, Boo, Boo, Boo, Boo, Boo, Boo, Boo] *// Even though the type reference in the above example is stored as Class<T>, erasure erases this to just Class. Consequently, the Array.newInstance() method in the body of the createArray() method, does not have any information about specific type and hence the need for an explicit cast at the point of exit. The same logic applies to the create() method where if we accept that there is no type information in the body of the method, then the only logical explanation for being able to recover the correct type from the Collection is because the compiler has already undertaken type checking at the boundary of the method. To be precise, Collection<T> has no type information and is simply stored as Collection. Same goes for the ArrayList, however the compiler is still able to ensure the correct type at the point of entry at compile time. Because of erasure it is useful to remind yourself that your type references are only objects within the body of your class.

Capturing erased type

The implication of this loss of type information is that you can not use type parameters in operations that explicitly refer to runtime types like casts, instanceof operations and expressions beginning with new. There are a number of ways to compensate for the loss of type information. For instance, to check the runtime type of an object, you can insert a type tag and then use the Class.isInstance() method instead, here's how:- package generics.java.erasure; class Meal { public Meal() {} } class Breakfast extends Meal {} public class CaptureType<T> { Class<T> type; public CaptureClassType(Class<T> anyType) { this.type = anyType; } public static void main(String[] args) { CaptureType<Breakfast> breakfast = new CaptureType<Breakfast>(Breakfast.class); CaptureType<Meal> meal = new CaptureType<Meal>(Meal.class); System.out.println(breakfast.type.isInstance(new Meal())); System.out.println(breakfast.type.isInstance(new Breakfast())); System.out.println(meal.type.isInstance(new Meal())); System.out.println(meal.type.isInstance(new Breakfast())); } } /* Output false true true true *// By passing in a type tag you can recover type information and still be able to perform the kind of type checking you would have got using the instanceof keyword. The following example demonstrates how to recover type information that would be useful in instantiating new types:- package generics.java.erasure; import java.util.HashMap; import java.util.Map; public class CaptureTypeFromContainer { @SuppressWarnings("serial") public static class AMap<T> extends HashMap<String, Class<?>> { T type; public void addType(String typeName, Class<?> type) { put(typeName, type); } @SuppressWarnings("unchecked") public T createNew(String typeName) { for(Map.Entry<String, Class<?>> anEntry : entrySet()) if(anEntry.getKey().equalsIgnoreCase(typeName)) { try { type = (T) anEntry.getValue().newInstance(); System.out.println("Correct class - required: " + typeName + "\n" + "found: " + anEntry.getKey()); } catch(InstantiationException e) { System.out.println("Unable to create"); } catch(IllegalAccessException e) { System.out.println("Unable to Access!"); } } else { System.out.println("Wrong class - required: " + typeName + "\n" + "found: " + anEntry.getKey()); } return type; } T get() { return type; } } public static void main(String[] args) { CaptureTypeFromContainer.AMap<Meal> meal = new CaptureTypeFromContainer.AMap<Meal>(); meal.addType("Meal", Meal.class); meal.addType("Breakfast", Breakfast.class); Meal meal2 = meal.createNew("meal"); System.out.println(meal2.getClass().getSimpleName()); } } /* Output Wrong class - required: meal found: Breakfast Correct class - required: meal found: Meal Meal *// The above code uses a nested Map to store an objects class name as it's key and type as the corresponding value. You can return a new type by calling the createNew() method with a specified type name. If the type exists in the container, a new instance is created and cast to the correct type. Again, the cast is necessary because erasure erases type information. Note that this version of newInstance() assumes it is working with a class that has a no args constructor. A more flexible approach to instantiating new types would be to use explicit factories whose type can be constrained only to those classes implementing it to dynamically instantiate objects at runtime like so:- package generics.java.erasure; interface Factory<T> { T create(String arg); } class Batman { String name; public Batman(String hero) { this.name = hero; System.out.println(hero); } static class HeroFactory implements Factory<Batman> { public Batman create(String name) { return new Batman(name); } } } class Spiderman { String name; public Spiderman(String hero) { this.name = hero; System.out.println(hero); } static class HeroFactory implements Factory<Spiderman> { public Spiderman create(String name) { return new Spiderman(name); } } } class StringFactory implements Factory<String> { public String create(String aString) { return new String(aString); } } class TypeMaker<T> { private T aType; public <I extends Factory<T>> TypeMaker(I afactory, String arg) { aType = afactory.create(arg); } public T getType() { return aType; } } public class Factories { public static void main(String[] args) { TypeMaker<Batman> hero1 = new TypeMaker<Batman>(new Batman.HeroFactory(), "Batman"); TypeMaker<Spiderman> hero2 = new TypeMaker<Spiderman>(new Spiderman.HeroFactory(), "Spiderman"); TypeMaker<String> fact = new TypeMaker<String>(new StringFactory(), "\"Good sense is equally distributed among men\" "); System.out.println(fact.getType()); } } /* Output Batman Spiderman "Good sense is equally distributed among men" *// The TypeMaker constructor accepts only classes that implement the Factory interface type and because you have explicit factories, unlike the previous example, you are not limited to being able to instantiate only those classes that have a default constructor. You can achieve a similar thing with reflection using the newInstance() method that accepts initialisation arguments:- package generics.java.erasure; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; class MyType { public MyType(String s) { System.out.println(s); } } public class InstantiateTypeWithReflection<T> { Class<T> type; public InstantiateTypeWithReflection(Class<T> aType) { this.type = aType; } public T createNew() { T t = null; try { Constructor<T> constructor = type.getConstructor(String.class); try { t = constructor.newInstance("MyType created Successfully!"); } catch (InstantiationException iException) { System.out.println(iException); } catch (IllegalAccessException iAException) { System.out.println(iAException); } catch (IllegalArgumentException iAException) { System.out.println(iAException); } catch (InvocationTargetException iTException) { System.out.println(iTException); } } catch(NoSuchMethodException nSMException) { System.out.println(nSMException); } catch(SecurityException sExeption) { System.out.println(sExeption); } return t; } public static void main(String[] args) { InstantiateTypeWithReflection<MyType> reflector = new InstantiateTypeWithReflection<MyType>(MyType.class); reflector.createNew(); } } /* Output MyType created Successfully! *// The version of the newInstance()method accepts varargs lists, which means you can work with both no args constructor and constructors that require arguments.

Generics and Arrays

Because erasure ensures the runtime type of an array can only be Object[], creating an array of generics can become slightly confusing, take a look at this code:- package generics.java.erasure; class Generic<T> {} public class ArrayOfGeneric { public static void main(String[] args) { // Generic<String>[] genArray = new Generic<String>[3] // Illegal syntax // Generic<String>[] genArray = (Generic<String>[])new Object[5]; // Class cast exception Generic<String>[] genArray = (Generic<String>[])new Generic[5]; // ok! Runtime type is raw //! genArray[0] = new Object(); // Compiler error for(int i = 0; i < genArray.length; i++) genArray[i] = new Generic<String>(); for(int i = 0; i < genArray.length; i++) System.out.println(genArray[i]); System.out.println(genArray.getClass().getSimpleName()); } } /* Output generics.java.erasure.Generic@15db9742 generics.java.erasure.Generic@6d06d69c generics.java.erasure.Generic@7852e922 generics.java.erasure.Generic@4e25154f generics.java.erasure.Generic@70dea4e Generic[] *// The first line in the main() of this example shows it is not possible to create an array of generics in the normal way you would normally create arrays of other types. This is because the runtime type of an array of generics is erased to an array of Object, but the compiler will still not allow you to cast an array of Object to an array of generics. The only way to create an array of generics is to create an array of the erased type and then cast that back to the array of generics. Once you successfully create an array of generics, you get the normal compile time type checking. Within the body of a class, you can create a generic type array either by casting an Object[] array to a type array T[] within the constructor or by using an Object[] array and casting it's elements to T only when required in a convenience get() method for example. Either way you still lose valuable type information about the underlying array implementation, which must be erased to Object[] at runtime. The best way to get around this is to use reflection by passing a type tag to the Array.newInstance() method to create an array of specified dimensions and then cast the result of that to generic type array T[], Here's how:- package generics.java.erasure; import java.lang.reflect.Array; import java.util.Random; public class GenericArray<T> { private T[] anArray; @SuppressWarnings("unchecked") public GenericArray(Class<?> type, int size) { anArray = (T[])Array.newInstance(type, size); } public void add(int index, T anObject) { anArray[index] = anObject; } public T get(int index) { return anArray[index]; } public T[] impl() { return anArray; } public static void main(String[] args) { GenericArray<Integer> holder = new GenericArray<Integer>(Integer.class, 10); Integer[] implementation = holder.impl(); // underlying type information for(int i = 0; i < 10; i++) { holder.add(i, i*new Random().nextInt(20)); } for(int i = 0; i < 10; i++) System.out.print(holder.get(i).toString() + " "); System.out.println(); System.out.println("generic array implementation: " + implementation) } } /* Output 0 18 30 51 68 85 84 105 144 117 generic array implementation: [Ljava.lang.Integer;@7852e922 *// Using this technique, it is clear that we can retain the type of the underlying array implementation as well as having access to the elements within the array. The benefits of understanding the effects and limitations imposed by erasure and how you might overcome it far outweigh any effort and makes you a more effective programmer.

In computer programming, generalisation is understood to be a noble pursuit and a fundamental tool for achieving reusability, the idea being that a programmer can be more expressive when he has tools that work with many types. You might recognise the effect of generalisation in many interrelated con ]]>

Class class, objects of which are used to create objects of your own classes.You will find that containers are a quite common theme in Java and they can be manifested in very many different forms, however the basic idea is always the same. A container contains variables and setter() and getter() methods to access and manipulate those variables. For example, Java's Stack class represents a last-in-first-out (LIFO) type of container where the last object you put in is the first one you get out. A good example is a magazine clip for an automatic handgun. You will find that such a clip has a sort of spring mechanism that you push down as you load each bullet and pushes up each time you unload one. If we were to try to implement such a mechanism, we might make an abstraction that would allow us to hold bullets in a type of list:- package generics.java; import java.util.ArrayList; class Bullet { private static int count = 0; private final long id = count++; public String toString() { return this.getClass().getSimpleName() + " " + id; } } public class Ammunition<T> extends ArrayList<T> { Class&ltT&gt type; public Ammunition(Class<T> bullet) { type = bullet; } public void put(int size) { for(int i = 0; i < size; i++) { try { add(type.newInstance()); } catch (InstantiationException e) { System.out.println(e); } catch (IllegalAccessException e) { System.out.println(e); } } } } Here, the Ammunition class is a type of ArrayList that can hold any type but in this example will be used to hold Bullet(s). Notice the use of a type tag to enable the retention of type information. A call to the put() method allows us to populate the list with Bullet objects using the Class.newInstance() method. The following linked Stack is a general purpose container that can be used to hold any type including Bullet like so:- package generics.java; public class Stack<T> { private static class Element<E> { E type; Element<E> currentElement; Element() { type = null; currentElement = null; } Element(E aType, Element<E> nextElement) { this.type = aType; this.currentElement = nextElement; } boolean end() { return type == null && currentElement == null; } } private Element<T> topElement = new Element<T>();// End sentinel public void push(T aType) { topElement = new Element<T>(aType, topElement); } public T pop() { T pop = topElement.type; if(!topElement.end()) topElement = topElement.currentElement; return pop; } public static void main(String[] args) { Ammunition<Bullet> bullets = new Ammunition<Bullet>(Bullet.class); bullets.put(7); Stack<Bullet> magazine = new Stack<Bullet>(); Bullet[] holder = new Bullet[bullets.size]; int index = 0; for(Bullet aBullet : bullets) { magazine.push(aBullet); holder[index++] = aBullet; } System.out.print("push(): " + Arrays.asList(holder)); Bullet aBullet; System.out.print("pop(): " + " ["); while ((aBullet = magazine.pop()) != null) if(aBullet.id == 0) { System.out.print(aBullet + "]"); } else { System.out.print(aBullet + ", "); } } } /* Output push(): [Bullet 0, Bullet 1, Bullet 2, Bullet 3, Bullet 4, Bullet 5, Bullet 6] pop(): [Bullet 6, Bullet 5, Bullet 4, Bullet 3, Bullet 2, Bullet 1, Bullet 0] *// In this example, the Stack container uses a nested class Element, to hold instances of particular types in this case Bullet objects. Each call to the push() method creates a new Element that holds a link to the previous Element within it. Calling the pop() method retrieves each element in reverse. Notice the topElementobject also works like an end sentinel to signal when the stack is empty. The most interesting part of this example is how the nested class is used as a linked container

Generic interfaces

You can also use type parameters with interfaces in much the same way as you do with classes. One of my favorite examples is the Fibonacci sequence. A fibonnaci sequence is a sequence of numbers where each subsequent number is a sum of the previous two. We can use a Generator interface to implement an abstraction of the process of generating a sequence of numbers. In the following example, the next() method will perform this function:- package generics.java; interface Generator<T> { T next(); } public class FibonacciSequence { class Sequence implements Generator<Integer> { private int seed = 0; public Integer next() { return funct(seed++); } private int funct(int next) { if(next < 2) return 1; return funct(next - 2) + funct(next - 1); } } public static void main(String[] args) { FibonacciSequence outer = new FibonacciSequence(); FibonacciSequence.Sequence sequence = outer.new Sequence(); for(int i = 0; i < 20; i++) { System.out.print(sequence.next() + " "); } } } /* Output 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 *// In this example, we use an inner class to implement the Generator. The algorithm that produces a fibonacci series is implemented in the funct() method which is in turn called by the implemented next() method. The autoboxing mechanism makes it possible for the int primitive returned by the funct() method to be converted to an Integer object expected by the next() method. To make this class work with the foreach statement, we could use the adapter design pattern to make it iterable like so:- package generics.java; import java.util.Iterator; public class FibonacciAdapter implements Iterable<Integer> { FibonacciSequence outer = new FibonacciSequence(); FibonacciSequence.Sequence sequence = outer.new Sequence() int counter; FibonacciAdapter(int count) { this.counter = count; } @Override public Iterator<Integer> iterator() { return new Iterator<Integer>() { @Override public boolean hasNext() {return counter > 0; } @Override public void remove() { throw new UnsupportedOperationException(); } @Override public Integer next() { counter--; return sequence.next(); } }; } public static void main(String[] args) { for( Integer next : new FibonacciAdapter(20)) System.out.print(" " + next); } } /* Output 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 *// When you implement the Iterable<T> interface you must implement the iterator() method to return an Iterator<T> over elements of the specified type. In this example, an anonymous class is used to return an Iterator object that implements methods by which you might iterate over a sequence. Notice here that the type parameter is replaced with the actual type over which we need to iterate. Also notice the use of a counter to control the number of iterations. Here is a variation of the same idea this time using a nested class, it really is a matter of design preference:- package generics.java; import java.util.Iterator; public class FibonacciAdapterTwo implements Iterable<Integer> { int counter; FibonacciAdapterTwo(int count) { counter = count; } static class IterableFibonacci implements Iterator<Integer> { FibonacciSequence outer = new FibonacciSequence(); FibonacciSequence.Sequence sequence = outer.new Sequence(); private int counter; public IterableFibonacci(int count) { this.counter = count; } @Override public boolean hasNext() { return counter > 0; } @Override public void remove() { throw new UnsupportedOperationException(); } @Override public Integer next() { counter--; return sequence.next(); } }; public Iterator<Integer> iterator() { return new IterableFibonacci(counter); } public static void main(String[] args) { for(Integer next : new FibonacciAdapterTwo(20)) System.out.print(" " + next); } } /* Output 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 *// Note that a nested class by definition has no access to the non-static elements of its enclosing class. To get around this you can create an instance of the nested class in the enclosing class and then pass values through this instance as demonstrated above; or in the alternative, you could choose to make the outer class member variable staticif you find this to be convenient.

Generic methods

Generic type parameters can also be used with methods in a way that makes it possible to vary the method independently of it's class and give the effect of the method being somehow overloaded. To parameterise a method, you place the type parameter in angle brackets before the return type like so:- package generics.java; class ArbitraryType {} public class GenericMethod { public static <T> String overloaded(T aType) { return aType.getClass().getName(); } public static void main(String[] args) { System.out.println(overloaded(new ArbitraryType())); System.out.println(overloaded(2.55)); System.out.println(overloaded("A String type")); System.out.println(overloaded(2.99F)); } } /* Output generics.java.ArbitraryType java.lang.Double java.lang.String java.lang.Float *// Because of the type parameter and type argument, we are able to pass in any type and hence the effect of the method being overloaded. You could of course specify an actual type in place of the type argument to restrict the use of the method to that particular type, but that is what would happen without the type parameter anyway and of course with generics, you can constrain the type parameter by specifying a bound as a way to exercise more control over the how the method is used. Here is container that can be used to generate, hold and iterate over any type, in addition to being able to create generic type generator:- package generics.java; import java.util.Iterator; public class TypeGenerator<T> implements Generator<T>, Iterable<T> { private Class<T> type; private int counter = 0; public TypeGenerator(Class<T> aType){ this.type = aType; } public TypeGenerator(Class<T> aType, int howMany) { this.type = aType; this.counter = howMany; } class IterableGenerator implements Iterator<T> { @Override public boolean hasNext() { return counter > 0; } @Override public T next() { counter--; return (T)TypeGenerator.this.next(); } @Override public void remove() { throw new UnsupportedOperationException(); } } public Iterator<T> iterator() { return new IterableGenerator(); } public T next() { try { return type.newInstance(); } catch (Exception anException) { throw new RuntimeException(anException); } } public static <T> Generator<T> create(Class<T> aType) { return new TypeGenerator<T>(aType); } } Note the create() method returns a non iterable Generator <T> reference only. Here is how to use the class:- package generics.java; public class GenerateTypes { public static void main(String[] args) throws ClassNotFoundException { Generator pGen = TypeGenerator.create(Piano.class); for(int i = 0; i < 9; i++) System.out.print(pGen.next() + " "); System.out.print("\n"); TypeGenerator bullGen = new TypeGenerator<>(Bullet.class, 6); for(Bullet aBullet : bullGen) System.out.print(aBullet + " "); } } /* Output Piano Piano Piano Piano Piano Piano Piano Piano Piano Bullet 0 Bullet 1 Bullet 2 Bullet 3 Bullet 4 Bullet 5 *// In the GenerateTypes class we use two methods to create TypeGenerator objects. The generic create() method returns a Generator reference and therefore is not iterable, however by using the new keyword to create a new TypeGenerator, a fully iterable object that can be used with the foreach method is returned. Generics are a very useful addition no doubt, to the Java programming language, and would seem, to the uninformed at least, to be the result of a logical and painless evolution. However it does possess some peculiarities that betray something of it's rather 'interesting' journey with the Java programming language.

Runtime type information (RTTI) refers to the correct identification of the type of your objects at run time. When you write code, it is generally desirable to do so in a way that takes advantage of OOP features like encapsulation and inheritance to make your program easily extensible, by for instance, as much as possible manipulating references to base classes and letting polymorphism work for you. Essentially, when you create a new object with a base class reference, the process necessarily involves an upcast to the base class from a more specialised type. There are many advantages to this style of programming not least of which includes the ability to simulate a more dynamic behaviour. Upcasting is a fairly straightforward process that the Java interpreter undertakes automatically, because there is very little risk associated with it. RTTI describes the reverse of this process when you wish to focus on a specific type for example to perform a particular operation. For instance, consider the following Game class hierarchy:- package runtime.types.java; abstract class Game { public int players; public String toString() { return "Game"; } void play() { System.out.println("playing " + this + "()"); } } class Charade extends Game { public String toString() { return "CharadeGame"; } } class Chess extends Game { public String toString() { return "Chess"; } } class CardGame extends Game { public String toString() { return "CardGame"; } } class BlackJack extends CardGame { public void shuffle() { System.out.println("Shuffle cards"); } public String toString() { return "BlackJack"; } } class OnlineGame extends Game { public String toString() { return "OnlineGame"; } } This is a fairly accurate representation of the structure of libraries that exist within an OO paradigm, even though in reality some classes inherit from base classes in other packages. In the following code a List is configured to hold subtypes of the abstract Game class. Each type ofGame is upcast to the List container which treats all elements as Game references having no memory of individual types. We can identify the benefit of RTTI in the playGame() method where we iterate through the list and the correct type is identified in the call toplay() because polymorphism allows us to make the correct binding at runtime:- package runtime.types.java; import java.util.Arrays; import java.util.List; public class Arcade { static void playGame(List<Game> options) { for(Game selection : options) selection.play(); } public static void main(String[] args) { List<Game> games = Arrays.asList(new Chess(), new CardGame(), new BlackJack()); playGame(games); } } /* Output playing Chess() playing CardGame() playing BlackJack() *// The above example is the most basic form of RTTI and why polymorphism is understood to be a general goal in object oriented programming. There are other circumstances when you might need to identify a specific type, perhaps to enable some operation unique to a specific type, circumstances for which you can not rely on polymorphism by itself. Java allows you to discover runtime type information in one of two ways. The first approach assumes all type information is available at compile time which you can obtain by querying the object reference. For instance, suppose we wanted to ensure the cards are shuffled before playing a game ofBlackJack. We could use RTTI to identify this specific type in order to call the appropriate method:- package runtime.types.java; import java.util.Arrays; import java.util.List; public class GettingType { public static void playGame(List<Game> options) { for(Game selection : options) { Class<? extends Game> type = selection.getClass(); if(type.isAssignableFrom(BlackJack.class)) ((BlackJack)selection).shuffle(); selection.play(); } } public static void main(String[] args) { List<Game> games = Arrays.asList(new Chess(), new BlackJack(), new Charade()); playGame(games); } } /* Output playing Chess() Shuffle cards playing BlackJack() playing Charade() *// In this instance, we query the object reference for type information using thegetClass() method, and then apply theisAssignableFrom() method to the resulting reference determine if this class is the same or a superclass of theBlackJack class. If it is, we cast the object to aBlackJack object and then call shuffle(). The logic of type as you will no doubt come to understand is sound and quite uncomplicated. You can also use theinstanceof keyword to check for the type of an object, for example prior to making a cast:- package runtime.types.java; public class TypeTest { public static void main(String[] args) { Game aGame = new BlackJack(); if(!(aGame instanceof BlackJack)) System.out.println("Not an instance"); ((BlackJack)aGame).play(); } } /* Output playing BlackJack() *// The other approach to discovering type information is to make use of a reflection mechanism by which means you can discover and use previously unavailable class information, exclusively at runtime. In any event, either approach requires a sound knowledge of how Java represents type information at runtime. 

The Class object

Java uses instances of the class Class to represent type information at runtime. Type refers to the classes and interfaces in a running Java application which are automatically loaded by the Java Virtual Machine (JVM) using a specialClassLoader mechanism. In effect, there exists aClass object for every class that is a part of your program which consists of information about your class and is used for creating all the other objects of your class. You can get a reference to this Class object by calling thegetClass() method as we did in a previous example. However in circumstances where this option might not be available, you can create a Class reference directly which can then be manipulated just like you do any other reference to conveniently discover all sorts of type information. You can return a Class reference by either calling thestatic forName() method or by using the class literal. Here is an example using both techniques;-public class GettingTypeInfo { static void printTypeInfo(Class<? extends Game> whichClass) { System.out.println("Class name - " + whichClass.getName()); System.out.println("Simple name - " + whichClass.getSimpleName()); System.out.println("isInterface - " + whichClass.isInterface()); System.out.println("Package - " + whichClass.getPackage()); System.out.println("SuperClass " + whichClass.getSuperclass()); } public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException { Class<? extends Game> aClass = Class.forName("runtime.types.java.BlackJack"); //class literal syntax Class anotherClass = Chess.class; printTypeInfo(aClass); System.out.println("isInstance - " + aClass.isInstance(new BlackJack())); System.out.println("------------------------------- "); printTypeInfo(anotherClass); System.out.println("isInstance - " + anotherClass.isInstance(new Game())); System.out.println("------------------------------- "); Object anObj = aClass.newInstance(); System.out.println("NewInstance " + anObj.toString()); } } /* Output Class name - runtime.types.java.BlackJack Simple name - BlackJack isInterface - false Package - package runtime.types.java SuperClass class runtime.types.java.CardGame isInstance - true ------------------------------- Class name - runtime.types.java.Chess Simple name - Chess isInterface - false Package - package runtime.types.java SuperClass class runtime.types.java.Game isInstance - false ------------------------------- NewInstance BlackJack *//The first statement in the main() makes use of thestatic forName() method to obtain a valid reference to the BlackJack Class, by contrast, the second statement makes use of a class literal to achieve the same effect. Both techniques are equally valid, but have subtle implications related to the way the class object is initialised. Notice the use of generic syntax with Class types in particular in the call to the forName() method. Generics provide a way to constrain objects to subtypes of a particular type. Here the wildcard symbol   symbol is used in combination with the extendskeyword to constrain all references to subtypes ofGame. Class references also work fine without the use of generics, however it is advisable to use generic syntax as you are likely to find out about mistakes much sooner TheprintTypeInfo() method displays output from a number of methods available to objects of the class Classproviding access to useful type information. TheisInstance() and newInstance() methods are also used in the main() to test for compatibility and create a new instance respectively. As you become used to working with types, you will find them useful in circumstances where you might wish to be able to identify individual types perhaps for some specific purpose. For instance, suppose you wanted a way to keep a track of the number of individual Gametypes generated by your application. The first thing you might need is a way to link the initialisation of each Gameobject with it's corresponding Class object. One way to do this might be to use a variation of the templatedesign pattern to create an abstract method that returns a list of types with which you might generate new instances of Game types:- package runtime.types.java; import java.util.List; import java.util.Random; public abstract class InitGame { static private Random generator = new Random(); public abstract List<Class<? extends Game>> getTypes(); public Game aRandomGame() { int index = generator.nextInt(getTypes().size()); try { return getTypes().get(index).newInstance(); } catch(InstantiationException ref) { throw new RuntimeException(ref); } catch(IllegalAccessException ref) { throw new RuntimeException(ref); } } public Game[] createGames(int capacity) { Game[] arrayOfGames = new Game[capacity]; for(int i = 0; i < capacity; i++) arrayOfGames[i] = aRandomGame(); return arrayOfGames; } } Essentially, this class uses a random number generator to index into a list of types in order to instantiate a new Game object. A second method uses this pseudo-random algorithm to return an array of games. As with all abstract classes, an inheriting class will need to implement the abstract getTypes() method. The following class uses class literals to create a list ofClass references:- package runtime.types.java; import java.util.Arrays; import java.util.List; public class GameTypeCreator extends InitGame { @SuppressWarnings("unchecked") public static final List<Class<? extends Game>> gameTypes = Arrays.asList(Chess.class, CardGame.class, BlackJack.class, Charade.class, OnlineGame.class); public List<Class<? extends Game>> getTypes() { return gameTypes; } } The final class in this sequence uses aMap to track the number individual type ofGame objects created. Here's how:- package runtime.types.java; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; class Util { static public Map<Class<? extends Game>, Integer> mapData(List<Class<? extends Game>> key, int value) { Map<Class<? extends Game>, Integer> data = new HashMap<>(); Iterator<Class<? extends Game>> sequence = key.iterator(); while(sequence.hasNext()) data.put(sequence.next(), value); return data; } } public class CountGame extends LinkedHashMap<Class<? extends Game>, Integer> { public CountGame() { super(Util.mapData(GameTypeCreator.gameTypes, 0)); } public void count(Game aGame) { for(Map.Entry<Class<? extends Game>, Integer> anEntry : entrySet()) //Class.isInstance to dynamically test for types if(anEntry.getKey().isInstance(aGame)) put(anEntry.getKey(), anEntry.getValue() + 1); } public String toString() { StringBuilder aString = new StringBuilder("{"); for(Map.Entry<Class<? extends Game>, Integer> anEntry : entrySet()) { aString.append(anEntry.getKey().getSimpleName()); aString.append("="); aString.append(anEntry.getValue()); aString.append(", "); } aString.delete(aString.length()-2, aString.length()); aString.append("} "); return aString.toString(); } } public static void main(String[] args) { CountGame aGameCounter = new CountGame(); GameTypeCreator aGameTypeCreator = new GameTypeCreator(); for(Game aGame : aGameTypeCreator.createGames(15)) { System.out.print(aGame.getClass().getSimpleName() + " "); aGameCounter.count(aGame); } System.out.println(); System.out.println(aGameCounter); } } /* Output OnlineGame BlackJack Charade BlackJack BlackJack Chess CardGame Chess OnlineGame BlackJack BlackJack Chess BlackJack Charade Charade {Chess=3, Charade=3, BlackJack=6, OnlineGame=2, CardGame=7} *// In this example, a Map is preloaded using amapData() utility that accepts a list ofClass types restricted to subtypes of theGame class and an integer value, zero in this particular instance. In the count(), theisInstance() method is used to test for type and then increment the value entry by one. A Map can not contain duplicate keys and each key can only map to one value so it is the perfect tool for this kind of application. ThetoString() method is overridden to provide a formatted view of the Map. Adding a new type ofGame is a simply a matter of making an update to the static gameTypes list in theGameTypeCreator class. This is a useful tool limited only by the fact that it can only be used to count types ofGame because the Map has been preloaded with Game types. A more useful tool would be one that we could use to count any type:- package runtime.types.java; import java.util.HashMap; import java.util.Map; public class CountAnyType extends HashMap<Class<?>, Integer> { private Class<?> baseType; public CountAnyType(Class<?> aType) { this.baseType = aType; } public void checkType(Object arg) { Class<?> aType = arg.getClass(); if(!baseType.isAssignableFrom(aType)) throw new RuntimeException("Wrong type! " + arg); count(aType); } public void count(Class<?> aType) { Integer sum = get(aType); put(aType, sum == null ? 1 : sum + 1); Class<?> superClass = aType.getSuperclass(); if(superClass != null && baseType.isAssignableFrom(superClass)) count(superClass); } public String toString() { StringBuilder aString = new StringBuilder("{"); for(Map.Entry<Class<?>, Integer> anEntry : entrySet()) { aString.append(anEntry.getKey().getSimpleName()); aString.append("="); aString.append(anEntry.getValue()); aString.append(", "); } aString.delete(aString.length()-2, aString.length()); aString.append("} "); return aString.toString(); } public static void main(String[] args) { CountAnyType aTypeCounter = new CountAnyType(Game.class); GameTypeCreator aGameCreator = new GameTypeCreator(); for(Game aGame : aGameCreator.createGames(15)) { System.out.print(aGame.getClass().getSimpleName() + " "); aTypeCounter.checkType(aGame); } System.out.println(); System.out.println(aTypeCounter); } } /* Output Charade Charade Chess BlackJack BlackJack BlackJack CardGame BlackJack Charade CardGame OnlineGame Charade Charade Chess CardGame {Game=15, Charade=5, BlackJack=4, OnlineGame=1, Chess=2, CardGame=7} *// In this example, we use a wildcard<?> argument to specify the type of the class, effectively making it possible to use any type with our container. We have also introduced a checkType() method that allows us to verify that we are counting the correct type using theisAssignableFrom() method. The count()method in this example, first counts the specific type and then recursively counts the base type. You would be correct to imagine that it would be possible to make a more sophisticated design in our approach to generating Game objects in circumstances where we were unconcerned about keeping track of types or for that matter if we had to generate Gameobjects with a much greater frequency. Here is an approach that makes use of the Factory design pattern by registering factories for the types to be created directly in the base class:-package runtime.types.java; import java.util.ArrayList; import java.util.List; import java.util.Random; interface GameFactory<T> { T createGame(); } class Game { static List<GameFactory<? extends Game>> factory = new ArrayList<>(); private static Random generator = new Random(); public String toString() { return getClass().getSimpleName(); } static { factory.add(new Charade.Factory()); factory.add(new Chess.Factory()); factory.add(new Scrabble.Factory()); factory.add(new Monopoly.Factory()); factory.add(new BlackJack.Factory()); factory.add(new OnlineGame.Factory()); factory.add(new VideoGame.Factory()); } public static Game autoCreate() { int index = generator.nextInt(factory.size()); return factory.get(index).createGame(); } } class PartyGame extends Game {} class Charade extends PartyGame { public static class Factory implements GameFactory<Charade> { public Charade createGame() { return new Charade(); } } } class BoardGame extends Game {} class Chess extends BoardGame { public static class Factory implements GameFactory<Chess> { public Chess createGame() { return new Chess(); } } } class Scrabble extends BoardGame { public static class Factory implements GameFactory<Scrabble> { public Scrabble createGame() { return new Scrabble(); } } } class Monopoly extends BoardGame { public static class Factory implements GameFactory<Monopoly> { public Monopoly createGame() { return new Monopoly(); } } } class CardGame extends Game {} class BlackJack extends CardGame { public static class Factory implements GameFactory<BlackJack> { public BlackJack createGame() { return new BlackJack(); } } } class OnlineGame extends Game { public static class Factory implements GameFactory<OnlineGame> { public OnlineGame createGame() { return new OnlineGame(); } } } class VideoGame extends Game { public static class Factory implements GameFactory<VideoGame> { public VideoGame createGame() { return new VideoGame(); } } } public class GameFactories { public static void main(String[] args) { for(int i = 0; i < 10; i++) System.out.println(Game.autoCreate()); } } /* Output Charade OnlineGame Charade BlackJack OnlineGame Scrabble Scrabble Chess OnlineGame Chess *// The GameFactory interface uses generic syntax and consequently is able to return a different type based on it's implementation. In this way, adding a new type of Game does not require too much effort, except to register it's inner GameFactory class in thefactory list in the base class . The genius of this design is in its simplicity and this is exactly what design patterns are able to do. They provide you with the ability to encapsulate change. 

The Reflection Mechanism

The RTTI mechanisms discussed thus far have in common the advantage of being able to discover type information for objects whose types will have been available at compile time, in other words these classes must have been compiled as a part of your program. Java uses reflection to discover and use classes at runtime about which you had no prior information. This capability is useful in circumstances where your application might need to make use of a foreign utility which might be accessed over a network connection, on the internet or in some other similar fashion to create and execute objects on remote platforms in a technique known as Remote Method Invocation (RMI). Java's reflection implementation consists of a number of classes within the java.lang.reflect library that can be used to represent the fields, methods and constructors after which they have been appropriately named. TheConstructor class for instance provides access to a single class constructor, the Field class includesgetter() and setter() methods to read and modify Field objects and the Method class includes an invoke() method by which means you might invoke the underlying method associated with theMethod object. These classes implement theMember interface which reflects identifying information about a single member. The class Classsupports reflection by including a number of convenience methods by which means you might discover and use type information at runtime. Reflection is also a useful tool for dynamically extracting information about a class, for example to reveal the entire interface including inherited and overridden methods. Here is a nifty little tool that uses reflection to automatically reveal information about a class at runtime. You can run this tool on any class to save you time from having to trawl through endless lines of documentation:- package runtime.types.java; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.util.regex.Pattern; public class InterfaceLookup { private static Pattern packageNames = Pattern.compile("\\w+\\."); public static void showInterface(Object ref) { try { Class<?> whichClass = Class.forName(ref.getClass().getName()); Constructor[] constructors = whichClass.getConstructors(); Method[] methods = whichClass.getMethods(); for(Constructor aConstructor : constructors) System.out.println(packageNames.matcher(aConstructor.toString()) .replaceAll("")); for(Method aMethod : methods) System.out.println(packageNames.matcher(aMethod.toString()) .replaceAll("")); } catch(ClassNotFoundException exceptionRef) { System.out.println("Class does not exist!"); } } public static void main(String[] args) { showInterface(new InterfaceLookup()); } } /* Output public InterfaceLookup() public static void main(String[]) public static void showInterface(Object) public final native void wait(long) throws InterruptedException public final void wait(long,int) throws InterruptedException public final void wait() throws InterruptedException public boolean equals(Object) public String toString() public native int hashCode() public final native Class getClass() public final native void notify() public final native void notifyAll() *// The example uses theforName() to return a reference to the current class and then uses convenience methods to return an array of constructors and methods which it can then iterate through and print out individually. The output is the result of using a regular expression to replace class name qualifiers. This is a quick and easy way to find out all you need to know about a class's interface while coding. As part of it's reflection mechanism, Java also provides classes and interfaces by which means you might implement dynamic proxies which are modeled on the Proxy design pattern. Proxy is a pattern that allows you to provide a surrogate or placeholder for another object in order to control access to it. This is useful in circumstances where you wish to differ the full cost of an objects creation until you actually need it or if you wanted to provide for additional operations you do not wish to be a part of your main object. For instance, consider a drawing application that renders graphics on screen in a scenario where drawing an image is a costly operation you only want to undertake when necessary. You can implement an image proxy between the Image and the calling client so that you can control when and how you create an Image. The following code provides a better illustration:- package runtime.types.java; interface Graphic { void draw(); } class Image implements Graphic { public void draw() { System.out.println("Hello!"); } } class ImageProxy implements Graphic { private Graphic anImage; public ImageProxy(Graphic args) { this.anImage = args; } public void draw() { System.out.println("\"Calling Image..\""); anImage.draw(); } } public class DrawingApplication { public static void drawImage(Graphic aGraphic){ aGraphic.draw(); } public static void main(String[] args) { drawImage(new ImageProxy(new Image())); } } /* Output "Calling Image.." Hello! *// The benefits of such a design may not be immediately obvious, however, it does provide us with additional options for instance, we can easily add code to the image proxy to keep track of calls to the Image or to measure the overhead of such calls. Java provides classes to implement a proxy instance that will handle method calls dynamically through the use of an InvocationHandlerinterface. We can re-implement our image proxy to act as an invocation handler like so:- package runtime.types.java; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; class AnotherImageProxy implements InvocationHandler { private Graphic anImage; public AnotherImageProxy(Graphic args) { this.anImage = args; } public Object invoke(Object proxy, Method aMethod, Object[] args) throws Throwable { System.out.println("\"Calling Image..\""); return aMethod.invoke(anImage, args); } } public class AnotherDrawingApplication { public static void drawImage(Graphic whichImage){ whichImage.draw(); } public static void main(String[] args) { Graphic proxy = (Graphic)Proxy.newProxyInstance(Graphic.class.getClassLoader(), new Class[]{Graphic.class}, new AnotherImageProxy (new Image())); drawImage(proxy); } } /* Output "Calling Image.." Hello! *//In this example, we implement the <>code>invoke() method which is responsible for processing a method invocation on a proxy instance and returning the result, which in this case happens to be a Method object used to invoke the underlying method which it represents. In the main() a proxy instance is returned using the staticnewProxyInstance() method which accepts a class loader, an array of interfaces to be implemented and the implemented invocation handler, which is handed theImage object as a part of its constructor. In this case it's probably easiest to pass an existingClassLoader like the Graphic.classreference. RTTI opens up a whole new world of programming possibilities as you come to understand how types provide you with backdoor access into pretty much any interface regardless of access permissions. For instance, consider the following simple interface in the Interfaces.java package:- package Interfaces.java; public interface AnInterface { void interfaceMethod(); }Suppose you wanted to hide the implementation of this interface to deter your customers from relying on it so that you might be free to change it at a later stage? You might think it is enough to restrict the implementation to package access thereby making it inaccessible to clients outside of the package like so:-package runtime.types.java; class HiddenImplementation implements AnInterface { private String aField = "Can't touch this"; public void interfaceMethod(){ System.out.println("public HiddenImplementation.interfaceMethod()"); } public void aMethod(){ System.out.println("public HiddenImplementation.aMethod()"); } void bMethod() { System.out.println("package HiddenImplementation.bMethod()"); } private void cMethod() { System.out.println("private HiddenImplementation.cMethod()"); } protected void dMethod() { System.out.println("protected HiddenImplementation.dMethod()"); } public String toString(){ return aField; } } public class PublicInterface { public static AnInterface makeAnInterface() { return new HiddenImplementation(); } } The PublicInterface class produces an implementation of AnInterface and is the only visible part of this package and you would expect your implementation to be fairly safe? Not exactly, I'm afraid. With reflection, anyone who knows the name of your class members can easily get around this restriction like so:- import java.lang.reflect.Field; import java.lang.reflect.Method; import Interfaces.java.AnInterface; import runtime.types.java.*; public class HackImplementation { static void hackInterface(Object anObject, String member) throws Exception { if(member.equals("aField")) { Field whichField = anObject.getClass().getDeclaredField(member); System.out.println(anObject.toString()); whichField.setAccessible(true); whichField.set(anObject, "Yes I can"); System.out.println(anObject.toString()); } else { Method whichMethod = anObject.getClass().getDeclaredMethod(member); whichMethod.setAccessible(true); whichMethod.invoke(anObject); } } public static void main(String[] args) throws Exception { AnInterface newInterface = PublicInterface.makeAnInterface(); newInterface.interfaceMethod(); //Compile error aField can not be resolved //!newInterface.aField; //Compile error method undefined for type AnInterface /* newInterface.aMethod(); newInterface.bMethod(); newInterface.cMethod(); newInterface.dMethod(); */ hackInterface(newInterface, "aField"); hackInterface(newInterface, "aMethod"); hackInterface(newInterface, "bMethod"); hackInterface(newInterface, "cMethod"); hackInterface(newInterface, "dMethod"); } } /* Output public HiddenImplementation.interfaceMethod() Can't touch this Yes I can public HiddenImplementation.aMethod() package HiddenImplementation.bMethod() private HiddenImplementation.cMethod() protected HiddenImplementation.dMethod() *// The example demonstrates how reflection allows you to get around all sorts of restrictions to access and change any field even those markedprivate and call just about any method no matter the level of the access specifier. With thesetAccessible() method you can modify fields and invoke methods, including even those within inner and anonymous classes, are still accessible with reflection. Even if you try to avoid this by distributing only compiled code so that your members are inaccessible, that is still not entirely the case as Java's class file disassembler (javap) can still be used to reveal all your class members. For instance the -private flag can be used to indicate that all members should be displayed includingprivate ones. Running the following command will reveal everything you wish to know about our hidden class.
javap -private HiddenImplementation
In reality, hardly anything is hidden from reflection and most are susceptible to change, with the exception only of fields markedfinal. On the flip side if you choose to misuse reflection in your program, committing all sorts of access violations, then you really will only have yourself to blame if a subsequent update to your library succeeds in breaking your code, which I am certain will be a very unpleasant experience Reflection gives you the keys to a new whole new world of dynamic programming in which having access to runtime type information allows for a very different style of programming with which it is easy to get carried away. It is important to remember to use RTTI and reflection in a way that is not detrimental to polymorphism as the most effective way to provide for extensibility in your programs.  
The manipulation of strings is a quite common activity for which the programmer undertakes responsibility fairly frequently. In Java, strings are of a distinct data type, that are implemented as literal constants. The String class facilitates the creation and manipulation of objects that are of an immutable character, by which I mean to refer to the unchangeable property with which one must strive to become familiar. The following example is meant to illustrate this point:- package regex.strings.java; public class ImmutableString { static String trim(String immutableRef) { String trimmed = immutableRef.trim(); return trimmed; } public static void main(String[] args) { String immutable = " Arbitrarily replace parts of this string"; System.out.println("\"" + immutable + "\"" ); String aString = ImmutableString.trim(immutable).replaceAll("tr|rep|p|hi", "x"); System.out.println("\"" + aString + "\""); System.out.println("\"" + immutable + "\""); } } /* Output " Arbitrarily replace parts of this string" "Arbixarily xlace xarts of txs sxing" " Arbitrarily replace parts of this string" *// In this very simple example, we pass a regular expression to thereplaceAll() member of the String class following a call to our own Immutable.trim() operation to remove leading whitespace, and return what might reasonably be expected to be a modified copy of our immutable Stringobject. The replaceAll() method replaces the pattern expressed in regular expression syntax with the Stringobject "x". The expression uses the logical regular expression operator '|' to describe a sequence of groups of characters that follow in no particular order. Following these operations, you will notice that no change has been recorded against our original string, because in actuality, only a copy of the original string reference is passed to the trim()method in the first instance, which returns a reference to a newString object to account for the modified string. The process is repeated for the call to the replaceAll()method. If you were to examine the bytecodes arising from running Java's class file disassembler (javap with -c switch) with this class, you will notice that Java creates threeStringBuilder objects in total, once for our original string and the other two in relation to each call to thetrim() and replaceAll() methods. This is what we mean when we make reference to the immutable property ofString objects, which it is to be understood, can also become a source of inefficiency and why Java discretely makes liberal use of the StringBuilder class whenever there is the need to make a modification to a String. Java's API documentation describes the StringBuilder class as capable of providing for the construction of a sequence of mutable characters and operations designed specially for use with single threaded applications. Some very talented programmers have suggested the propriety of explicitly making use of theStringBuilder class, in particular during repeated operations involving the modification of Stringobjects in order to avoid any issues that might arise as a result of the inefficiencies associated with immutability, particularly in environments where unnecessary overhead is not normally considered acceptable. For instance, one of the interesting things you can do with String objects is to concatenate two or more strings, the one end to the other. Java provides a number of ways to do this, like for example by means of the overloaded '+'operator. Overloaded in the sense that it takes on an extra meaning when used with the String class:- package regex.strings.java; public class ConcatenateString { String compoundOperator = ""; public ConcatenateString(String args) { String[] splitter = args.split(" "); compoundOperator += " \""; for(int i = 0; i < splitter.length; i++) { compoundOperator += splitter[i] + " "; } compoundOperator += "\""; } public static void main(String[] args) { String aDefinition = "Cognitive computing is the development of computer \n" + "systems modelled on the human brain"; ConcatenateString overloadedPlus = new ConcatenateString(aDefinition); String listOfMetals = "Hydrogen" + ", " + "Lithium" + ", " + "Sodium" ; String statementOfFact = "A List of metals include: " + listOfMetals; System.out.println(statementOfFact + "\n"); System.out.println(overloadedPlus.compoundOperator); } } /* Output A List of metals include: Hydrogen, Lithium, Sodium "Cognitive computing is the development of computer systems modelled on the human brain " *// In the main() method we make use of the '+' operator to combine a number of individual strings into one coherent String object. Within the class constructor, notice the use of the overloaded '+='operator which also acts like an append method when used withString objects. Both of these methods are suitable for simple operations, but become inefficient when used in loops like you have in the above constructor because Java has to create a newStringBuilder object at every iteration which, as has been pointed out before now, is really not ideal. A more efficient way would be to explicitly create a StringBuilderobject and make use of the append() method within the loop, like the following example demonstrates:- package regex.strings.java; public class ConcatenateString2 { StringBuilder buildString = new StringBuilder(); public ConcatenateString2(String args) { String[] splitter = args.split(" "); buildString.append(" \""); for(int i = 0; i < splitter.length; i++) { buildString.append(splitter[i] + " "); } buildString.append(" \""); } public static void main(String[] args) { String aDefinition = "Cognitive computing is the development of computer \n" + "systems modelled on the human brain"; ConcatenateString2 stringBuilder = new ConcatenateString2(aDefinition); System.out.println(stringBuilder.buildString); } } /* Output "Cognitive computing is the development of computer systems modelled on the human brain " *// By making an explicit call to StringBuilder before you enter your loop, you produce better and more efficient code. With the release of Java SE 7, came the addition of the ability to use Stringobjects with the switch statement which was not always the case. Being that Java SE 8 was released while I was putting this piece together, I figured I might as well use the opportunity this example provided me to test the utility of the new Date/Time API, which altogether seems to be quite an improvement over the previous version:- package regex.strings.java; import java.time.Month; import java.time.YearMonth; import java.time.format.TextStyle; import java.util.ArrayList; import java.util.List; import java.util.Locale; public class GregorianCalendar { private List<Month> leapYear = new ArrayList<Month>(); public void setMonths() { for(int month = 1; month < 13; month++) { leapYear.add(Month.of(month)); } } public void daysOfTheMonth(int month) { Month whichMonth = leapYear.get(month); switch(whichMonth.getDisplayName(TextStyle.FULL, Locale.ENGLISH)) { case "April": case "June": case "September": case "November": System.out.println(whichMonth.getDisplayName(TextStyle.FULL, Locale.ENGLISH) + " = 30 days"); break; case "February": System.out.println(whichMonth.getDisplayName(TextStyle.FULL, Locale.ENGLISH) + " = 29 days"); break; default: System.out.println(whichMonth.getDisplayName(TextStyle.FULL, Locale.ENGLISH) + " = 31 days"); } } public static void main(String[] args) { GregorianCalendar aCalendar = new GregorianCalendar(); aCalendar.setMonths(); for(int i = 0; i < aCalendar.leapYear.size(); i++) aCalendar.daysOfTheMonth(i); } } Java 8's new Date/Time API consists of about 5 packages that provide you with a comprehensive framework for representing an instance of time. In our example, we make use of theMonth class which is of an enumerated type to provide a string representation to test for a certain conditionality in ourswitch statement by which means we are able to print the number of days in a particular month. 

Regular expressions

A regular expression is a string processing technique for describing the patterns that may be found in string based text. This is achieved by giving special meaning to the arrangement of metacharacters when used in particular context. A metacharacter is a character that has been given a special meaning by Java's regular expression interpreter and therefore it would not be a mistake for you to predispose your mind to the notion that presupposes that regular expressions are a completely separate, though indistinct language from Java, which really does not require too much of a stretch of the imagination, even if they are conceived as strings, and are subsequently applied to exactly this same type. There are a number of predefined character classes that represent the basic building blocks of regular expressions with which you must become properly acquainted if it is your wish to attain an expert level of proficiency in this subject. For instance, a word character is represented with a backslash followed by the letter w like so'\w'. In consequence, a digit is represented by the metacharacter '\d', while '\s' is used to represent the whitespace character , '\W', a non-word character, and the non whitespace and non-digit character are represented as'\S' and '\D' respectively. In addition, to indicate any of these predefined characters in regular expression syntax, you must precede each one with an additional backslash '\'such that the expression '\\w' would be used to indicate a word character, or '\\d' to indicate a digit, and et cetera.. You should also make yourself to become familiar with a set of arrangements that consists of characters enclosed in square brackets [...], known as character classes and used to indicate a preference, so that the arrangement "[abc]"indicates a preference for a,b or c and"[a-zA-Z]" indicates a preference for any character in the range a-z or A-Z. The '-' metacharacter acts like a range forming operator when used in square brackets. These character classes can also be arranged in other ways that make more complex operations possible, for instance the arrangement"[a-e[l-p]]" is a regular expression union operator that specifies a preference for any within the range athrough e or l through p, and the expression"[a-z&&[hij]]" is an intersection operator that refers to h, i or j. And then of course you also have a number of logical operators including 'AB'to indicate that B follows A , 'A|B' to indicate A or B and (A) as a reference to a capturing group, an explanation of which is better sought within the pages of your official documentation; all of this in addition to other categories of metacharacters, boundary matchers, quantifiers and a multiplicity of character classes competing to represent every conceivable character combination you can possibly imagine. For this reason, you will probably have to become used to making a constant reference to your official documentation for a full list of Java's regular expression metacharacters and the valid range of arrangements. Nevertheless, the easiest way to use regular expressions in Java is to pass a valid argument to the convenience method, matches() of the String class to make a test of whether or not the expression matches the currentString:- package regex.strings.java; public class StringMatcher { public static void main(String[] args) { System.out.println("Flight 8957".matches("\\w+\\s?\\d+")); System.out.println("Flight8957".matches("[Ff]li[huog]ht\\s?\\w+")); System.out.println(" Flight-8957".matches("\\s?\\w+-?\\d+")); System.out.println("Flight8957".matches("[a-zA-Z]+[0-9]+")); System.out.println("Flight8957".matches("\\w+")); } } /* Output true true true true true *// In addition to some of Java's predefined character classes, the above example uses 'quantifiers' so as to regulate the varying degrees of frequency with which a match is made against a given string, according to a particular pattern. So for instance, the first expression in the above example uses the '+' quantifier to match a word character"\\w" one or more times, and then uses the '?'quantifier to match the whitespace character "\\s"once or not at all, before this time matching a digit"\\d+" one or many times in the preceding string"Flight 8957". The matches() method returns a boolean value that should indicate the truth or falsehood of any assertion. With quantifiers, it is important to bear in mind that they apply only to the metacharacter that immediately precede their definition, except when you use parenthesis to group patterns or of course when you apply them to character classes, so for instance the expression"\\w+" which indicates a preference for a word character one or more times, will match the string"Flight8957" but to make a match of the string"Flight-8957" which contains a non-word character, you will need to write "\\w+-?\\d+" which reads match a word character one or many times, followed by a hyphen once or not at all, and then match a digit one or more times. You may apply this reasoning to unravel the mystery behind the remaining regular expression statements. Parenthesis allow you to group individual characters to form a pattern, for instance the '*'metacharacter is a third quantifier that allows you to make a match of a pattern zero or more times, so that the expression"(abc)*" would match the pattern 'abc' in a given string, zero or many times, while the expression"abc*" reads - match 'ab' followed by'c' zero or many times. This quantifier in addition to those earlier referenced constitute a category of the so-called 'greedy' quantifiers, which when used in particular combination can be of the 'possessive' or 'reluctant' variety - the categories, are a reference to the varying degrees of regularity with which each class of quantifier is known to make a match against a given string, according to the varying levels of generality that exist within a pattern. Java provides a package of APIs' (java.util.regex) that provide you with more advanced features with which you can create, compile and match regular expressions against string based text, in a standardised way. The relevant classes that should concern you initially are the Pattern andMatcher class. With this technique, you introduce aPattern object by passing a valid regular expression argument to the static compile() method of thePattern class, against which you must supply your search string as argument in a manner that makes possible, the recovery of a Matcher object, from which certain operations become available, by which means you may query such an object for complex information. In the following example, we apply this technique to locate patterns, first in a file and then manually on a test string:- package pattern.matching.java; import java.io.BufferedReader; import java.io.FileReader; import java.util.NoSuchElementException; import java.util.Scanner; import java.util.regex.Matcher; import java.util.regex.Pattern; public class Parser { static void parseString(String arg1, String arg2 ){ Pattern regex = Pattern.compile(arg1); Matcher intepreter = regex.matcher(arg2); // find pattern match in search string while(intepreter.find()) { System.out.println("found pattern: " + intepreter.group() + " at index " + intepreter.start()); } //System.out.println("No match found"); return; } public static void main(String[] args) throws Exception { FileReader reader = new FileReader("/home/geekfest/eclipse/about.html"); BufferedReader in = new BufferedReader(reader); Scanner input = new Scanner(in); boolean reading = false; String searchString; // search pattern beginning http[^\s] String regex = "h\\w+p\\S+"; try { while((searchString = input.nextLine()) != null) { //match search pattern in search string //parseString(regex, searchString); reading = true; } } catch(NoSuchElementException e) { //System.out.println("End of input"); } input.close(); if(reading == false) return; String testString = "abracadabracadab"; parseString("abr?", testString); System.out.println("-----------------------------"); parseString("abr??", testString); System.out.println("-----------------------------"); parseString("(abr)+", testString); } } /* Output found pattern: abr at index 0 found pattern: abr at index 7 found pattern: ab at index 14 ----------------------------- found pattern: ab at index 0 found pattern: ab at index 7 found pattern: ab at index 14 ----------------------------- found pattern: abr at index 0 found pattern: abr at index 7 *// This example is useful to demonstrate a number of simple techniques. Firstly, we implement a simple parseString() algorithm by creating aPattern object, and then calling thematcher() method of this object to create aMatcher object which we are then able to query repeatedly within our loop for information about specific patterns in particular using the group() andstart() members. In the main(), we make use of a Scanner object to scan input from a file into a String object against which we make a test of our regular expression that describes a pattern that matches the first few letters of a URL address. In this example, we have had to comment out the code that would have resulted from this match to satisfy our desire for compactness as much as possible in the use of code for illustrations. Nevertheless, we manually apply this method to a simple search string the result of which is provided for your perusal. Notice the difference in the first two statements that make use of different classes of quantifiers. The second statement uses a quantifier from the reluctant '??' category which will match the minimum number of characters necessary to satisfy the pattern, while other two statements use quantifiers from the greedy category, which will find as many matches for the pattern as possible. Furthermore, consider the effect of the parenthesis based on the output from the third statement. 

Formatting String

Another interesting thing you are able to do with strings is to control how they are written to a particular output destination. The Formatter class provides you with this kind of capability by acting as an interpreter for "format strings" by which means you are able to control the justification, alignment and spacing of string based output. Format strings are a combination of static text and format specifiers that describe the conversions, alignment, spacing and layout justification, that is to be applied to output. Java's format specifiers can be understood within the boundaries following conventions:-%[argument_index$][flags][width][.precision]conversion The first four specifiers in square brackets are optional and may take on a different meaning depending on the value of theconversion specifier to which they are applied. Theconversion format specifier is mandatory and is used to indicate a preference for a particular data type, whose value may be optionally specified by means of the argument_index$format specifier. Some of the typical conversions you should expect to be able to make include character conversions denoted by the specifier 'c', string conversions denoted by 's', a range of numeric conversions of either the integral or floating point kind 'd' and 'f' respectively, date/time conversions 't', and a number of less frequent others. For some of these conversions, an upper case representation is as equally valid, to the extent that the result is converted to upper case according to the rules of the prevailing locale, so for instance the conversion 't', and 'T' would both refer to Date/Time conversions except that the result of one will be in lower case and the other in upper case. The argument_index$format specifier is an integer used to indicate the position of the required argument in the argument list, which is nominally a reference to the value of the conversion format specifier, while the optional, flags format specifier consists of metacharacter that modify the output string in any one of a number of ways depending on the conversion. By contrast, the.precision format specifier is a non-negative integer that acts to restrict the number of characters to be written but whose precise functionality also depends on the conversion to which it relates, in exactly the same way as the flags format specifier. Finally, the width format specifier is a positive integer used to indicate the minimum number of characters to be written to output. The Formatter API includes two variations of the format() method that accept a format string and type arguments and can write formatted output to aPrintStream object or other destination of your choice, with the difference being that one of the two makes use of the specified locale. The format string consists of a mixture of static text and format specifiers:- package regex.strings.java; public class MatchResult { public static void main(String[] args) { String s = "Team"; int i = 6; System.out.format("%2$s-B (%1$d - 0) %2$s-A ", i, s); } } /* Output Team-B (6 - 0) Team-A *// In the above example, we can discern five distinct pieces of static text in the format string argument to our format() method made up of"-B", "-", "0" and"-A" as well as the parenthesis grouping the integers that represent team scores. Format specifiers make up the remainder of the string, including the percent '%' argument which produces a literal result. The format string can be described from left to right to read, position the second argument as specified by the argument_index$ specifier, of type string to the left of the static text "-B" to produce the literal"Team-B", and then position the first argument of type integer to produce the literal result "6", and finally, position the second argument of type string such that it produces the output "Team-A". The argument list is comprised of two arguments of the integer and string type. Here is another example that makes use of the flags andwidth format specifiers only:- package regex.strings.java; public class FormatString { public static void main(String[] args) { System.out.format("%-20s \n%(.2f \n%25s", "left-justify", -3.186329, "right-justify"); } } /* Output left-justify (3.19) right-justify *// The format string in this example is separated into three lines of text by the interposing new line '\n' operator, with the first and third lines specifying a size value in the immediate path of the percent'%' metacharacter which, contrary to the current JDK documentation is applicable to the .precision specifier and indeed to at least one other flag in addition to the'-' flag whose purpose is to left-justify output, the default being right justified, as may be deduced from the position of the last line of output. The second line of the format string uses the '(' flag to enclose the negative value in parenthesis and the .precision specifier to indicate the number of digits after the radix point for our floating point conversion. To employ this technique to your advantage, you must attain proficiency with the functionality of the format specifiers that comprise a fundamental part of the format string in order to write more efficient and flexible code. The following class formats a list of staff in a using the Formatter interpreter:-package pattern.matching.java; class Format { void FormatHeader() { System.out.format("%-10s %5s %10s \n", "Name", "DoB", "Age"); System.out.format("%-10s %5s %10s \n", "----", "---", "---"); } void FormatEntry(String name, String dob, int age) { System.out.format("%-9s %-11s %4d \n", name, dob, age); } } public class Printer { public static void main(String[] args) { Format style = new Format(); style.FormatHeader(); style.FormatEntry("John", "09/06/1981", 33); style.FormatEntry("Amy", "20/11/1985", 29); style.FormatEntry("Karyn", "02/02/1978", 36); } } /* Output Name DoB Age ---- --- --- John 09/06/1981 33 Amy 20/11/1985 29 Karyn 02/02/1978 36 *// Essentially, each format string divides the output into three columns with values of unequal size, into some of which we apply the '-' flag to left justify output. You will find that the '-' flag and widthformat specifier work closely most often to control the spacing and position of output. In this example, the arguments consists mostly of string conversions and an integer conversion. The example is an obvious demonstration of how Formatter class makes it possible to write output for which we can tightly control presentation. You should consult with your official documentation for an in-depth explanation of format specifiers. Strings are not a trivial topic by any means and overall include perhaps a slightly moderate level of complexity sufficient to satisfy any curious mind. In particular, regular expressions can be challenging, but there is absolutely nothing about it that should constitute a barrier to those interested to discover it's truth.  
In this post, I try to give a reasonable account of Java's error handling system being as it is that the handling of errors is a concern that any reasonable programming language must find some way to contend with. Java's error handling methodology is based on an idea of exceptions. An exception is a condition that prevents your program from further executing along the current path. It signifies a problem in your program serious enough to require intervention because the system lacks sufficient information that would allow your program to proceed along current context. When your program encounters an exceptional condition, Java provides a mechanism that allows you to 'throw' an exception in a way that passes the problem to an exception handler designed for just such an eventuality. Throwing an exception is a term that is used to describe the creation of a new object derived from the classes belonging to either one of two subtypes of the Throwable class i.e. the Error class - which are essentially a group of unchecked exceptions related to compile time and system errors which you are not required to declare in your exception specification, and the Exception class, most of whose subclasses with the exception of RuntimeException, belong to a category of checked exceptions you would normally be concerned to handle and which you would be required to declare in your exception specification. The exception specification refers to the part of your method appearing just after the argument list beginning with the throws keyword followed by a list of all potential exceptions types, essentially a way to alert users to the kind of exceptions your method is liable to throw. Objects derived from RuntimeException are unchecked because they often represent exceptions that can be thrown during the normal operation of the Java Virtual Machine for instance, programmatic errors that may be beyond your control like an uninitialised variable could be an example of a run time exception. These kind of exceptions form a part of the standard Java runtime checking and as a consequence, you should not have to include them in your exception specification or worry about handling them. 

Throwing exceptions

Throwing an exception in Java is simply a matter of making a call to the appropriate exception type after the throwkeyword. For instance, you might throw an exception following a test for some particular condition like so:- package errors.handling.java; public class ThrowException { public static void main(String[] args) { String[] sequence = {"first element", "seccond element" }; for(int i = 0; i < sequence.length; i++) //do something here System.out.println("In bound"); throw new ArrayIndexOutOfBoundsException("sequence.length"); } } /* Output In bound In bound Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: sequence.length at errors.handling.java.ThrowException.main(ThrowException.java:9) *// The above example reports an illegal index with theArrayIndexOutOfBoundsException, with an optional string message in it's constructor argument. As you may observe, the name of exception classes in Java often implicitly describe the type of error and is often enough information to assist you to make an assessment of the problem. When you throw an exception using thenew keyword, an object is created on the heap in the normal way, however in addition to this, the current execution path is immediately terminated and the newly created object reference is ejected from the current context, in effect exiting the method just like you do with a return statement. At this moment Java's exception handling mechanism begins the task of locating an appropriate exception handler, usually in a higher context, from where the program may be recovered. 

Exception handling

The handling of exceptions in Java constitute a two step process involving firstly, the capture of the exception and then the handling of it. Both stages work in concert to provide a robust exception handling model. To capture an exception you place exception generating code within whats called a "guarded region" - which consists of the try keyword followed by an ordinary scope:- try { //guarded region } catch(Type1 ref1) { // exception handler for type1 //exception handling code goes here } catch(Type2 ref2) { // exception handler for type 2 //exception handling code goes here } Immediately following thetry block is the exception handler beginning with thecatch keyword. The idea is to pass the appropriate exception type as argument to the catch block, such that a captured exception from the try block might be matched against it by the exception handling mechanism. To properly appreciate Java's exception handling model, you must quickly become wise to the fact that more often than not, you will be concerned with handling other peoples thrown exceptions. As an example, consider for instance Java's FileReader class in the I/O package. This class is handy for reading streams of character from files but quite naturally has a constructor that throws aFileNotFoundException. If you wish to create an object of this class for use in your program, you will be required to handle this exception one way or another. The way to do that is to place the call to the constructor within atry/catch block like this:- package errors.handling.java; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; public class HandleException { public static void main(String[] args) { String path = "/home/geekfest/eclipse/notice.html"; File resource = new File(path); BufferedReader reader; try { reader = new BufferedReader(new FileReader(resource)); try { String console; while((console = reader.readLine()) != null); //System.out.println(console); } catch(IOException e) { System.out.println("read failed"); } } catch(FileNotFoundException e) { System.out.println("File not found"); //exception handling code here } System.out.println("reader created successfully"); } } /* reader created successfully *// This example makes use of a nested try block to guard against multiple scenarios. First, we pass the static call to theFileReader constructor as an argument to create a reader within the first try block. Next, we read the contents of a file within a nested try block with thereadLine() method which incidentally throws anIOException which is handled by the innercatch block. The outer catch block handles any exception thrown from the call to the FileReaderconstructor within the outer try block. We could just as easily have accomplished the same thing with a singletry block and multiple catch blocks so long as we paid attention to the normal restrictions imposed by inheritance. Of course the above example did not generate any exceptions so neither exception handler was ever really necessary. But the opposite might just have easily been the case if, for instance we made an error in our configuration or suffered some benign interruption to our I/O operation that caused it to fail. The point to emphasise here is that you can define as manycatch blocks as necessary to handle the many different exception types captured within your try block but you only need the one catch block to handle multiple instances of the same exception, all of this in addition to paying particular attention to the peculiar structure and semantics that come with the use of nested try blocks. Irregardless, the exception handling mechanism will always make a search through the list of exception handlers in the order in which they are written and will enter into the first handler that is a match for a captured exception. Once a match is located, no further searching takes place as the particular exception is considered handled. Note that as a result of inheritance, a match in this context does not have to be an exact match between the thrown exception object and the type of the exception handler; this is to say an exception handler with a base class argument will match a derived class object. For instance, a handler defined with the baseException type argument will match an object of the derived type IOException, for this reason it is best practice to specify handlers of a more generalised type at the bottom of the list of exception handlers to avoid preempting any other more specific types that might be a closer match. Sometimes, when dealing with programs significantly less complicated than of a commercial application, it is convenient to preserve your exceptions without regard to having to write a great deal of code by passing them out to console via your main() method. In this way you are precluded from having to writetry/catch blocks within the body of yourmain():- package errors.handling.java; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; public class ConsoleException { public static void main(String[] args) throws Exception { String path = "/home/geekfest/eclipse/notice.html"; File resource = new File(path); BufferedReader reader = new BufferedReader(new FileReader(resource)); String console; while((console = reader.readLine()) != null); //System.out.println(console); System.out.println("reader created successfully"); reader.close(); } } /* Output reader created successfully *// In this version of a previous example, we use the exception specification syntax to specify that our main() throws the baseException. This approach means we end up writing less code but is only really appropriate for use with very simple programs. So what does it mean to handle an exception within the context of the code you write in the catch clause? Normally, you would want to use the catch block to report the exception to the method caller. In the preceding example, if an exception was returned from the call to theFileReader constructor, it would have been caught in the associated catch clause and you would have had "Caught File Not Found Exception" printed to screen. Reporting the exception is as much about notification as it is about providing pertinent information pertaining to the exception itself. TheThrowable class provides a number of methods with which one might query objects of it's subtypes for useful information pertaining to a thrown exception. For instance thegetMessage() and getLocalisedMessage()methods both return a detailed and localised decription of the throwable object respectively, the printStackTrace(),printStackTrace(PrintStream) andprintStackTrace(PrintWriter) - all of which print theThrowable and its backtrace to a stream of your choice - the no-argument constructor version prints to standard error. Another method, the fillInStackTrace() method records information within this throwable about the current state of stack frames. It is a useful practice to become familiar with the meaning inherent in the output returned from some of these methods to assist your troubleshooting efforts. 

The stack trace

Of all the methods available to subtypes of theThrowable class, the printStackTrace()method is special because it tells you the exact point from whence this exception originated. This information could be very useful in locating the source of bugs in your code. You can use its cousin, the getStackTrace() method to return an array of stack trace elements that describe the sequence of method invocations leading up to the exception:- package errors.handling.java; public class StackTraceArray { static void first() { try { throw new Exception(); } catch(Exception exceptionRef) { for(StackTraceElement traceElement : exceptionRef.getStackTrace()) System.out.println(traceElement.getMethodName()); } } static void second() { first(); } static void last() { second(); } public static void main(String[] args) { first(); System.out.println("\n" ); second(); System.out.println("\n"); last(); } } /* Output first main first second main first second last main *// In this particular example, we throw and handle an exception of the base class Exception within our first() method and then progressively reach out to this method from within two other methods, a second() and last()method. In the exception handler, we use the for each syntax to loop through an array of stack trace elements returned by thegetStackTrace(). The output displays the result of each method call from the main() and should be read as an array where the top of the stack equates to element zero in the array and represents the most recent method invocation in the sequence and typically the point from where the exception originated. In our little example we can easily see this to be thefirst() method. The last element in the array represents the bottom of the stack and is the oldest method invocation in the sequence. 

Rethrowing exceptions

In addition to throwing an exception, you can rethrow an exception within a catch block for any number of reasons which may be convenient to your particular application. You may choose to rethrow the exception you have just caught or a different exception altogether. The key difference is when you rethrow an exception you have just caught, it ends up in an exception handler with all the original exception information intact, however, when you rethrow a different exception, you would normally be expected to lose all the information pertaining to the original exception which is in any case, replaced with information relating only to the new exception:- package errors.handling.java; public class RethrowingException { static void original() throws Exception { System.out.println("Throwing new exception from original()"); throw new Exception("original Exception()"); } static void throwOriginalException() throws Exception { System.out.println("Inside throwOriginalException():"); try { original(); } catch (Exception exceptionRef) { throw exceptionRef; } } static void throwNewException() throws Exception { System.out.println("Inside throwNewException()"); try { original(); } catch(Exception exceptionRef) { throw new Exception("new Exception()"); } } public static void main(String[] args) { try { throwOriginalException(); } catch(Exception exceptionRef) { System.out.println("in catch 1:"); exceptionRef.printStackTrace(System.out); } try { throwNewException(); } catch(Exception exceptionRef) { System.out.println("in catch 2:"); exceptionRef.printStackTrace(System.out); } } } /* Output Inside throwOriginalException(): Throwing new exception from original() in catch 1: java.lang.Exception: original Exception() at errors.handling.java.RethrowingException.original(RethrowingException.java:6) at errors.handling.java.RethrowingException.throwOriginalException(RethrowingException.java:11) at errors.handling.java.RethrowingException.main(RethrowingException.java:26) Inside throwNewException() Throwing new exception from original() in catch 2: java.lang.Exception: new Exception() at errors.handling.java.RethrowingException.throwNewException(RethrowingException.java:21) at errors.handling.java.RethrowingException.main(RethrowingException.java:32) *// For this example, we call two methods in themain() both of which reference ouroriginal() method in turn, from which an exception is thrown. In the throwOriginalException() the caught exception is rethrown while a new exception is thrown inthrowNewException(). The result in the output marked"in catch 2" is that any reference to the original exception is lost. 

Chaining Exceptions

If you do not want to lose the information pertaining to the original exception while rethrowing a different exception, you can employ a technique called exception chaining to retain this information whereby you pass the original exception as a cause argument to the constructor of a Throwable object or objects of any of it's two main subclasses as well as an object of the RuntimeException class. For all other derived classes, you must use the initCause() method inherited from the Throwable class, that takes and returns aThrowable object which you can use to represent the cause:- package errors.handling.java; class NoSuchItemException extends Exception {} class Item { String name; public Item(String item) { this.name = item; } } public class ShoppingCart { private Item[] cart; public ShoppingCart(String[] list) { cart = new Item[list.length]; for(int i = 0; i < list.length; i++) cart[i] = new Item(list[i]); } public boolean checkItem(Item item) throws NoSuchItemException { if(item == null) { NoSuchItemException chainedException = new NoSuchItemException(); // use initCause to wrap exception for //Throwable subclasses chainedException.initCause(new NullPointerException()); throw chainedException; } for(int i = 0; i < cart.length; i++) if(cart[i].name.equals(item.name)) return true; return false; } public void addItem(Item item) { try { if(checkItem(item)) return; Item[] shelf = new Item[cart.length+1]; for(int i = 0; i < cart.length; i++) shelf[i] = cart[i]; // first make copy of array for(int i = cart.length; i < shelf.length; i++) shelf[i] = item; // add item to array cart = shelf; } catch(NoSuchItemException noSuchItemRef) { noSuchItemRef.printStackTrace(System.out); } } public int equals(String it) { for(int i = 0; i < cart.length; i++) if(cart[i].name.equals(it)) return i; return -1; } public int getItemIndex(Item item) throws IndexOutOfBoundsException { int index = this.equals(item.name); if(index == -1) throw new IndexOutOfBoundsException(); return index; } public Item[] getCart() { return cart; } public String toString() { StringBuilder displayCart = new StringBuilder(); for(Item ref : cart) { displayCart.append(ref.name); displayCart.append("\n"); } return displayCart.toString(); } public static void main(String[] args) { String[] shoppinglist = { "Bread", "Milk", "Sugar" }; ShoppingCart cart = new ShoppingCart(shoppinglist); System.out.println(cart); try { Item firstItem = new Item("Beans"); Item secondItem = new Item("Tshirt"); cart.addItem(firstItem); System.out.println(cart); cart.addItem(secondItem); System.out.println(cart); System.out.println(cart.getItemIndex(firstItem)); System.out.println(cart.checkItem(secondItem)); Item thirdItem = null; cart.addItem(thirdItem); } catch(NoSuchItemException noSuchItemRef) { noSuchItemRef.printStackTrace(System.out); } catch(IndexOutOfBoundsException outOfBoundsRef) { outOfBoundsRef.printStackTrace(System.out); } } } /* Output Bread Milk Sugar Bread Milk Sugar Beans Bread Milk Sugar Beans Tshirt 3 true errors.handling.java.NoSuchItemException at errors.handling.java.ShoppingCart.checkItem(ShoppingCart.java:22) at errors.handling.java.ShoppingCart.addItem(ShoppingCart.java:35) at errors.handling.java.ShoppingCart.main(ShoppingCart.java:84) Caused by: java.lang.NullPointerException at errors.handling.java.ShoppingCart.checkItem(ShoppingCart.java:25) ... 2 more *// *// The example describes aShoppingCart that is composed of an array ofItem objects that are first initialised when aShoppingCart object is created. You can then subsequently add additional items, check for an item or return the index of a specific item. To add an item, you first make a temporary copy of the array with length one longer than current array, append the item to that and then copy back to the original array in a way that is an abstraction of the process of selecting items from a shelf at your local supermarket. If you try adding a null value, the checkItem() method throws a custom exception distinct from the originalNullPointerException which we pass to theinitCause() method of the custom exception. You can see a NullPointerException is listed as the original cause of this exception in the output. 

Turning off checked exceptions

Exception chaining also allows you to, in effect turn off checked exceptions by converting them to unchecked exceptions without losing any information about the original exception. You do this by wrapping a checked exception in the inside of aRuntimeException like so:- package errors.handling.java; import java.io.IOException; public class TurnOffException { static void throwAnException() { System.out.println("Throwing new exception from throwAnException()"); try { throw new IOException(); } catch(IOException ioExceptionRef) { throw new RuntimeException(ioExceptionRef); } } public static void main(String[] args) { try { TurnOffException.throwAnException(); } catch(RuntimeException runtimeExceptionRef) { try { throw runtimeExceptionRef.getCause(); } catch(IOException ioExceptionRef) { System.out.println("IOException " + ioExceptionRef); }catch(Throwable throwableRef) { System.out.println("Throwable " + throwableRef); } } //can call method without try block TurnOffException.throwAnException(); } } /* Output Throwing new exception from throwAnException() IOException java.io.IOException Throwing new exception from throwAnException() Exception in thread "main" java.lang.RuntimeException: java.io.IOException at errors.handling.java.TurnOffException.throwAnException(TurnOffException.java:11) at errors.handling.java.TurnOffException.main(TurnOffException.java:27) Caused by: java.io.IOException at errors.handling.java.TurnOffException.throwAnException(TurnOffException.java:9) ... 1 more *// This technique effectively allows you to ignore the checked exception relieving you of the need of having to write try/catch clauses and/or the usual exception specification. 

Throwing custom exceptions

You might sometimes find it necessary to create your own exceptions to handle errors that might be peculiar to your own library by inheriting from an existing exception class, ideally an exception that more closely matches in meaning of your own exception:-package errors.handling.java; import java.util.Random; class CustomException extends Exception { public CustomException(String message) { System.out.println(message); } } public class ThrowAnException { public void throwCustomException(int condition) throws CustomException { if(condition == 5) throw new CustomException("Just got ejected!"); System.out.println("condition = " + condition); //some code } public static void main(String[] args) { ThrowAnException objRef = new ThrowAnException(); try { for(int i = 0; i < 100; i++) objRef.throwCustomException(new Random().nextInt(6)); } catch(CustomException customExceptionRef) { System.out.println("Caught it!"); } } } /* Output i = 3 i = 0 i = 3 Just got ejected! Caught it! *// Here, we inherit from the base Exception class to create aCustomException that is thrown in the main whenevercondition == 5. The methodthrowCustomException() uses the the exception specification syntax to describe it's potential to throw aCustomException. Whenever we come across a method that uses the exception specification to declare a list of potential exceptions, this is the clue that we must handle this exception whenever we call the method. In true OOP tradition, inheritance further imposes other constraints on derived classes with respect to the exception specification. For instance, when you override a method that defines an exception specification, the derived method can only throw those exceptions that have been specified in the base method, or exceptions derived from those specified in the base method, or it can choose not to throw any methods at all, but it can not throw a different set of exceptions to the one in the base class. With constructors however, this restriction is partially eased in a sense because even though a derived class must somehow account for exceptions thrown by the base class constructor, it is free to throw additional exceptions. Lastly, when you implement an interface in a derived class, methods inherited from that interface can not be expected to override those inherited from the base class. 

The finally statement

The finally clause is used to perform what is commonly referred to as 'clean up' operations in Java. These are the type of operations you would normally want your program to execute irregardless of whether or not an exception is thrown. Thefinally clause is normally placed at the end of atry/catch block. The kinds of operation you would normally want to place within a finallyclause include code to shut out a network connection after you no longer have any use for it, or close a file once your program has successfully read it's contents or some other such operation. In a sense, the finally clause allows you to delay the termination of the current execution path following a thrown exception, just long enough to execute some code. In the following example, a FileResource class uses aFileReader and a BufferedReader object from the Java standard I/O library to open and read a file. Java's API reference describes the FileReader class constructor as possibly throwing aFileNotFoundException. The FileResourcehas a read() method to read the file and aclose() to perform clean up at the end of the object's lifetime. The close() method of this class calls theclose() method of the BufferedReaderobject to close the stream and release any system resources associated with it:- package errors.handling.java; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; class FileResource { private BufferedReader reader; String path = "/home/geekfest/eclipse/notice.html"; File resource = new File(path); public FileResource() throws FileNotFoundException { try { reader = new BufferedReader(new FileReader(resource)); } catch(FileNotFoundException ref) { System.out.println("unable to open file " + resource); ref.printStackTrace(); } finally { //Don't close here } } public String read() { String output = null; try { output = reader.readLine(); } catch(IOException ref) { ref.printStackTrace(System.out); } return output; } public void close() { try { reader.close(); System.out.println("close() successful"); } catch(IOException ref) { ref.printStackTrace(System.out); } } } public class ConsoleDevice { public static void main(String[] args) { try { FileResource resource = new FileResource(); try { String console; while((console = resource.read()) != null); //System.out.println(console); } catch(Exception ref) { ref.printStackTrace(System.out); } finally { resource.close(); } } catch(Exception ref) { ref.printStackTrace(System.out); } } } /* Output close() successful *// In the main() of theConsoleDevice class we use a set of nestedtry blocks to safely create and use theFileResource class to read text from a file unto our console object. Following the while loop in the innertry block, we call the close() method in the finally clause to perform clean up, at the only point in the program we can be certain clean up will be necessary. 

try-with-resources statement

With Java SE 7 came the introduction of the try-with-resources statement to ensure that each resource is automatically closed at the end of a statement. A resource includes any object that implements AutoClosable. The following example demonstrates the the use of the try-with-resources statement with out FileResource class:- package errors.handling.java; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; class FileResource implements AutoCloseable { private BufferedReader reader; String path = "/home/geekfest/eclipse/notice.html"; File resource = new File(path); public FileResource() throws FileNotFoundException { try { reader = new BufferedReader(new FileReader(resource)); } catch(FileNotFoundException ref) { System.out.println("unable to open file " + resource); ref.printStackTrace(); } finally { //Don't close here } } public String read() { String output = null; try { output = reader.readLine(); } catch(IOException ref) { ref.printStackTrace(System.out); } return output; } public void close() { try { reader.close(); System.out.println("close() successful"); } catch(IOException ref) { ref.printStackTrace(System.out); } } } public class ConsoleDevice2 { public static void main(String[] args) throws FileNotFoundException { try (FileResource resource = new FileResource();) { String console; while((console = resource.read()) != null); //System.out.println(console); } } } /* Output close() successful *// In example, thetry-with-resources statement is implemented in themain() by means of a call to ourFileResource class within the parenthesis that appear following the try keyword. OurFileResource class has had to be modified to implement the java.lang.AutoCloseable interface. With thetry-with-resources statement, you do not need to include a finally statement because the resource will be closed regardless of whether the try statement fails to complete. In addition, exceptions thrown from from within the try block will supercede those thrown from thetry-with-resources statements it self which become suppressed. You can include one or more resources in atry-with-resources statement declaration, by separating each call with a semi-colon. Each resources'close() method will be called in the opposite order of their creation.  
If you have followed previous posts, you might begin to perceive a pattern in the semantics of the Java programming language. If not, it might help to go over previous posts as I tend to return to expand on previous topics or add clearer examples as time permits. Inner classes might at first seem like a whole new language to the uninitiated but they are a nice feature in Java that allow you to logically group related classes and control the visibility of one class from outside of the other.  Even more than that, inner classes provide you with the ability to inherit from more than one interface or implementation in a kind of "multiple implementation inheritance". The code in an inner class can be used to manipulate the members of the outer class within which it exists. Inner classes are not limited to the functionality of the base class of the outer class, but can inherit independently of it. Whereas outer classes allow you to undertake some kind of multiple inheritance with interfaces, inner classes allow you to do the same thing not only with interfaces but with abstract or concrete classes. This mechanism allows you to code solutions to some otherwise intractable programming problems. The syntax for creating inner classes is pretty straightforward:- package kingsley.java; public class Company { class Employee { private String name; Employee(String name) { this.name = name; } public String getName() { return name; } } class Department { private String name; Department (String name) { this.name = name; } public String getName() { return name; } } public Employee employed(String name) { return new Employee(name); } public Department department(String name) { return new Department(name); } public void newStarter(String name, String department) { Employee emp = employed(name); Department dpt = department(department); System.out.println(emp.getName() + " is a member of " + dpt.getName()); } public static void main(String[] args) { Company c = new Company(); c.newStarter("kingsley", "IT"); // Referencing inner classes Company.Employee ce = c.employed(); Company.Department cd = c.department(); } } /* Output kingsley is a member of IT *// Here, the outer class Companyhas methods that return references to the inner classesEmployee and Department. ThenewStarter() within the outer class is able to use inner classes like it would any other class, with the only difference being these classes are actually nested withinCompany. In the main() notice how we reference objects of the inner classes withOuterClassName.InnerClassName. This is necessary because objects of any non-static inner class can only be created in association with an object of the outer class, outside of any non-static method within the outer class. As a consequence, objects of the inner classes you create usually have access to all the private and protectedmembers of the surrounding class without any special syntax. This is because when you create an inner class in Java, the compiler captures a reference to the particular enclosing class within which the inner class exists, thus making it possible to reference members of the enclosing class, in this way, a derived inner class can be used to manipulate the members of an enclosing class. The following example demonstrates this clearly:- package kingsley.osime; interface Repeater { boolean start(); String current(); void next(); } public class StringArray { private static String[] sequence; public StringArray(String s) { this.sequence = s.split(" "); } private class ReverseSequence implements Repeater { private int i = 0; public boolean start() { return i == sequence.length; } public String current() { return sequence[sequence.length-(i+1)]; } public void next() { if(i < sequence.length) ++i; } } public Repeater repeater() { return new ReverseSequence(); } public static void main(String[] args) { StringArray sa = new StringArray("Good sense is of all things the most " + "equally distributed among men"); Repeater repeater = sa.repeater(); while(!repeater.start()) { System.out.print(repeater.current() + " "); repeater.next(); } } } /* Output men among distributed equally most the things all of is sense Good *// In this example, the derived inner classRequestSequence is used to manipulate the array member within the enclosing class by providing functionality for an interface that acts like an iterator. In this instance the content of the array member is read in reverse. 

Multiple implementation inheritance

With inner classes you can solve the problem of multiple implementation inheritance when you are limited to working with abstract or concrete classes as opposed to interfaces:-package Innerclasses.java; abstract class A {} class B {} class C extends A { class D extends B { } } public class MultipleImplementation { static void takesA(A a) {} static void takesB(B a) {} public static void main(String[] args) { C c = new C(); takesA(c); // using dot new to create object //inner class directly takesB(c.new D()); } } Note the use of an object of the outer class followed by the new keyword to create an object of the inner class in the takesB() method. Java will not allow you to create an object of the inner class directly, unless you already have an object of the outer class. The only exception to this rule is when you are dealing with nested classes i.e. inner classes that have been declared static 

.this keyword

If you want to reference the outer class from within the inner class, you must first reference the outer class followed by a dot and then the this keyword like so:- package kingsley.osime; public class Outer { void d() { System.out.println("Outer d()"); } public class Inner { public Outer getOuter() { return Outer.this; } } public Inner getInner() { return new Inner(); } public static void main(String[] args) { Outer ot = new Outer(); Outer.Inner oi = ot.getInner(); oi.getOuter().d(); } } /* Output Outer d() *// If you were to use the this keyword on its own from within the inner class, Java will return a reference to the inner class itself. Just as an inner class is able to reference the members of the outer class without qualification, an outer class is likewise able to access the private elements of the inner class but must do so by directly referencing the inner class:-package Innerclasses.java; public class Outer { class Inner { private String s = "My String"; } public String innerString() { return new Inner().s; } public static void main(String[] args) { Outer ot = new Outer(); System.out.println(ot.innerString()); Outer.Inner oi = ot.new Inner(); } } /* Output My String *//

Upcasting inner classes

Inner classes provide a very useful way to hide implementation when inheriting from a base class or interface, in this way, one may restrict the visibility of one's classes from client programmers by providing only a reference to the base class or interface. Here is a modified version of an earlier example to illustrate this point; we modify our Employee and Departmentimplementations to interfaces and inherit from both usingprivate and protected inner classes here:- package Innerclasses.java; import Interfaces.java.Department; import Interfaces.java.Employee; class Company1 { String employee; String department; protected class NEmployee implements Employee { public String getName() { return employee; } } private class NDepartment implements Department { public String name() { return department; } } public Employee employed() { return new NEmployee(); } public Department getName() { return new NDepartment(); } } public class NewCompany { public static void main(String[] args) { Company1 c1 = new Company1(); Employee emp = c1.employed(); Department dept = c1.getName(); Company1.NEmployee ce = c1.new NEmployee(); // Can not access private inner class //! Company1.NDepartment cn = c1.new NDepartment(); } } Note that when you apply theprivate access specifier to a derived inner class you restrict access to that class to the client programmer thereby preventing any type coding dependencies. Take note of the upcasting taking place within the public interface of the outer class from a more specific class to the more generalised type. Further, unlike aprivate inner class, a protected inner class does allow some limited access. 

Inheriting from inner classes

On the subject of inheritance, Java does not prevent you from inheriting from an inner class when such a design make sense to you. The only requirement is that you make the association between the outer class and inherited inner class, explicit like so:-class Outer { class Inner {} } public class InnerInheritance extends Outer.Inner { InnerInheritance(Outer ot) { ot.super(); } public static void main(String[] args) { Outer ot = new Outer(); InnerInheritance ii = new InnerInheritance(ot); } } When you inherit from an inner class, you need to add special syntax to the constructor as the default constructor will not work. Note how we reference the enclosing class of the inherited inner class from within the derived class constructor in order to provide the correct reference. 

Local and anonymous inner classes

Java also allows you to create what we refer to as local and anonymous inner classes that exist within method scopes. A local inner class is a class created within the scope of a method as opposed to just being within a class. You use a local inner class to return a reference when you're implementing an interface and to help solve some very complex programming problems whereby a class might be the only means of sufficiently expressing the level of complexity required. An anonymous inner class is a local inner class that has no name and can be expressed within a method or arbitrary scope. The syntax for both types of classes is like so:-package Innerclasses.java; import Interfaces.java.Employee; public class Company2 { public Employee createEmployee(String name) { class NewEmployee implements Employee { String name; public NewEmployee(String myName) { this.name = myName; } public String getName() { System.out.println(name); return name; } } return new NewEmployee(name); } public Employee createEmployee2() { return new Employee() { String name = "kingsley-Anonymous"; public String getName() { System.out.println(name); return name; } }; } public static void main(String[] args) { Company2 c2 = new Company2(); Employee em = c2.createEmployee("Kingsley-local"); Employee em2 = c2.createEmployee2(); em.getName(); em2.getName(); } } /* Output Kingsley-local kingsley-Anonymous *// As you can see, the local inner class begins and ends within the scope of a method, aside from which it is no different to how you would implement any other class. The anonymous inner class provides exactly the same functionality as an inner class except that it is shorthand and quicker to write because you write the class as an expression within the method or scope. Here we simply implement the methods within the interface as we would do if we were implementing in a class. Notice the semi-column at the end of the expression as if it were any other statement in Java. Theoretically, we can implement local and anonymous inner classes within any arbitrary scope surrounded by curly braces. 

Nested classes

Nested classes are inner classes that have been declaredstatic. When you declare an inner classstatic, you do not require an object of the outer class to create the inner class and you are restricted from accessing a non-static outer class from an object of a nested class. Here is our Company example modified to use nested inner classes:- package Innerclasses.java; import Interfaces.java.Department; import Interfaces.java.Employee; public class Company4 { private static class NewEmployee implements Employee { private String name; NewEmployee(String name) { this.name = name; } public String getName() { return name; } } protected static class EmployeeDepartment implements Department { private String name; EmployeeDepartment (String name) { this.name = name; } public String name() { return name; } static class BusinessUnit { static String bu = " Finance "; static String getBU() { return bu; } } } public static Employee employed(String name) { return new NewEmployee(name); } public static Department department(String name) { return new EmployeeDepartment(name); } public static void main(String[] args) { Employee em = employed("kingsley"); Department dept = department("IT"); System.out.println(Company4.EmployeeDepartment.BusinessUnit.getBU()); } } /* Output Finance *// In this example, note how we do not require an object of the outer class to create an object of the inner class in the main(). Unlike a non-staticinner class, a nested inner class can have staticdata, fields and other nested static classes as you can observe from the nested BusinessUnit class. 

Nesting within interfaces

Java also allows you to nest classes within interfaces when you wish to create some common code to be used by different implementations of the interface. When you put a class in an interface it is automatically public, however you must explicitly declare the class static to ensure it does not violate the normal interface rules. Here's an example that implements the enclosing interface in the nested class:-package Innerclasses.java; public interface NestedInterface { void f(); static class InnerClass implements NestedInterface { public void f() { System.out.println("Nested Class in Interface"); } public static void main(String[] args) { new InnerClass().f(); } } } /* Nested Class in Interface *// 

Implementing callbacks

At once inner classes might seem like a bit tedious and rather difficult to manage to the impatient mind, but it is worth taking the extra effort to understand some of the benefits of using inner classes in your program code. As mentioned earlier, inner classes allow you to inherit from more than one abstract or concrete class, something you are severely restricted from doing with outer classes. Further more, a single outer class can have multiple inner classes implementing the same interface in different ways. This is a particularly powerful programming technique that allows you to implement a control type framework like theTemplate method design pattern. Because inner classes retain scope information, they also allow you to provide a kind of call-back mechanism which acts like a pointer in your code. With a callback some other object is has the necessary information to reach back into the originating object at some later point in time:- import java.util.ArrayList; import java.util.List; interface U { void a1(); void a2(); void a3(); } class A { int i = 0; int count; public A(int i) { this.i = i; count = i++; } public U getU() { return new U() { public void a1() { System.out.println("a1() " + count); } public void a2() { System.out.println("a2() " + count); } public void a3() { System.out.println("a3() " + count); } }; } } class B { U[] ul = new U[3]; int i = 0; public void addRef(U ui, int i) { ul[i] = ui; } public void setRef(int i) { System.out.println("Setting element at " + i + " to null"); ul[i] = null; } public void goOver(int i) { ul[i].a1(); ul[i].a2(); ul[i].a3(); } } public class Callback { public static void main(String[] args) { B b = new B(); for(int i = 0; i < 3; i++) { A a1 = new A(i); b.addRef(a1.getU(), i); b.goOver(i); } b.setRef(1); } } /* Output a1() 0 a2() 0 a3() 0 a1() 1 a2() 1 a3() 1 a1() 2 a2() 2 a3() 2 Setting element at 1 to null *// This simple example creates a method in classA that returns a reference to interface Uby building an anonymous inner class. In a second classB we create an array containing Ureferences and implement various methods that allows us to accept and add U references to the array, removeU references from the array and a third method through which we can move through the array and call the methods inU. In the main(), we populate a singleB object with U references returned by a number of A objects. We then use B to call back into all the A objects. This is a simplification of a very powerful programming technique. Understanding when and how to use inner classes is more of a design issue that should become second nature with repeated practice to the dedicated programmer.  

In the normal course of solving a general programming problem, it is almost certain that you will become compelled to create, and identify useful ways by which to hold any number of objects within your program. In Java, you are normally inclined toward the array as the natural choice for holding a group of primitives, but this has the obvious limitation of being of a fixed size, whereas, under normal circumstances, you are unlikely to know before hand, the number of objects, or indeed anything about their type before run-time.

The java.util package provides a collection of type safe containers with which you can very quickly and easily begin to solve a number of well documented programming problems. These containers are expressed as basic interfaces of two libraries - 1) Collection interface:- which describe a sequence of individual elements to which certain rules may be applied. Containers within this category include List, Set and Queue and 2) Map interface:- a group of key-value pairs that allow you to look up a value using a key. A Map is also known as an associative array. Type safety within this context refers to the ability to ensure that only objects of the specified type can be inserted into a particular container. Java makes this possible through the use of generics, which provides a way for classes and interfaces to become parameters within other classes, interfaces and methods. For instance, one of the most commonly used container in Java is the ArrayList which represents a type of Collection. We could create a type safe ArrayList container to hold Fruit objects in the following way:- ArrayList<Fruit> fruits = new ArrayList<Fruit>();The angle brackets surrounding the type parameter is used to denote  the actual type (class or interface) for which purpose the container was created. Java's containers are very simple to learn and use once you are able to get your head around the concept of generics. The following examples are designed to further elucidate the matter. First a non-parameterised  container is used to  hold a number of unrelated objects:- package kingsley.java import java.util.ArrayList;   class Fruit {     private static long counter;     private final long id = counter++;     public long getId() { return id; } } class Furniture { } public class UsingNonParameterisedContainer {     @SuppressWarnings("unchecked")     public static void main(String[] args) {         ArrayList fruits = new ArrayList();         for(int i = 0; i < 2; i++)             fruits.add(new Fruit());         fruits.add(new Furniture());         for(int i = 0; i < fruits.size(); i++)             System.out.println((Fruit)fruits.get(i));                //! Class cast Exception     } } In this example a non-parameterised ArrayList class is used to hold Fruit and Furniture objects, both of which are of dissimilar types. Because the container is not parameterised, the compiler is unable to undertake any form of type checking and elements are upcast to Object making it possible to include different  types into the container absent warning. The problem arises when we go to retrieve elements from the container and we have to make a cast back to the original types. In this particular example, the compiler reports a class cast exception because it is unable to cast a Furniture object to Fruit In contrast to the previous example, this next example uses a type safe container (generics) to achieve much the same thing with the proviso that these containers are much more intuitive and produce better result:- package kingsley.java import java.util.ArrayList; class Mango extends Fruit {} class Orange extends Fruit {} class Funiture {} class Table extends Furniture {} public class UsingParameterisedContainer {     public static void main(String[] args) {         ArrayList<Fruit> fruits = new ArrayList<Fruit>();         for(int i = 0; i < 3; i++)             fruits.add(new Mango());         fruits.add(new Orange());         //fruits.add(new Table()); Compiler error!         for(int j = 0; j < fruits.size(); j++)             System.out.println(fruits.get(j).getId());         //using foreach syntax to iterate through list         for(Fruit f : fruits)             System.out.println(f.getClass().getSimpleName());     } } /*Output 0 1 2 3 Mango Mango Mango Orange *// In this version of a previous code, the parameterised container ArrayList is configured to hold Fruit objects with the addition of angle brackets that denote  the use of generics. In this example, a number of Fruit subtypes are added to the container with little fuss, but the attempt to add a Table object induces a compiler error. The compiler protects Java's containers from abuse by undertaking type checking  to guarantee that the container holds only the specified type. As a result of this guarantee, note that there is now no need to make a cast when retrieving elements from the container. In the previous example, a wrong type was only flagged at runtime, with Java's post SE 5 containers you get to find out about these sorts of bugs much sooner. The example further demonstrates how to select each element from within the container using both the for loop and foreach syntax, both of which are ideally suited to a number of different scenarios. The use of the foreach syntax with any Collection object is made possible because of the presence of the Iterable interface whose iterator() method produces an Iterator.

Collection<E> Interface

In Java, collections is a term used to describe a single unit or group comprising of multiple elements. It is synonymous with the concept of a container and both are often used interchangeably. Java provides a collections framework that comprise more than a dozen interfaces that make it possible for containers to be manipulated independent from the details of their implementation. At the root of this framework is the Collection interface which  represents a generalisation of the concept of a collection implemented by all containers of this type in a way that allows for  a greater level of flexibility and variety in the range of it's application and implementation. An ArrayList is an oft used type of Collection which we might have chosen to implement in the following way:- Collection<Fruit> fruits = new ArrayList<Fruit>();  By upcasting an ArrayList object to a Collection reference, we are in effect programming to the interface. This is a preferred method of programming that encourages loose coupling and high cohesion. Of course, such an arrangement would restrict our access to the methods in the ArrayList class, however this technique provides us with much flexibility that means we could easily switch implementation to any other subtype of the Collection interface with very little effort. The Collection interface provides several methods that can be used to manipulate elements within containers including for instance some of the more frequently used ones like size() method, which returns the number of elements in the specified collection, the iterator() method, returns an iterator over all elements in the collection, the remove() method which removes an instance of the specified element from the collection, the toArray() method which returns an array containing all of the elements in this collection and a number of others. One may wish to consult the Java API for the full list of  methods available to  subtypes of the Collectioninterface.

List<E> Interface

List is a basic type of Collection that maintains elements in a particular sequence and may contain duplicate elements. In addition to the methods inherited from the Collection interface, List provides additional methods including for instance methods that allow indexed access to elements within the list and unlike arrays, are automatically resizeable to accommodate additional elements. The most commonly used List implementation include those referred to previously i.e. ArrayList - a type of List that particularly excels at randomly accessing elements but is less efficient at insertion and removal operations and LinkedList - a type of List that performs insertion and removal operations more efficiently than does an ArrayList but is known to be less efficient at random access operations. In addition to Implementing the basic List interface, a LinkedList includes methods that make it useable as a Queue or double-ended queue (Deque). A Deque is a linear collection of elements that allows the addition and removal of elements at both end points. The following example demonstrates some of the more common operations associated with objects of a List subtype:- import java.util.*; public class ListsOperations {       public static void main(String[] args) {         ArrayList<Integer> arrayList = new ArrayList<Integer>(10);         LinkedList<Integer> linkList = new LinkedList<Integer>();         Random rand = new Random(10);         for(int i = 0; i < 10; i++) {             arrayList.add(i*rand.nextInt(100));             linkList.add(arrayList.size()*rand.nextInt(100));         }         System.out.println("1: arrayList = " + arrayList);         arrayList.add(new Integer(500));// appends to end of list         System.out.println("2: arrayList.add(new Integer(500)) = " +  arrayList);         System.out.println("3: arrayList.contains(new Integer(500)) = " + arrayList.contains(new Integer(500)));         System.out.println("4: arrayList.remove(new Integer(92)) = " + arrayList.remove(new Integer(92)));         System.out.println("5: arrayList.indexOf(291) = " + arrayList.indexOf(291));         System.out.println("6: linkList = " + linkList);         System.out.println("7: linkList.getFirst() = " + linkList.getFirst());         linkList.addFirst(new Integer(1000));// insert element at beginning of list         System.out.println("8: linkList.addFirst(new Integer(1000)) = " + linkList);         linkList.offer(new Integer(1000)); // adds as tail element         System.out.println("9: linkList.offer(new Integer(1000)) = " + linkList);         arrayList.addAll(linkList);// add to arraylist         System.out.println("10: arrayList.addAll(linkList) = " + arrayList);         List<Integer> subList = arrayList.subList(5, 11);// new list from arraylist         System.out.println("11: arrayList.containsAll(subList) = " + arrayList.containsAll(subList));         System.out.println("12: subList = " + subList);         Collections.sort(subList); //sort in ascending order         System.out.println("13: Collections.sort(subList) = " + subList);         Collections.shuffle(subList); // random permutations         System.out.println("14: Collections.shuffle(subList) = " + subList);     } } /* Output 1: arrayList = [0, 93, 92, 291, 324, 115, 546, 665, 688, 657] 2: arrayList.add(new Integer(500)) = [0, 93, 92, 291, 324, 115, 546, 665, 688, 657, 500] 3: arrayList.contains(new Integer(500)) = true 4: arrayList.remove(new Integer(92)) = true 5: arrayList.indexOf(291) = 2 6: linkList = [80, 180, 168, 352, 70, 594, 56, 640, 477, 380] 7: linkList.getFirst() = 80 8: linkList.addFirst(new Integer(1000)) = [1000, 80, 180, 168, 352, 70, 594, 56, 640, 477, 380] 9: linkList.offer(new Integer(1000)) = [1000, 80, 180, 168, 352, 70, 594, 56, 640, 477, 380, 1000] 10: arrayList.addAll(linkList) = [0, 93, 291, 324, 115, 546, 665, 688, 657, 500, 1000, 80, 180, 168, 352, 70, 594, 56, 640, 477, 380, 1000] 11: arrayList.containsAll(subList) = true 12: subList = [546, 665, 688, 657, 500, 1000] 13: Collections.sort(subList) = [500, 546, 657, 665, 688, 1000] 14: Collections.shuffle(subList) = [1000, 657, 665, 546, 500, 688] *// Note that both types of lists store elements in the order in which they are inserted and both constitute a modifiable sequence i.e the quality of being automatically resizable. Line 2 adds an element to the list, line 3 checks if the list contains a particular element, line 4 removes an element from the list and line 5 returns the index of a referenced element. Note that these operations use the equals() method inherited from the root Object to decide if any two objects are equal and as a consequence may behave differently depending on the behaviour of the equals() method. This example uses Integer wrapper classes that define equality as values being of an equivalent primitive type. LinkedList has methods that provide very similar behaviour but have different names to reflect the context of particular usage. For instance, the getFirst(), element() and peek() methods all return the head or first element in the list, while getFirst() and element() throw a NoSuchElementException if the list is empty, the peek() method returns null.  The same applies to the remove() and removeFirst() methods both of which remove and return the head of the list and will throw a NoSuchElementException if a list is found to be empty, while the poll()method provides a similar functionality but will return null in the event of an empty list. Only a few of these methods are demonstrated in the above example.

Set<E> Interface

A Set has only a slightly different interface as a Collection, but produces a different behaviour which does not allow for duplicate elements from among the set. One of the more common uses of a Set is for membership lookup i.e. to test for the existence of an object within the set. A Set determines membership based on the value of an object. Set implementations include HashSet, TreeSet and LinkedHashSet, all of which differ in how they store and process  elements. For example, HashSet uses a hashing function to add speed to it's processing of elements and makes no guarantees as to the iteration order of the set, while TreeSet keeps elements sorted in a red black tree structure and is based on a TreeMap.  Finally, a LinkedHashSet maintains elements in the order of insertion using a LinkedList but also uses hashing for lookup. Here is an example of some operations available to objects that implement the Set interface:- import java.util.*; public class SetOperations {     public static void main(String[] args) {         Set<String> hashset = new HashSet<String>();         HashSet<String> linkhashset = new LinkedHashSet<String>();         Collections.addAll(linkhashset, "A E I O U".split(" "));         Collections.addAll(hashset, "A B C D E F".split(" "));         System.out.println("1: linkhashset = " + linkhashset);         System.out.println("2: hashset = " + hashset);         System.out.println("3: linkhashset.contains(\"X\") = " + linkhashset.contains("X"));// membership lookup         System.out.println("4: linkhashset.containsAll(hashSet2) = " + linkhashset.containsAll(hashset));         Collections.addAll(linkhashset, hashset.toArray(new String[0]));         System.out.println("5: Collections.addAll(linkhashset, hashset) = " + linkhashset);         System.out.println("6: linkhashset.containsAll(hashSet2) = " + linkhashset.containsAll(hashset));         System.out.println("7: hashset.remove(\"E\") = " + hashset.remove("E"));         System.out.println("8: hashset" + hashset);         System.out.println("9: hashset.removeAll(linkhashset) - " + hashset.removeAll(linkhashset));         System.out.println("10: hashset" + hashset);         Collections.addAll(linkhashset, hashset.toArray(new String[0])); // No duplicates         System.out.println("11: linkhashset" + linkhashset);         String v = new String("V");         linkhashset.add(v);         System.out.println("12: linkhashset.add(v) = " + linkhashset);         System.out.println("13: linkhashset.contains(v) = " + linkhashset.contains(v));     } } /* Output 1: linkhashset = [A, E, I, O, U] 2: hashset = [A, B, C, D, E, F] 3: linkhashset.contains("X") = false 4: linkhashset.containsAll(hashSet2) = false 5: Collections.addAll(linkhashset, hashset) = [A, E, I, O, U, B, C, D, F] 6: linkhashset.containsAll(hashSet2) = true 7: hashset.remove("E") = true 8: hashset[A, B, C, D, F] 9: hashset.removeAll(linkhashset) - true 10: hashset[] 11: linkhashset[A, E, I, O, U, B, C, D, F] 12: linkhashset.add(v) = [A, E, I, O, U, B, C, D, F, V] 13: linkhashset.contains(v) = true *// The example upcasts a HashSet object to a Set and a LinkedHashSet to a HashSet. Both containers are populated using the utility Collections.addAll(). The rest of the example demonstrates some of the methods available to subtypes of the Set interface. Further if you are interested in an ordered set of results, you can make use of a SortedSet like so:- SortedSet<Integer> treeSet = new TreeSet<Integer>();

Queue<E> Interface

A Queue is a type of Collection that typically takes a "first-in-first-out" (FIFO) approach to the processing of elements. This is to say elements are retrieved in the same order in which they are inserted with the exception of objects that implement the  priority queue discipline - which is an alternative queuing technique that subscribes to highest priority or greatest need. Queue objects can be used as a reliable means to comfortably transfer objects from one area of your program to another and  they also possess the peculiar feature of including multiple forms for methods that provide a common functionality but behave differently in that whereby one form throws an exception in the event of an operation failure, the other returns some special value given similar circumstances:- import java.util.*; public class QueueOperations {     public static void main(String[] args) {         Queue<Character> qe = new LinkedList<Character>();         for(char c : "Encyclopedia".toCharArray())         qe.offer(c);         System.out.println("Queue.offer() - "+ qe);         qe.poll();         System.out.println("Queue.poll() - "+ qe);         System.out.println("queue.peek() " + qe.peek());         qe.add(new Character('E'));         System.out.println("queue.add() " + qe);     } /* Output fer() - [E, n, c, y, c, l, o, p, e, d, i, a] Queue.poll() - [n, c, y, c, l, o, p, e, d, i, a] queue.peek() n queue.add() [n, c, y, c, l, o, p, e, d, i, a, E] *// The offer() method inserts the specified element into the queue if possible and returns false in the event of a failure. The add() method inherited from the Collection interface performs the same operation which it can only fail by throwing an exception, as a result, the offer() method is the preferred option. The poll() method retrieves and removes the head of the queue, or returns null if the queue is empty. The remove() method performs the same operation but throws an exception if the queue is empty. The peek() and element() methods retrieve but do not remove the head of the queue. While the element() method will  throw an exception if the queue is empty, the peek() method returns nullgiving the same set of circumstances.

Map<K,V> interface

A Map is quite unlike those subtypes of Collection with which we have by now become familiar, in fact it is a very distinct data structure. The Map  interface describes methods that operate on key/value pairs, providing you with the ability to map objects to other objects by using a key to map to at most a single value, and for which duplicate keys are forbidden. Map implementation  include HashMap, TreeMap and LinkedHashMap, all of which provide similar behaviour and performances to those described in the  Set interface subheading. Some of the methods available to Map objects include those for performing basic operations like put(), get(), remove(), size(), containsKey(), containsValue(), et cetera as well as other methods that perform bulk operations and provide collection views:- import java.util.*; public class MapOperations {       public static void main(String[] args) {         Map<String, String> myPets = new HashMap<String, String>();         myPets.put("new Dog ", " woof woof");         myPets.put("new Cat ", " meeow meeow");         myPets.put("new bunnyRabbit ", " honk honk");         System.out.println("myPets: " + myPets);         System.out.println("myPets.containsKey(\"new cat\") = " + myPets.containsKey("new Cat "));         System.out.println("myPets.containsValue(\"honk honk\") = " + myPets.containsValue(" honk honk"));     } } /* Output myPets: {new Cat = meeow meeow, new Dog = woof woof, new bunnyRabbit = honk honk} myPets.containsKey("new cat") = true myPets.containsValue("honk honk") = true *// The above code is a simple example of how to look up objects and values in a Map using the containsKey() and containsValue() method. A Map provides a very powerful abstraction that simplify very many programming problems, for instance, here is a program that tracks the pseudo-random nature of Java's Random class, where the number produced by the Random is assigned as the key and the  number of times that number is produced is taken to be the value. It would be necessary to generate very many random numbers restricted to a small subset of numbers:- import java.util.*; public class MapOperations2 {       public static void main(String[] args) {         Map<Integer, Integer> map = new LinkedHashMap<Integer, Integer>();         Random rand = new Random(25);         for (int i = 0; i < 2000; i++) {             int x = rand.nextInt(10);             Integer freq = map.get(x);             map.put(x, freq == null ? 1 : freq + 1);         }         System.out.println(map);       } } /* Output {1=200, 8=218, 7=194, 5=195, 6=198, 4=188, 0=198, 9=191, 2=220, 3=198} *// In this example, a ternary if/else operator is used to test and increment the frequency a particular number has been randomly generated.  Because Maps do not accept duplicate keys there is little chance of a particular key occurring more than once. Maps can also be expanded to include multiple dimensions by including other  maps whose values also happen to be other containers or even further made up of other maps. A Map may return a Collection of its values, a Set of its keys or a Setof its pairs.

Iterator design pattern

An Iterator object provides a way to iterate over the elements in a sequence without exposing its underlying implementation. It comes under the category of a behavioural design pattern and any discourse on Java's containers is incomplete without affording it adequate attention, since you may have perceived before now that most containers within the Java's collection framework implement the Iterable interface, which is a prerequisite for accessing an Iterator. A Map on the other hand produces a Set view of it's elements with the entrySet() method which proves sufficient for iteration purposes. An Iterator object provides you with a number of very useful methods that rest easily beside the concept of a container, like for instance the next() method which is a call to get the next element in the sequence, the hasNext() method which returns either of true or false according to whether the sequence remains empty or not, and the remove() method which removes the last element returned by the iterator:- import java.util.*; public class Iteration {     public static void main(String[] args) {         List<Integer> arraylist = new ArrayList<Integer>();         Random rand = new Random(27);         for(int i = 0; i < 8; i++)             arraylist.add((Integer)rand.nextInt(20));         System.out.println("arraylist: " + arraylist);         Iterator sequence = arraylist.iterator();         while(sequence.hasNext()) {             Integer next = sequence.next();             System.out.println("The double value for " + next + " is " + next.doubleValue());         }         sequence.remove();         System.out.println("arraylist: " + arraylist);     } } } /* Output arraylist: [10, 12, 17, 18, 11, 16, 10, 14] The double value for 10 is 10.0 The double value for 12 is 12.0 The double value for 17 is 17.0 The double value for 18 is 18.0 The double value for 11 is 11.0 The double value for 16 is 16.0 The double value for 10 is 10.0 The double value for 14 is 14.0 arraylist: [10, 12, 17, 18, 11, 16, 10] *// In this example, the iterator object sequence steps through the container sequentially, so long as the test condition in the while clause evaluates to true, printing the each element to screen. The example also demonstrates the use of the remove() method which removes the last element returned by the iterator from the underlying collection. Here is a method that uses an iterator to step through a sequence providing a view of the elements within a variety of containers:- import java.util.*; public class Iteration2 {     static void view(Iterator<Character> it) {         while(it.hasNext()) {             Character p = it.next();             System.out.print("[ " + p + " " + " ]");         }         System.out.println();     }     public static void main(String[] args) {         char[] cc = {'d', 'e', 'c', 'x', 'd'};         Random rand = new Random();         ArrayList<Character> list = new ArrayList<Character>();         LinkedList<Character> list2 = new LinkedList<Character>();         HashSet<Character> set = new HashSet<Character>();         for(int i = 0; i < cc.length; i++) {             list.add(cc[rand.nextInt(cc.length)]);             list2.add(cc[rand.nextInt(cc.length)]);             set.add(cc[rand.nextInt(cc.length)]);         }         view(list.iterator());         view(list2.iterator());         view(set.iterator());     } } /* Output [ d  ][ d  ][ c  ][ d  ][ c  ] [ e  ][ c  ][ e  ][ e  ][ d  ] [ d  ][ x  ] *// The view() method in this example has no knowledge of the underlying container or the type of sequence it is traversing, and therein lies the real value of the iterator design pattern - it provides you with the ability to separate the operation of traversing a sequence from the underlying implementation of the said sequence. An Iterator is limited only by it's ability to move in one direction only - forward through a sequence. A ListIterator is a subtype of Iterator that can only be produced by List subtypes and that has the unique quality of not only being bidirectional, meaning it can move forward and backward through a list, but it can also replace the most recently visited element using it's set() method, in addition to being able to produce the indexes of the next and previous elements relative to it's current position in the list. import java.util.ArrayList; import java.util.List; import java.util.ListIterator; class Element {     private static long counter = 0;     private final long id = counter++;     public String toString() {         return this.getClass().getSimpleName() + " " + id;     } } public class LisIteration {     static void listIterator(List list) {         ListIterator listIterator = list.listIterator(list.size());         while(listIterator.hasPrevious())             System.out.print("The " + (listIterator.previousIndex() == 1 ? "1st" :                                         (listIterator.previousIndex() == 2 ? "2nd" :                                           (listIterator.previousIndex() == 3 ? "3rd" :                                             (listIterator.previousIndex() == 4 ? "4th" :                                               (listIterator.previousIndex() == 5 ? "5th" : "0")))))                                                   +  " element is " + listIterator.previous() + "\n");         listIterator.set(new Element());     }     public static void main(String[] args) {         List<Element> l1 = new ArrayList<Element>();         for(int i = 0; i < 6; i++) {             l1.add(new Element());         }         listIterator(l1);         System.out.print(l1);     } } /* Output The 5th element is Element 5 The 4th element is Element 4 The 3rd element is Element 3 The 2nd element is Element 2 The 1st element is Element 1 The 0 element is Element 0 [Element 6, Element 1, Element 2, Element 3, Element 4, Element 5] *// The above example uses some rather elaborate code to print out the elements within a container while iterating backwards through the sequence and then replaces the most recently selected element using the set() method.  You may have noticed that unlike arrays, you can produce a printable representation of the elements within a container without the need for an additional API to parse the output like the Arrays.toString() method. Also unlike arrays, containers do not hold primitives, and must rely on wrapper classes to perform the necessary conversion using the autoboxing and autounboxing mechanism.

Interfaces are completely abstract classes in Java that provide you with a uniform way to properly delineate the structure or inner workings of your program from its publicly available interface, with the consequence being a greater amount of flexibility and reusable code as well as more control over how you create and interact with other classes. More precisely, they are a special construct in Java with the additional characteristic that allow you to perform a kind of multiple inheritance i.e. classes that can be upcast to more than one class; a technique from which you are severely restricted from undertaking (and with good reason) when working exclusively with classes. To create an interface in Java, you simply use the special interface keyword like this:- interface Transaction { ... }
You may include the public access identifier to the left of the interface keyword if the interface is defined in a file of the same name. Without the publickeyword, the interface defaults to package access. Interfaces have no implementation and therefore relieve you of any concerns pertaining to storage; this is to say your interface can only be implemented in a concrete class. When you create an interface, you may determine method names, arguments types as well as return types, but your methods will have no body because that is left to the imagination of those classes that implement a particular interface. A class is said to conform to an interface when it uses the special implements keyword in relation to a specific interface:- class Account implements Transaction { ... }
Once you implement an interface in a class, it becomes usable as you would any other class. The methods you declare in an interface must be implemented in your inheriting classes and must be declaredpublic. Interfaces may also include fields which are implicitly static and final. For instance, you could create different types of bank accounts to conform to a Transaction interface in the following way:-package kingsley.java interface Transaction { int BALANCE = 500; Object transaction(Object input); } class CurrentAccount implements Transaction { int bal; public Object transaction(Object input) { this.bal = BALANCE - (int)input; return bal; } public String toString() { return "Current acc"; } } class SavingsAccount implements Transaction { int bal; public Object transaction(Object input) { this.bal = BALANCE + (int)input; return bal; } public String toString() { return "Savings acc"; } } public class Account { public static void payment(Transaction t, Object input) { System.out.println(t + " is debited: " + t.transaction(input)); } public static void deposit(Transaction t, Object input) { System.out.println(t + " is credited: " + t.transaction(input)); } public static void main(String[] args) { Integer input = new Integer(600); deposit(new SavingsAccount(), input); payment(new CurrentAccount(), input); } /* Output Savings acc is debited: 1100 Current acc is credited: -100 *// Observe how both implementing classes CurrentAccount andSavingsAccount are automatically upcast in methods within the Account class that accept aTransaction interface. The payment() anddeposit() methods utilise what we call a Strategy design pattern and represent an instance of the complete decoupling of interface from implementation. Strategy design pattern allows method to vary independently from the clients that use it. Theoretically, you can adapt any class to use these methods by simply making them conform to the Transactioninterface. Interfaces give you a considerable amount of flexibility, and release you from the sort of constraints inherent in using particular data types and their subclasses. Note theBALANCE field in the Transaction interface which is a constant and is implicitly static andfinal. Finally, note that methods declared in interfaces have no body. One way to understand the utility of interfaces is to imagine how you might be able to utilise methods that accept interfaces within your own classes or how they might make it possible for others to make use of your own methods without having access to specific knowledge of its implementation, effectively keeping that part hidden. For example, imagine that a part of a program that allowed you to track the business activities of a property management company looked something like this:-package kingsley.java public class Activity { String name; public Property transact(Property input) { return input; } public String getName() { return name; } public static void main(String[] args) { System.out.println(new Sale(2).transact(new Property("1 Easy Street"))); System.out.println(new Purchase(8).transact(new Property("5 Main Street"))); } } class Property { private static long counter; private long id = counter++; private String address; public Property(String address) { this.address = address; } public String toString() { return "Property " + id + " at " + address; } } class Sale extends Activity { int id; String name = "Sale acc"; public Sale(int i) { this.id = i; } public Property transact(Property input) { return input; // Dummy transaction } public String getName() { return name; } } class Purchase extends Activity { int id; String name = "Purchase acc"; public Purchase(int i) { this.id = i; } public Property transact(Property input) { return input; } public String getName() { return name; } } /* Output Property 0 at 1 Easy Street Property 1 at 5 Main Street *// The purpose of this example is to demonstrate one of the ways by which one may reuse the previous Transactioninterface within a class that was perhaps written by a completely different individual. The Activity class represents certain business transactions that would be relevant to some property development company. On closer examination, you might notice that the Activity class contains some of the same elements as our earlier Transaction interface. This gives us some sign that it might be possible to make use of the Transaction interface to undertake some of those transactions defined as part of the public interface of theAccount class and which might be relevant to activities implemented in the Activity class. One way to do this, would be to make use of the Adapter designpattern to create an adapter that would allow us to quickly add value to our program. An implementation of this idea would look something like this:- package kingsley.java public class Activity { String name; public Property transact(Property input) { return input; } public String getName() { return name; } public static void main(String[] args) { Account.deposit(new ActivityAdapter(new Sale(3)), new Property("1 Easy Street")); Account.payment(new ActivityAdapter(new Purchase(6)), new Property("5 Main Street")); } } class ActivityAdapter implements Transaction { Activity activity; public ActivityAdapter(Activity activity) { this.activity = activity; } public Property transaction(Object input) { return activity.transact((Property)input); } public String toString() { return activity.getName(); } } /* Output Sale acc is credited Property 0 at 1 Easy Street Purchase acc is debited Property 1 at 5 Main Street *// The result has a more intuitive feel to it. Notice how the ActivityAdapter class takes anActivity object in the constructor and produces an object that has the Transaction interface as a part of it. This is the a classic example of the Adapter design pattern without which it would not be possible for Activity andAccount classes to work together. Adapter makes it possible for classes with incompatible interfaces to work together 

Multiple Inheritance

When you work with classes, you are limited to inheriting from only one base class. Interfaces relax this constraint somewhat by allowing you undertake a kind of multiple inheritance by combining multiple interfaces within a class. To do this, you simply place interface names in sequence following the implementskeyword separated by commas:- package kingsley.java interface Forward { void drive(); } interface Stop { void park(); } interface Speed { void turbo(); } class GearBox { public void move() { } } class Automatic extends GearBox implements Forward, Stop, Speed { public void drive() { System.out.println("drive()"); } public void park() { System.out.println("park()");} public void turbo() { System.out.println("turbo()"); } public void move() { System.out.println("move()"); } } public class Car { public static void cruise(Forward x) { x.drive(); } public static void park(Stop x) { x.park(); } public static void race(Speed x) { x.turbo(); } public static void move(GearBox x) { x.move(); } public static void main(String[] args) { Automatic auto = new Automatic(); cruise(auto); // Interface Forward park(auto); // Interface Stop race(auto); // Interface Speed move(auto); // class GearBox } } /* Output drive() park() turbo() move() *// In the preceding example, note the way by which the Automatic class implements multiple interfaces but inherits from only one class. Java will not allow you to inherit from more than one class, but you may implement as many interfaces as you need. The value in this example is in how an object of the Automatic class can be upcast to multiple types, as demonstrated in the main(), and hence my earlier reference to the concept of multiple inheritance. It is also possible to extend interfaces with inheritance in the same way you do classes by including new fields and methods. Unlike classes though, you can combine several interfaces into a new interface with inheritance. The result is a new interface with much of the same characteristics as those of its base interfaces.package kingsley.java interface SuperHero { void powers(); } interface Alien { void planet(); } interface SuperMan extends Alien, SuperHero { void xRayVision(); } interface Human { void normal(); } interface Monster extends Alien { void killHuman(); } class Skrull implements Monster { void shapeShift() {} public void killHuman() {} public void planet() {} } class ClarkKent implements SuperMan, Human { public void normal() {} public void planet() {} public void xRayVision() {} public void powers() {} } class Hulk implements Human, SuperHero { void thunderClap() {}; public void normal() {} public void powers() {} } public class Earth { static Alien invasion(Monster mt) { return mt; } static SuperMan change(ClarkKent ck) { return ck; } static void battle(SuperHero sh, Monster m) { sh.powers(); m.planet(); m.killHuman(); } public static void main(String[] args) { Skrull ogre = new Skrull(); invasion(ogre); ClarkKent christopherReeve = new ClarkKent(); SuperMan superMan = change(christopherReeve); battle(superMan, ogre); battle(new Hulk(), ogre); } } One may also choose to nest interfaces within classes and other interfaces with very interesting results. package kingsley.java class OuterClass { interface Inner1 { void d(); interface Inner2 { void d1(); } } public class InnerClass1 implements Inner1.Inner2 { public void d1() { } } public interface Inner3 { void d(); } private interface Inner4 { void d(); } private class InnerClass2 implements Inner4 { public void d() {} } public class InnerClass3 implements Inner4 { public void d() {} } public Inner4 getInner4() { return new InnerClass3(); } private Inner4 i4; public void getInner4(Inner4 in4) { i4 = in4; i4.d(); } } interface Outer1 { void x(); interface Outer2 { void d(); } // Invalid identifier. Can only be public // within interface //! private interface Outer3 { } } public class NestingInterfaces { public class Class1 implements OuterClass.Inner1.Inner2 { public void d1() { } } class Class2 implements OuterClass.Inner3 { public void d() {} } // private interface not visible // from outside implementing class //! class Class3 implements OuterClass.Inner4 { //! public void d() { } //! } class Class3 implements Outer1 { public void x() {} class Class4 implements Outer1.Outer2 { public void d() {} } } public static void main(String[] args) { OuterClass oc = new OuterClass(); // Error can't access private interface //! OuterClass.Inner4 = oc.getInner4(); // Error can't access private interface members //! oc.getInner4().d(); // To get to a nested private interface // use another OuterClass OuterClass oc2 = new OuterClass(); oc2.getInner4(oc.getInner4()); } } The example demonstrates some of the features available when working with nested interfaces. As you may observe for instance, it is possible to nest interfaces within interfaces which may have public or package access visibility same as non-nested interfaces do. Calling nested interfaces would then be a simple matter of placing a dot next to the surrounding class or interface, before making a call to the nested interface. Matters get a little complicated however with private interfaces, which provide a way to force the definition of methods without adding the benefit of type. In the main(), accessing private nested interface is not quite so straightforward, as attempts to use a returned reference to the private interface are unsuccessful. This is because in the first instance we are not able to access the private interface directly and secondly we can not access a member of that interface. We however can access the interface by handing the return value to an object that has permission to use it, in this case another OuterClass object. It is important to note that in implementing an interface, one is not required to implement any interfaces nested within and private interfaces can not be implemented outside of their defining classes. 

Factory Methods

Interfaces have the added benefit of allowing you to make multiple implementations using the Factory Method design pattern. The Factory pattern allows you to define an interface for creating an object, but defer instantiation to implementing classes, making it so that your code is completely isolated from the interface implementation. This method is useful when creating a framework to be used by multiple types. Here is an example that uses a ticket factory to create the various types of tickets people might be interested to buy:- package kingsley.java; interface Ticket { String type(); int price(); } interface TicketFactory { Ticket getTicket(); } class AdultTicket implements Ticket { int PRICE = 500; public String type() { return "Adult Ticket"; } public int price() {return PRICE;} } class AdultTicketFactory implements TicketFactory { public Ticket getTicket() { return new AdultTicket(); } } class ChildTicket implements Ticket { int PRICE = 40; public String type() { return "Child Ticket"; } public int price() { return PRICE; } } class ChildTicketFactory implements TicketFactory { public Ticket getTicket() { return new ChildTicket(); } } public class Tickets { public static void buyTicket(TicketFactory tf) { Ticket t = tf.getTicket(); System.out.println("Paid - " + "1 " + t.type() + "
In object oriented programming, polymorphism is a feature that allows you to provide a single interface to varying entities of the same type. This is analogous to the interpretation of the same concept in the field of Biology. To understand how this works in Java, we must consider inheritance and the ways by which the Java programming language makes method calls. When you create a class in Java, you implicitly inherit the fields and methods of the rootObject class even when you do not explicitly inherit from some other class. This ability allows you to substitute an object for its base class and is proof of the saying - "in Java everything is an object". To demonstrate, we consider the simple example of Shape objects:- class Shape { public String toString() { return " a Shape"; } } class Triangle extends Shape { public String toString() { return "a Triangle"; } } public class DrawShape { /** * @param args */ static void draw(Shape s) { System.out.println("Drawing " + s); } public static void main(String[] args) { Triangle t = new Triangle(); draw(t); // TODO Auto-generated method stub } } /* Output Drawing a Triangle *// What is interesting about this example is how in the main(), we pass a Triangle reference to thedraw() method that expects a Shape reference. What is even more interesting is how the compiler accepts this without complaint and Java is able to make the correct method call at run time and without the need for upcasting. This is essentially how polymorphism works. Because the draw() is a dynamically bound method (as are all normal methods in Java), a programmer is able to ignore types and write methods that takes a base class as argument confident in the knowledge that such methods can also be applied to derived classes. Here is a slightly modified version of the example to better elucidate my point:- class Shape { public void draw() { System.out.println("Drawing a Shape"); } } class Triangle extends Shape { public void draw() { System.out.println("Drawing a Triangle"); } } public class DrawShape2 { /** * @param args */ public static void main(String[] args) { Shape s = new Triangle(); s.draw(); // TODO Auto-generated method stub } } /* Output Drawing a Triangle *// In this example, we assign a Triangle object to a Shapereference. A call to the overloaded draw() method produces the correct behaviour, when it might be reasonable to expect that the draw() method in the Shape object might be bound to the call; afterall, we are speaking of a Shape reference. However on closer inspection, the output makes sense because aTriangle object is a kind of Shape, a fact concretised by the use of the extends keyword that denotes the use of inheritance. You might wonder how it is that this is possible? I mean how does Java know what method to call in order to produce the correct behavior at run time? This is essentially what polymorphism is designed to achieve. To get a better understanding of how it works we might consider the concept of binding which refers to the process of connecting a method call to a method body. In programming, early bindingreferences the point when the binding process is performed before the program is run. This is typically done by the compiler and is synonymous with some procedural languages. In the above example, it is clear that the compiler can not know which method to call when it only has a Shape reference from which we have derived at least one other type. To overcome this, Java uses the concept oflate binding or dynamic binding, which allows binding to occur at run time. The term dynamic binding is often used to refer to polymorphism. When we say all method calls in Java happen polymorphically, we may correctly imagine the implementation of some mechanism that allows the correct object type to be determined at run time. The mechanism of this invention however, is not of itself of any interest to us, but the ways by which it might be perceived. 

Polymorphism and constructors.

Constructors in Java are not known to be polymorphic and there is disagreement as to whether they constitute staticmethods or not. Be that as it may, it has been suggested in other well regarded text that constructors are indeed implicitlystatic and we are happy to retain this view in the absence of anything to suggest the contrary. In the previous example, we demonstrated how polymorphism allows us to substitute a simple Triangle object for its base class. In this section we aim to explain how polymorphism effects a more complex type and the order of construction of such objects. The example below gives an idea of what a complex class looks like:- class Books { Books() { System.out.println("Books"); } class Computers { Computers() { System.out.println("Computers"); } } class Address { Address() { System.out.println("Address"); } } class Building extends Address { Building() { System.out.println("Building"); } } public class Library extends Building { /** * @param args */ private Books bs = new Books(); private Computers cp = new Computers(); public Library() { System.out.println("Library"); } public static void main(String[] args) { // TODO Auto-generated method stub new Library(); } } /* Output Address Building Books Computers Library *// The example demonstrates the effect of polymorphism on the order of constructor calls in Java. TheLibrary class is an example of a more complex type reflecting at least two levels of inheritance as well as being composed of a number of other objects. Notice how a call to theLibrary() constructor results in a call to its base classes in a sort of recursive manner as can be evidence by the output. The logic of this is inherent in the fact that for a derived class to be properly constructed, the base classes from which it is derived must first be properly initialised. In other words, an inherited class must know all about its base class or classes and be able to access all of its public and protectedelements. What we are trying to say is when you have a complex class that makes use of composition and inheritance, the order of constructor calls begins by first calling the base class constructor at the root of the hierarchy, followed by other constructors within the hierarchy in a sort of recursive and sequential manner. It is only after this process has been completed that individual members within the class are initialised in the order in which they are written, after which the derived class constructor may then be called. There is sufficient evidence of this in the above output. As mentioned previously, Java applies late binding to all normal method calls. This means that all methods with the exception of constructors are polymorphic by default. It is important to remember that this has an impact when you try to call a dynamically bound method from within a class constructor. In these circumstances, the overridden method may be called before the object is fully constructed making it more likely that you might end up using an unintialised variable, which might result in hard to find bugs in your program. The best way to avoid such a scenario is to do as little as possible within your constructors to get the object into a proper state. However if you must call a dynamically bound method within your constructor, the only safe methods to call are those declared final andprivate which cannot be overridden. When you declare a method final you effectively place a lock on it and prevent inheriting classes from changing its meaning. This is of course a design consideration. By the same token, methods declaredprivate are implicitly final and therefore can not be accessed or overridden by inheriting classes. 

Summary

In this post we have identified the effect of polymorphism on objects of derived classes, how such classes can be substituted for their base classes and as a consequence the order of constructor calls on objects of classes composed by means of composition and inheritance. Polymorphism is an essential construct in any OOP language as it works with essential features like inheritance and encapsulation and provides you with the ability to use the same interface with different forms. Having a proper understanding of how polymorphism works helps improve your code design with several desirable characteristics such as extensibility, readability and better code organisation. contact me @ kaseosime@btinternet.com       
There are mainly two ways by which one may reuse classes in Java. The first is by way of composition. Composition provides a way to compose your classes from objects of existing classes, essentially making use of the objects' functionality as opposed to its form. The second method is by what we call inheritance, which describes how one may derive a new class as a type of an existing class. With inheritance you make use of not only the functionality of an existing class, but more importantly its form. 

Composition

To make use of composition in your class, for non-primitives, you simply create a reference to that object; however for primitives you must define them directly. Here is an example of a class using composition:- class Dog { Dog() { System.out.println( "Dog()" ); } } public class Kennel { private int i; private double d; private String Dog1, Dog2, Dog3, Dog4, Dog5, Dog6; private Dog poddle = new Dog(); public String toString() { return "Dog1 = " + Dog1 + " " + "Dog1 = " + Dog1 + " " + "Dog1 = " + Dog1 + " " + "Dog1 = " + Dog1 + " " + "Dog1 = " + Dog1 + " " + "Dog1 = " + Dog1 + " " + "\n" + "i = " + i + " " + "d = " + d; } public static void main(String[] args) { Kennel kn = new Kennel(); System.out.print(kn); } } /* Output Dog() Dog1 = null Dog1 = null Dog1 = null Dog1 = null Dog1 = null Dog1 = null i = 0 d = 0.0 *// The Kennel class in this example is composed using primitives as well as non-primitives like the Stringand Dog object. Primitives that are fields in a class are automatically initialised to zero as can be gleaned from the output, while object references are initialised to null. As you may observe it is possible to print a null reference without throwing an exception, however an attempt to call a method on an uninitialised variable will induce the relevant compiler error. Further, take note of the special toString() method in the Kennel class which comes as standard in every non-primitive object and is useful in special situations when the compiler wants a string but has only an object. Composition is generally best suited to those situations where you require the functionality of an existing class inside of your new class but not its interface. In other words, composition allows you to embed an object in order to use it to implement features in your new class. To achieve this, you simply embed private objects of an existing class inside your new class. 

Inheritance

Inheritance on the other hand, is a way of taking one class and deriving from it, another class of the same type. The relationship between the two classes can be described as one class being like another or a type of another class. For instance, consider the relationship between a vehicle and a car. We could say, a car is a type of vehicle and our reasoning would make sense to most people. This is essentially how inheritance is designed to work. In Java, all classes you create implicitly inherit from the standard root class Object, from which all objects are ultimately derived. To make use of inheritance, you add the extendskeyword followed by the name of the base class:- class Pet { private String s = "Pet"; public void append(String a) { s += a; } public void cuddle() { append(" cuddle()"); } public void run() { append("run()"); } public void Jump() { append(" jump()"); } public String toString() { return s; } public static void main(String[] args) { Pet p = new Pet(); p.cuddle(); p.run(); p.Jump(); System.out.print(p); } } public class Cat extends Pet { //change a method public void Jump() { append(" Pet.jump()"); super.Jump(); } //add new members to interface public void purr() { append(" purr()"); } public static void main(String[] args) { Cat c = new Cat(); c.cuddle(); c.run(); c.Jump(); c.purr(); System.out.println(c); System.out.println("Test base class:"); Pet.main(args); } } /* Output Pet cuddle() run() Pet.jump() jump() purr() Test base class: Pet cuddle() run() jump() *// In the above example, the Cat class extends or otherwise inherits the members of the Pet class and adds new members as you can see with the purr() method. It is also possible to observe within this example, how both classes include amain() method which is a way to allow for the easy testing of your classes. It is possible to include a main() method in every one of the classes in your program without breaking any rule. In such situations only the main() for the class invoked from the command line will be called though in this case, the Pet.main() method is invoked from the main() of the Cat class. Inheritance is clearly demonstrated in this example because the Cat class, by making use of theextends keyword, ensures Cat objects automatically get all the methods defined in the Pet class - even if not explicitly defined - which to all intents is considered to be its base class. This explains why the Cat class is able to casually make a call to the append() method of its base class from within the jump() and purr() methods The example also demonstrates how to modify a method already defined in the base class, within the derived class as is demonstrated by the jump() method. The superkeyword is used to call the base class version of the jump()method from within the same method in the Cat class. Further, it should be noted how all methods within the Petclass are declared as public access. This is important because the Pet class defaults to package access as is expected of any class for which you do not specify any access specifier and failure to make the methods public might make them inaccessible to inheriting classes from other packages. 

Base class initialisation

On the subject of inheritance, it is worth noting that when you create an object of a derived class, it automatically contains a sub-object of the base class within it. This is possible because Java automatically inserts a call to the base class constructor from within the derived class constructor. Here is an example that demonstrates my meaning:- class Hat { Hat() { System.out.println("Hat constructor"); } } class Fedora extends Hat { Fedora() { System.out.println("Fedora constructor"); } } public class Stetson extends Fedora { Stetson() { System.out.println("Stetson constructor"); } public static void main(String[] args) { Stetson st = new Stetson(); } } /* Output Hat constructor Fedora constructor Stetson constructor *// The preceding example demonstrates how, when you use inheritance, the base class is always initialised before the derived class constructors are able to access it. In other words construction happens inside-out from the base class. This is how Java ensures the base-class subobject is initialised correctly and avoids many of the problems experienced in other programming languages. Note also that this example uses the default no args constructor. If however, your base class included only constructors with arguments, you would be forced in those circumstances to make an explicit call to the base class constructor using the super keyword. In addition, the call to the base class would have to be the first thing you do in the derived class constructor. 

Upcasting

Upcasting is a term that refers to the direction of movement from a derived type to a base type up the inheritance chain. It is based on the way class inheritance diagrams have traditionally been drawn i.e. with the root or base class at the top of the page, and extending downward. Upcasting is very relevant to inheritance, the most important aspect of which is the relationship expressed between the new class and the base class, which can be summarised by saying "the new class is a type of this existing class".It is normally considered a safe operation because you are going from a more specific type to a more general type with very little chance of compromising your data. The derived class is said to be a superset of the base class and consequently might contain more methods than the base class, but it must contain at least the methods in the base class. Consider the following example:-class Instrument { public void play() {} static void tune(Instrument i) { i.play; } } public class Piano extends Instrument { public static void main(String[] args) { Piano grandPiano = new Piano(); Instrument.tune(grandpiano); //upcasting } } The interesting thing about this example is that thetune() method, which accepts an Instrument object reference is passed a Piano object reference in themain(). How is this possible? You might well observe that an object of the Piano class is also a type ofInstrument by virtue of the fact that it inherits all the methods of the Instrument class, and therefore has access to the tune() method of its base class. The act of converting aPiano object into an Instrument reference is what we refer to as upcasting. Understanding when you might need to upcast in your code allows you to make an informed decision about whether to use composition or inheritance when designing your classes. If you will ever need to upcast in your program, then inheritance is probably necessary, but if not, you should consider carefully whether you need inheritance as it is only really useful when there is a clear need for it. Finally, it should be well understood that inheritance has some implication for how Java loads and initialises your classes particularly when dealing with statics; 

Combining composition and inheritance

More often, one may combine both composition and inheritance to derive a more complex type. The following example demonstrates the use of both methods:- class Beverage { Beverage(int i) { System.out.println("Beverage constructor"); } } class OrangeJuice extends Beverage { OrangeJuice(int i) { super(i); System.out.println("OrangeJuice constructor"); } } class Beer extends Beverage { Beer(int i) { super(i); System.out.println("Beer constructor"); } } class Food { Food(int i) { System.out.println("Food constructor"); } } class Potatoes extends Food { Potatoes(int i) { super(i); System.out.println("Potato constructor"); } } class Chicken extends Food { Chicken(int i) { super(i); System.out.println("Chicken constructor"); } } class Dessert { Dessert(int i) { System.out.println("Dessert constructor"); } } class Cake extends Dessert { Cake(int i) { super(i); System.out.println("Cake constructor"); } } class Dinner { Dinner(int i) { System.out.println("Dinner constructor"); } } public class Meal extends Dinner { private OrangeJuice oj; private Beer br; private Potatoes pt; private Chicken chk; private Cake ck; public Meal(int i) { super(i + 1); oj = new OrangeJuice(i + 1); br = new Beer(i + 2); pt = new Potatoes(i + 10); chk = new Chicken(i + 1); ck = new Cake(i + 1); } public static void main(String[] args) { Meal ml = new Meal(1); } } /* Output Dinner constructor Beverage constructor OrangeJuice constructor Beverage constructor Beer constructor Food constructor Potato constructor Food constructor Chicken constructor Dessert constructor Cake constructor *//The Meal class is constructed using both composition and inheritance and the example further demonstrates the importance of calling the base class constructor as the first thing you do in the derived class constructor using the super keyword. This is particularly necessary when you are working with constructors that accept any number of arguments. 

Summary

In this post, we have discussed the important subject of code reuse in Java as a mechanism by which one may quickly and easily add functionality to the classes one creates. We have also distinguished between two main ways by which this possible - composition and inheritance. Finally, we looked briefly at the manifestation of the inheritance mechanism in Java and its effects within constructor initialisation, upcasting and in the loading and initialisation of objects. contact me @ kaseosime@btinternet.com       
A key consideration for the library designer in the normal conduct of operations is maintaining the ability to make changes or improvements to the library at any time without requiring the consumers (client programmers) of that library to do the same. In Java, a library consists of a logical grouping of .classfiles packaged together to make a working program. An apt analogy to this point may be to imagine the considerable inconvenience you might suffer, if, as a result of an update to the Java SE library, you were compelled to make wholesale changes to your existing classes that worked well with a previous version. As a consumer, you rely on the parts of a library on which your code depends staying the same, and a situation where this ceased to be the case would be very problematic to say the least. As a matter of custom, an 'unwritten' agreement exists whereby the library designer agrees not to alter or remove existing methods on which your code depends, when modifying some part of a library, since that would break the client programmers code, and make a mockery of years of trusted convention. To do this, the library designer must figure out a way to separate the parts that change in his code from the parts that do not. More precisely, the designer must look to the concept of implementation hiding. Implementation hiding in Java is closely aligned to the need for access control by providing a way to allow the library designer to say what is available to the client programmer (i.e. the parts that do not change) and what is not (i.e. the parts that do change) by putting boundaries within a data type that help separate the interface from the implementation. This interface/implementation distinction is an important point to understand as even though an interface is, by convention, accessible to the client programmer, the implementation which is a part of the structure of the library is hidden or not accessible to the user. In this way, the designer can make changes to the internal mechanism, which we now understand to be quite apart from the interface, without affecting or requiring the client programmer to make any changes in the way he(or she) uses such library. Java provides access specifiers that enable the library creator to say what is available to the client programmer and what is not by controlling access to data types and the members of which they are comprised. These access specifiers consist of the keywords public, protected andprivate, each reflecting a different level of access from 'most access' to 'least access'. There is also the defaultpackage access which occurs when a programmer fails to specify any of the above access specifiers. In subsequent sections, I discuss these specifiers in more detail, however we would do better to begin with a discussion as to how components in Java are bundled together into a coherent library unit. 

package: Library unit

In Java, a package consists of a grouping of classes organised under a single namespace. We may perceive a package as a mechanism by which one may mitigate the risk that those classes one writes for the web do not collide with that of some other programmer simply because they may have the same class name. The logic for this arrangement may be linked to the uniform interface constraint, a key constraint within REST that applies the principle of generality to component interfaces. In Java, a class file has a .class extension and is normally a product of your source code file. You see, when you write Java programs, you create source code files that comprise a compilation unit, usually with a .java extension. Each compilation unit must have only one public class with the same name as the file (without the.java extension) within which it exists. The Java compiler is responsible for producing output files with the .classextension, from a group of these source code files with the.java extension. These output files are what comprise the library. The package keyword in Java is the mechanism by which you may package all your source files into a single namespace and ultimately reduce the risk of collisions. A package in Java would normally contain many .class files and thepackage keyword is one way Java is able to reference them. Understanding the semantics behind this mechanism is important if you intend to program effectively in Java. Thepackage keyword must appear as the first non-comment line in your Java class file; and following the keyword should be the name of a directory on your system within which your files must reside and which must be searchable beginning from theCLASSPATH. By so doing, Java takes advantage of the hierarchical file structure of your operating system by allowing you to implicitly specify a directory structure when you assign a package, a name. For instance, suppose I wanted to create a package for my source code file MySourceCode.java in thekingsley.java directory, I would do something like this:-package kingsley.java; public class MySourceCode { ... } The above example says the file MySourceCode.javais located within the package kingsley.java. The Java compiler is responsible for producing the associatedMySourceCode.class file, normally in a separate directory from the source file. Certain semantics allow for the concatenation of a string that describe the location of .class file directories relative to the root by which the Java interpreter may be able to find and load these files. The importkeyword allows you to specify or import a package to use within your own program. For instance, if you wanted to use myMySourceCode.java file in your own program, you would do something like this:- package user.java; import kingsley.java.MySourceCode; import java.util.*; public class MyUserFile { ... } With the import statement, the MySourceCode.java file becomes available to your program. If there were, for instance more than one file in thekingsley.java package you were interested to use, instead of importing each file individually, you would use the wildcard character (*). Take the second import statement for example which is used to import all the files java.utilpackage. It is still possible in some rare instances where you may import two libraries that contain the same class name making a collision inevitable when you try to create a reference to an object. In these circumstances you will be required to specify the full class name including the package within which it resides. For instance, lets us suppose we have our own Random class in the kingsley.java package and then we also import thejava.util library which also contains a Random class like so:- import kingsley.java.*; import java.util.*;A collision would definitely occur if we tried to make aRandom object reference like so:- Random rand = new Random();//! Error, Which Random
You would most likely receive a compiler error forcing you to be explicit. You can avoid this by specifying the full class name like this:- java.util.Random rand = new java.util.Random();
This gives the compiler the exact location of your intendedRandom class and ensures you avoid compiler errors. 

Access Specifiers

Access specifiers in Java include the keywords public,private and protected which are placed on the same line and immediately preceding each definition of the members of your class. Each specifier provides controlled access only to that particular member definition. If you do not specify any access control for a particular class, it automatically defaults to what we call package access. 

Package access

Package access is the default access when you fail to specify any access control option, which means that class will become accessible only to those classes within the same package but will appear as private to other classes outside of the package. We can think of package access as a way to group related files together granting mutual access and interaction to classes within the same package while restricting access to others. There are four ways in Java to grant access to members within a particular class:- i. You might include the public keyword to make a class member accessible to everyone, everywhere. ii. Not specify any access control thereby defaulting to package access. iii. Include the protected keyword which allows an inherited class to access the member. iv. Provide accessor/mutator methods (get/set) that read and change members' value. 

public: interface access

The public keyword allows you to grant access to any member of your class to everyone, particularly those client programmers who rely on these portions of your code staying the same; examine the following class:- package kingsley.java; public class Switch { public Switch() { System.out.println("Switch constructor"); } public void on() { System.out.println("Switch on"); } void off() { System.out.println("Switch off"); } }Now suppose you created another class outside of thiskingsley.java package, you would be required to import theSwitch.java class in order to access any of its members like so:- import kingsley.java.Switch; public class Light { public static void main(String[] args) { Switch sw = new Switch(); sw.on(); sw.off(); //Error, can't access } } /* Output Switch constructor Switch on *// You might glean from the output that the Light class is able to access the constructor member of the Switch class, as well as the on()method. This is because both methods have been declaredpublic. The off() method on the other hand, is inaccessible to the Light class because it has no access specifier, it defaults to package access. Note that when you declare a member public, anyone can access it. Tip: To run the example, comment out the off() method 

private: hidden access

When you specify the private keyword in relation to a member of a class, you make that member inaccessible to anyone else, and the consumers of your library are restricted from using it. This is in effect a way of hiding implementation of the 'parts that change' in your program to give you, as the library creator, the ability to modify it without impacting on your consumers code. Further, private members of a class are only available to methods within the same class. Consider the following example:-package kingsley.java; class Egg { private Egg() { System.out.println("Egg constructor"); } static Egg makeEgg() { System.out.println("in makeEgg()"); return new Egg(); } } public class Breakfast () { public static void main(String[] args) { Egg egg1 = new Egg(); //! Error can not Make new Eggs Egg egg2 = Egg.makeEgg(); } } /* Output in makeEgg() Egg constructor *// In this example, both classes are actually in the same package and it demonstrates how to use the privatekeyword to control how an object is created by preventing a user from directly accessing the class constructor. In this instance, the user is prevented from directly creating anEgg object by applying the private keyword to the Egg constructor. In the main() of theBreakfast class, any attempt to create an Egg object directly is certain to induce a compiler error, however in this instance, we are forced to use the staticmakeEgg() method, a member of the same class to create anEgg object. In this way, a client programmer may use themakeEgg() method to construct a new Egg object even as the class designer is free to change the way this object is constructed without having to worry about affecting the consumers code. 

protected: inherited access

The protected access control specifier is relevant to the concept of inheritance in Java. Inheritance refers to the mechanism by which a derived class may inherit the members of it's base class. It is a fundamental concept in OOP that says take this existing class (base class) and add new members to a new class without interfering with the existing class in any way. Derived classes are subclasses of a base class and provide a simple way to extend the functionality of data types in Java. To cause your class to inherit the members of another class, you use theextends keyword like so:- class Light extends Switch { ... }
The protected keyword allows a class designer to grant access to derived classes but not to everyone in general. It is a kind of midway point between the private andpublic access control specifiers. In the previous example, the Light class was unable to access the off() member in the Switch class which defaulted to package access. We could modify our Light class by inheriting from the Switch class and adding a constructor and a couple of public methods to elucidate further;- package kingsley.java; public class Switch { public Switch() { System.out.println("Switch constructor"); } public void on() { System.out.println("Switch on"); } void off() { System.out.println("Switch off"); } } package kingsley.java.com; import kingsley.java.*; public class Light extends Switch { public Light() { System.out.println( "Light constructor" ); } public void lightOn() { on(); } public void lightOff() { off();//!Error can not access } public static void main(String[] args) { Light ls = new Light(); ls.lightOn(); ls.lightOff(); } } /*Output Switch constructor Light constructor Switch on **// The interesting thing to note in this example is you would expect the Lightclass being a derived class of Switch class to inherit all its members including the off() method. But this is not so in this case because the Light class exists in a different package to the Switch class and the lack of an access control specifier ensures the off() member remains inaccessible. To get around this, we could add theprotected keyword to our off() member in the following manner:- package kingsley.java; public class Switch { public Switch() { System.out.println("Switch constructor"); } public void on() { System.out.println("Switch on"); } protected void off() { System.out.println("Switch off"); } } package kingsley.java.com; import kingsley.java.*; public class Light extends Switch { public Light() { System.out.println( "Light constructor" ); } public void lightOn() { on(); } public void lightOff() { off(); //protected method } public static void main(String[] args) { Light ls = new Light(); ls.lightOn(); ls.lightOff(); } } /*Output Switch constructor Light constructor Switch on Switch off **// The protected keyword makes the off() member accessible to any class inheriting from the Switch class, even to those that exist in a different package. 

class access

It is also possible to use access specifiers to determine which classes are available within a library to a user of that library. To make classes available to a consumer of a library, just specify the public keyword on the entire class definition like so:- public class Shape { ... }
However, if on the other hand you were inclined to deter the client programmer from becoming reliant on that class, so that you could re-engineer it at some later time, you would make it inaccessible or hidden from the consumer by leaving out the publickeyword in which case the class defaults to package access, making it like so:- class Shape { ... }
You should be aware that in this scenario, it will make sense to make fields of the class private - which is always good practice, even for your classes that are public. It is also considered within reason to give methods the same access as your class, which in this case is package access. Note that it is not possible for a class to be private or protected. If you must restrict anyone from having access to your class, the best way would be to make all constructors private, thereby preventing anyone but yourself from making access from within a static member of the same class. 

Summary

In this discussion, we have identified the convention that exists between the library designer and the client programmer. This 'unwritten' agreement provides rules that guide custom to ensure a certain amount of universality in the operation of software. We have also briefly discussed some of the mechanisms and components for access control that exist within the Java programming language at reasonably higher level of abstraction to simplify understanding. There are two primary motivations for controlling access to class members. The first motivation is to be able to separate the publicly accessible interfaces from the internal workings of the program. The public interfaces are only relevant to the client programmer and by restricting some members, you are actually making it easier for consumers to use your library. The second reason is to allow the library designer the flexibility to change the internal workings of the program without having to worry about affecting the consumers code. contact me @ kaseosime@btinternet.com       
Java uses conditional statements to determine the execution path. Conditional statements provide a way to determine the truth or falsehood of a conditional expression, by which we mean to describe expressions that make use of relational operators and such, and that are able to produce a boolean value.  These include the if-else statement, which is a control statement most commonly used to control the flow of execution, also the while, do-while, andfor statements, which are mainly used to control iteration and loops, the return, breakand continue statements, which allow us to perform unconditional branching and finally the switchstatement, which, prior to Java SE 7 worked mainly with integral values and provides a way for multiway selection. 

if-else statement

The if-else statement provides a way to control the flow or sequence of statements by allowing you to test for certain conditions within the conventions of a booleanexpression. It is a way of saying if x == y then doz. Note the use of the relational equivalence operator which works with primitives as well as objects, though in the latter case it actually compares object references as opposed to the content of the object themselves. Here is an example of the use of anif-else statement that imitates a simple traffic control system:- public class TrafficLights { public static void main(String[] args) { boolean condition = false; if(condition) { System.out.println("Walk") } else { System.out.println("Don't walk") } } } /* Output Don't Walk *// In the main(), the if statement is used to evaluate theboolean-expression, in this case, if theboolean variable condition happens to betrue or false. If conditionevaluates to true, it prints "Walk" to system console, otherwise, if it is false it prints "Don't walk". The placement of curly braces should be well noted, as a common error is when a programmer gets confused as to how to properly situate curly braces particularly when there is a subsequent else statement. Curly braces are optional, without an else statement, otherwise anif statement should be properly enclosed within an open { and close } curly brace before any subsequentelse statement. We can extend the if-elsestatement in a manner that allows us to provide for several execution paths like so:- import java.util.Random; public class ThrowDice { public static void main(String[] args) { Random rand = new Random(8); for (int i = 1; i < 6; i++) { int spin = rand.nextInt(7); if(spin == 1) { System.out.println(spin + ": Loser.. Low number"); } else if(spin == 6) { System.out.println(spin + ": Winner! High number"); } else if (spin > 1 && spin < 6){ System.out.println(spin + ": Try again.."); } else { System.out.println(spin + ": Not allowed" ); } } } } /* Output 1: Loser.. low number 2: Try again.. 4: Try again.. 0: Not allowed 6: Winner! High number *// Here is a class that uses a random object to imitate a dice throwing game. A random number generator is set with a long seed, which is just a way of giving it an initial value to keep our results consistent. The random object rand uses the nextInt() method to return a pseudorandom value between and including 0 and, but excluding 7. What this means is the value of our spin variable may be anything from 0 to 6, which does not strictly conform to the six sides of a standard die. Note how we extend the use of theif-else statement to deal with a number of possible scenarios, depending on the number generated. An additionalif is added to the else to test for the high and low numbers and everything else in-between. Also note the final else statement which acts as a default and deals the number 0. You may also wish to note the use of conditional and logical operators to test for values between 1 and 6, in this instance printing "Try again.." to the screen if spinis greater than 1 but less than 6. Further, we place ourif-else statement in a for loop that allows us to have 6 throws of the dice. 

Iteration and looping

Iteration or looping is a way to allow certain code in your program be repeated multiple times. This is usually achieved by means of a sequence of quantities returned from a test condition. These quantities act in a way to determine the number of iterations required in your loop. Java uses the keywords while,do-while and for, to implement iteration statements. 

while loop

The while loop evaluates an expression once, at the beginning of every iteration. It is of the form:-while(Boolean-expression) statement Thewhile statement continues until theboolean-expression evaluates to false. Here is a demonstration that prints a sequence of numbers to screen as long as the condition count < 10 evaluates totrue. import java.util.Random; public class Counter { public static void main(String[] args) { Random rand = new Random(8); int count = rand.nextInt(10); while(count < 10) { System.out.println("count is " + count); count++; } } } /* Output count is 4 count is 5 count is 6 count is 7 count is 8 count is 9 //* The reader will note how it is necessary to manually increment the count variable within the whileblock, otherwise the test condition will never evaluate tofalse and then you might get into what we call an infinite loop. 

do-while loop

The do-while loop works slightly differently from thewhile loop because it always executes the statement at least once, even if the test condition evaluates thefalse the first time. This is so, because thedo-while evaluates the expression after the statement, like so:- do statement while(Boolean-expression); We could modify our Counter class to implement ado-while loop like this:- import java.util.Random; public class Counter { public static void main(String[] args) { Random rand = new Random(8); int count = rand.nextInt(10); do { System.out.println("count = " + count); count++; } while(count < 10); } } /* Output count is 4 count is 5 count is 6 count is 7 count is 8 count is 9 //* 

for loop

The for loop is one most commonly used for iteration and whose logic is divided into three distinct segments, each terminated by a semi-colon, that speak to the initialisation of a variable, a termination condition, and then a step - that is the actual incrementing of the variable proper after each iteration. It is of the form:- for(initialisation; termination-condition; step) statement Here is an example using our Counterclass:- import java.util.Random; public class Counter { public static void main(String[] args) { Random rand = new Random(8); for(int count = rand.nextInt(10); count < 10; count++) { System.out.println("count is " + count); } } } /* Output count is 4 count is 5 count is 6 count is 7 count is 8 count is 9 //* As you will observe, incrementation is performed automatically, in a manner of speaking, at the end of every iteration so there is little need to manually increment thecount variable within the loop as in the whileand do-while loops. With the for loop, You can define multiple variables separated by a comma operator like this:- import java.util.Random; public class Counter { public static void main(String[] args) { Random rand = new Random(8); for(int count = rand.nextInt(10), i = count * 2; count <  10; count++, i = i - count ) { System.out.println("count = " + count + ", i is " + i); } } } /* Output count is 4, i is 8 count is 5, i is 3 count is 6, i is -3 count is 7, i is -10 count is 8, i is -18 count is 9, i is -27 *// In the above example, we initialise two int variables count andi, separated by the comma operator. At each step,count is incremented by 1 while the i variable is divided by the current value of the count variable. 

foreach syntax

Another variation of the for loop exists specifically for use with arrays and containers. Sometimes called theforeach syntax it allows you to count through a sequence of items in a container and looks like this:- for(type variable : arrayVariable)
Here is an example of a class using the foreach syntax:- import java.util.Random; public class ForEach { public static void main(String[] args) { Random rand = new Random(8); int[] count = new int[5]; for(int i = 0; i < 5; i++) { count[i] = rand.nextInt(); } for(int x : count) System.out.println(x); } } /* Output count is 4 count is 6 count is 0 count is 1 count is 2 *// In this example, thefor loop is first used to populate an array [ ]of int. The foreach syntax iterates through the array and assigns each element within to a variable x also of type int; in other words the variable x, holds the current element in the array. The foreach syntax is ideally suited to any method that returns an array. 

Unconditional branching

Unconditional branching statements allow us to break from the current iteration in a loop or exit from some method without any test conditions. Java uses the keywords return,break and continue are used to achieve this effect. 

return statement

The return statement is used to specify the return value of a method i.e. one that is not declared void, as well as causing the program to exit from that method with or without a return value:- static int Counter() { return ++count; } The return statement causes the method to exit and returns control to the point where the method was invoked. A method declared as void has an implicit return so adding a return statement would be superfluous but not necessarily illegal. 

break statement

The break statement is used to break out of a loop without executing the rest of the statements; It can be used with either of the for, do,do-while or switch statements. To terminate a loop, you simply place the break keyword at the point where you wish for this to happen:- import java.util.Random; public class BreakLoop { public static void main(String[] args) { Random rand = new Random(6); for(int i = 0; i < 6; i++) { int x = rand.nextInt(6); if(x == i) { System.out.println("x == i " + "x is " + x + ", i is " + i + ", breaking out of loop!"); break; } System.out.println("x != i: " + "x is " + x + ", i is " + i); } } } /* Output x != i: x is 1, i is 0 x != i: x is 0, i is 1 x == i: x is 2, i is 2, breaking out of loop! *// The break statement can also be used in the while and do-while loops, but in this example, it is used to break out of the for loop if x == i, otherwise, it carries on until termination condition. In a situation where we might have nested loops i.e. loops within loops, the break statement will terminate the inner most loop returning control to the outermost loop. To terminate the outermost loop from within an inner loop, we may use a labelled break statement like so:- public class LabelledBreak { public static void main(String[] args) { outer: for(int i=0; i < 10; i++) { for(int x=i * 10; x < 100; x++) { if (x % 9 == 0) break outer; System.out.print(x + " "); } } } } /* Output 10 11 12 13 14 15 16 17 *// The labelouter is an identifier used to mark the start of the outermost for loop, which signals the point where thebreak statement must terminate. This is to say control is returned to statement immediately following the labelled statement. From the example, it is clear that x never gets 100 as the break statement terminates the loop when there is no remainder from the modulus operator. Note the use of the print statement which prints horizontally across the screen as opposed to the println statement which prints vertically. 

continue statement

The continue statement causes control to return to the beginning of the next iteration of the innermost loop, without completing the current iteration. Unlike the breakstatement it does not break out of the loop completely.public class ContinueStatement { public static void main(String[] args) { for(int i = 0; i < 100; i++) { if(i % 10 != 0) continue; //Top of the loop System.out.println(i + " "); } } } /* Output 10 20 30 40 50 60 70 80 90 *// Thecontinue statement in this example, is used to exit the current iteration if the condition i % 10 is not equal to 0, and only prints when the value of the expression evaluates to 0. 

switch statement

The switch statement is a kind of selection statement that allows you to select from a number of possible execution paths. The switch statement works with integral values like int, char primitive types, as well as enumerated types, the String class and certain other wrapper classes. The following code uses a switchstatement to print the value of i to screen:- public class SwitchStatement { public static void main(String[] args) { for(int i = 0; i < 6; i++) { switch(i) { case 1: System.out.println("i is " + i); break; case 2: System.out.println("i is " + i); break; case 3: System.out.println("i is " + i); break; case 4: System.out.println("i is " + i); break; case 5: System.out.println("i is " + i); break; default: System.out.println("i is " + i); } } } } /* Output i is 0 i is 1 i is 2 i is 3 i is 4 i is 5 *// You may observe the body of aswitch statement is enclosed between curly braces that comprise the switch block. Following the switch, One may have multiple case labels whereby a matching case is executed based on the evaluation of the test expression. The preceding example compares the value of i with each case label and prints the appropriate value to screen, so for instance, if i == 1, the statements in case 1 are executed. Note that each case ends with a break clause, which causes execution to jump to the end of the switch block. Also note the last statement which is the default statement, handles all scenarios not explicitly provided for in any of the case labels and does not require a break sytatement, even though it would comprise no ill-effect were you to choose to include one; in this case, the default statements prints 0 to screen. It is also possible to stack case labels in a way that provides multiple matches for a particular piece of code. Run the following example to see the result:- public class SwitchStatement2 { public static void main(String[] args) { for(int i = 0; i < 10; i++) { switch(i) { case 1: case 3: case 5: case 7: case 9: System.out.println("odd number " + i); break; default: System.out.println("even number " + i); } } } } It is essential to put a break statement at the end of a particular case otherwise control will simply drop through and continue processing until a break is encountered. In the above example, the cases are stacked on top of the other wheni is an odd number, otherwise the default statement is used to print out even numbers. 

Summary

We have fully explored the basics of controlling the flow of execution in your Java program. We should by now be well acquainted with how to use the if-else statements to control flow, the switch statement for multiway selection, implementing loops like for, while and the do-while, terminating loops using thebreak statement, breaking out of the current iteration with the continue statement and how to use thereturn statement to return required values in methods that specify a return type. contact me @ kaseosime@btinternet.com       
The proper initialisation of objects is a concern that has primarily to do with safety in programming. In some programming languages, failing to properly initialise a variable or library component before attempting to use it can lead to very many bugs in your software that may be difficult to locate, however we are fortunate that Java takes a sensible approach to these matters. Java provides guaranteed initialisation of objects with the use of a constructor, which is sometimes described as an implicitly static method that a class designer may provide to guarantee the initialisation of every object created. When a constructor exists for a class, Java automatically calls that constructor when an object of that class is created, before it can be used, thus guaranteeing initialisation. Initialisation is an important technique the programmer must take care to master because it is the point at which storage is created for objects that makes them ready for use. 

Class constructors

A constructor in Java, usually has the same name as the class, and can take any number of arguments as would an ordinary method. A default constructor is one that takes no arguments, and if provided is called automatically to initialise the object before it can be used; Consider the following example:- package kingsley.java class Table { public Table() { System.out.print("Table "); } } public class CreateTables { public static void main(String[] args) { for(int i = 0; i < 5; i++) new Table(); } } /* Output Table Table Table Table Table *// As you can see, constructor names do not exactly follow the normal naming convention of making the first letter of all method names lowercase, because the constructor name must match the class exactly. In the above example, the default constructor Table(), prints "Table" to screen when we create a Table object using thenew keyword. If you create a class with no constructors, Java automatically creates a default constructor for you, however if you define any constructors for a class, with or without arguments, and attempt to call a constructor that you have not defined, the compiler will not synthesize one for you, more likely, that it might complain about not finding a match for the method you have called. Constructors can, like regular methods, also accept any number of arguments; for instance, we can modify our Table constructor to accept some argument like so:- package kingsley.java; class Table { int i; public Table(int i) { this.i = i; System.out.print("Table" + i + " "); } } public class Carpenter { static void makeTable(int i) { new Table(i); } public static void main(String[] args) { for(int i = 0; i < 5; i++) Carpenter.makeTable(i); } } /* Output Table0 Table1 Table2 Table3 Table4 *// Constructor arguments allow you to provide parameters for the initialisation of an object. The above example takes an int argument and provides a way for you to distinguish between Table objects. It is possible for a class to have more than one constructor in circumstances where you may want to create an object in more than one way. Method overloading is a technique that allows the same method name to be used with different argument types, thus you could have a class that looks like this:- package kingsley.java; class Car { int speed; Car() { System.out.print("Car is stopped"); speed = 0; } Car(int speed) { this.speed = speed; System.out.println("Car is travelling at " + speed + " mph" ); } } public class PoliceSpeedoMeterClock { public static void main(String[] args) { for(int i = 1; i < 6; i++) { Car c = new Car(i); } new Car(); } } /* Output Car is travelling at 1 mph Car is travelling at 2 mph Car is travelling at 3 mph Car is travelling at 4 mph Car is travelling at 5 mph Car is stopped *// TheCar class demonstrates the use of overloaded constructors. The first constructor is the default constructor that prints "Car is stopped" to screen. The second overloaded constructor uses an int variable to simulate the speed at which the car is currently travelling. Also note how this is achieved with the use of a for loop in addition to the fact that both constructors have the same name, which is of course the same as that of the class. 

Overloading methods

Method overloading is not limited by any means to just constructors alone, but can be applied to regular methods within a class sameway. Java is able to distinguish between overloaded methods by their list of argument types which must be unique to each overloaded method, and even the ordering of such a list is sufficient for Java to be able to distinguish between two or more overloaded methods. Here is an example of overloaded methods using primitive types:- package kingsley.java; public class Dog { void Bark(char c) { System.out.println("whine whine"); } void Bark(int i, float f) { System.out.println("woof woof"); } void Bark(float f, int i) { System.out.println("ruff ruff"); } void Bark(double d) { System.out.println("howl howl "); } public static void main(String[] args) { Dog d = new Dog(); d.Bark('a'); d.Bark(2, 2.1f); d.Bark(2.1f, 4); d.Bark(3.2); } } /* Output whine whine woof woof ruff ruff howl howl *// TheBark() method is overloaded using primitive types and even though we have not defined any constructors, it is obvious from this example that Java automatically creates a default constructor. Each method prints a different type of dog bark to screen depending on its arguments. Note how the arguments to the second and third overloaded Bark() methods are exactly the same, yet Java is able to distinguish these because the ordering of the arguments in both methods are different. It is worth bearing in mind that when you use primitives with overloaded methods or methods in general, a primitive argument of a smaller type can be automatically promoted to a larger type without too much hassle. However when you have a larger argument than is expected by the method, you will be required to perform a narrowing conversion with a cast to avoid a compiler error:- package kingsley.java; public class Race { void start(int i) { System.out.println("int " + i); } void start(double d) { System.out.println("double " + d); } void end(short s) { System.out.println("short " + s); } public static void main(String[] args) { Race f1 = new Race(); f1.start(new Character('a')); f1.start(new Byte("5")); f1.start(new Short("8")); f1.start(new Float(1.5)); f1.start(new Long(23000000)); char c = 'a'; int x = 10; float f = 1.3f; long l = 23000000L; f1.end((short)c); f1.end((short)x); f1.end((short)f); f1.end((short)l); } } /* Output int 97 int 5 int 8 double 1.5 double 2.3E7 short 97 short 10 short 1 short -3136 *// In this example, the Race class defines an overloadedstart() method and an end() method. We test both methods against a number of primitive types in the main. The overloaded start() method is able to make automatic conversions depending on the given argument; The smaller arguments are promoted to type int while the larger arguments like float and long are converted to double. The end() method on the other hand requires the use of a narrowing conversion from various larger arguments to short primitive type. 

this keyword

The this keyword is a useful mechanism reserved for those occasions when you wish to reference the current object from within a non-static method of another class. In other words, as your programs get larger and more complicated, it can become a daunting task to keep track of objects you create. Thethis keyword allows you to reference the current object for which a method has been called. It is most often used inreturn statements to return a reference to the current object. For instance, here is an example that uses thethis keyword to pass the current Itemobject to the scan() method of theCashier class:- package kingsley.java; class ShoppingCart { Item[] item = new Item[1]; public ShoppingCart add(Item it) { for(int i = 0; i < item.length; i++) this.item[i] = it; System.out.print(" added to cart" + "\n"); return this; } } class Item { String name; Item(String s) { this.name = s; } Item buy() { return Cashier.scan(this); } } public class Cashier { static Item scan(Item it) { System.out.print(it.name + " paid -"); return it; } public static void main(String[] args) { ShoppingCart sc = new ShoppingCart().add(new Item("cofee").buy()); sc.add(new Item("Bread").buy()); } } /* Output cofee paid - added to cart Bread paid - added to cart *// The Item class in this example uses the this keyword to pass the current Item object to the Cashier.scan()method, which can be thought of as a foreign utility method to the class itself. This style of programming is common when you need an external method that can be applied across many different classes. Note how we use a constructor to initialise the Stringdata member - name, of the Item class in a manner that provides us with a way to uniquely identify each item object added to the cart. The this keyword takes on a different meaning however when used with constructors. In those instances, it makes an explicit call to the constructor that matches the argument list. Here is an example:- package osime.java; public class Bird { int birdCount = 30; String s = "Pigeons"; Bird (int number) { this("Pigeons"); birdCount = number; System.out.println("Bird constructor w/ int arg"); } Bird(String s){ System.out.println("Bird constructor w/ String args"); this.s = s; } Bird(String s, int number) { this(number); this.s = s; System.out.println("Bird constructor, w/ String & int args"); } Bird() { this("Swallows", 10); System.out.println("Default constructor, no args"); } void printBirdMembers() { //Error can not use this from non-constructor //!this(10); System.out.println("Bird count = " + birdCount + " s = " + s); } public static void main(String[] args) { Bird b = new Bird(); b.printBirdMembers(); } } /* Output Bird constructor w/ String args Bird constructor w/ int arg Bird constructor, w/ String & int args Default constructor, no args Bird count = 10 s = Swallows *// In this example, we create a Bird class with an overloaded constructor. Notice how the this keyword is used from within each constructor to call another constructor. In the defaultBird() constructor, the call to the overloaded constructor with String & intarguments using the this keyword, makes a call to the overloaded Bird constructor with int argument, which in turn makes a call to the String argument constructor in a kind of series of recursive method call. Also note that when using the this keyword from within constructors, the call to the constructor must be the first thing you do or else you get an error. Further more in theprintBirdCount() method, you can see how it is not possible to make a call to a constructor using thethis keyword from within a non-constructor. It is important to make the connection here between the use of thethis keyword and static methods; essentially, the this keyword can not be applied tostatic methods since static methods are in a sense global methods i.e. they can be called for the class but not for individual objects unlike the this keyword which when used refer specifically to the current object. 

Member Initialisation

Java ensures field variables within a class are initialised to default values before they are used. This guarantee applies equally to primitives as well as objects:- package kingsley.osime; public class DefaultValues { static byte b; static short s; static int i; static long l; static float f; static double d; static boolean bl; static char c; static DefaultValues reference; static void printDefaultValues() { System.out.println("byte = " + b); System.out.println("short = " + s); System.out.println("int = " + i); System.out.println("long = " + l); System.out.println("float = " + f); System.out.println("double = " + d); System.out.println("boolean = " + bl); System.out.println("char = [ " + c + "]"); System.out.println("DefaultValues = " + reference); } public static void main(String[] args) { DefaultValues.printDefaultValues(); } } /* Output byte = 0 short = 0 int = 0 long = 0 float = 0.0 double = 0.0 boolean = false char = [ DefaultValues = null *// Even as we have not initialised these variables, Java is able to automatically initialise them to default values. With non-primitives like theDefaultValues object, Java automatically initialises these to null. It is noteworthy that this guarantee of initialising variables does not apply to local variables, which are variables created within a method. If you were to try to call a method from an uninitialised local variable, you will be certain to receive a compile time error. We could initialise our variables directly by assigning values at the point of creation like so:- public class DefaultValues { byte b = 30; short s = 0xff; int i = 10; long l = 1; float f = 2.1f; double d = 3.14; boolean bl = true; char c = 'a'; } The same method could be used to initialise non-primitive objects; for instance, we could create and initialise a Data object like this:- class Data {} public class System { Data d = new Data(); } A variable can be initialised in any number of ways, including by calling a method that returns some value that is of the same type as the variable; for instance you could say:- public class Init { double d = f(); double f() { return 2.3; } } As you can see thef() method returns a value of type doublewhich is of course the same type as the variable d for which it is called. Such methods may also have arguments, providing those arguments belong to class members that have previously been initialised. When you try to initialise a variable with a method that takes arguments that are yet to be initialised, the compiler complains about forward referencing, which is basically a warning of an uninitialised variable. 

Order of initialisation

Variables within a class get initialised in the order in which they are defined within the class. Variable definitions may be scattered throughout and in between method definitions, but they are always initialised before any methods are called, including even the constructor. At this point it is necessary that we make a distinction between static and non-staticfields as these definitions have implications for when and how defined variables are initialised. The following example demonstrates the proper order of initialisation in Java:-package kingsley.osime; class ClothingItem { ClothingItem(int number) { System.out.println("ClothingItem (" + number + ")"); } void c1(int number) { System.out.println("c1 (" + number + ")"); } } class Suitcase { static ClothingItem cl1 = new ClothingItem(1); Suitcase() { System.out.println("Suitcase ()"); cl2.c1(1); } void s1(int number) { System.out.println("s1 (" + number + ")"); } ClothingItem cl2 = new ClothingItem(2); } public class OrderOfInit { public static void main(String[] args) { System.out.println("Creating new Suitcase in main"); new Suitcase(); System.out.println("Creating new Suitcase in main"); new Suitcase(); suitcase.s1(1); } static Suitcase suitcase = new Suitcase(); static ClothingItem item = new ClothingItem(3); } /* Output ClothingItem (1) ClothingItem (2) Suitcase () c1 (1) ClothingItem (3) Creating new Suitcase in main ClothingItem (2) Suitcase () c1 (1) Creating new Suitcase in main ClothingItem (2) Suitcase () c1 (1) s1 (1) *// The Suitcaseclass contains a static and non-static member of theClothingItem class and along with theOrderOfInit class allows you to observe the proper order of initialisation. As you may observe from the example, thestatic members of the OrderOfInit class are initialised first which in turn causes those classes to be loaded and since the Suitcase class containstatic ClothingItem members (1) and (2) those are first initialised before making a call to theSuitcase constructor and then the staticClothingItem object (3) is also created. All through this, the main() method of theOrderOfInit class is yet to be called. Note thatstatic members are only initialised once, when they are first accessed or when an object of the class is first created, but non-static members are re-initialised everytime they are accessed. From this we can surmise the order of initialisation as statics first, if they are not initialised already, followed by non-static objects before any class constructors are called. When inheritance is involved, the process does get a little bit more complicated. 

Initialising Arrays

Arrays are containers that hold a sequence of objects or primitive types, packaged under an identifier referencing the same type. Arrays may be of any length and are defined using the square-brackets [] indexing operator, for instance, to create an array of type int you would write something like this:- int[] x1;
Here, the variable x1, is declared as an array of type int. It is also possible though unconventional for the square-brackets to be located after the identifier like so:- int x1[];
At this point, all you have is a reference to an array and therefore no space has been allocated to the array object itself. It is often necessary to write an initialisation expression in order to create storage for an array, one way to do this would be to use the new keyword like so:- int[] x1 = new int[20];
Note that using the new keyword with primitives will only work when applied in the context of an array. The above expression creates an array with enough storage for 20 elements and assigns the array to the x1 variable. We could have also used a special kind of initialisation that encloses a set of values within curly braces like so:- int[] x1 = { 2, 4, 6, 8, 10};
Here the x1 array contains the values 2, 4, 6, 8 and 10 all of which comprise its elements. Each element can be referenced by means of an index that begin at 0 up to the number of elements in your array. For instance, in our x1 array, the element at index 0 is 2, element at index number 1 is 4, at index number 2 is 6 and so on. All arrays regardless of type have an intrinsic length member that allow you to query the number of elements defined within the array. Elements start from 0 and the largest element you can index is equal to length - 1. For instance to find out the number of elements contained within the x1 array you would write:- int size = x1.length;
If you were to call a method to print out the value of thesize variable, the number 5 would be returned. Here is an example that uses a for loop to iterate through an array of type while populating it:- package kingsley.java; import java.util.Random; public class InitArray { static int[] x1 = new int[5]; public static void main(String[] args) { Random rand = new Random(10); for(int i = 0; i < x1.length; i++) { x1[i] = rand.nextInt(20); System.out.println("Element at " + i + " is " + x1[i]); } } } /* Output Element at 0 is 13 Element at 1 is 0 Element at 2 is 13 Element at 3 is 10 Element at 4 is 6 *//What we see here is a random object number generator rand, using the nextInt() method, available to all random objects, to populate the x1[] int array, whose current elements are being referenced by the variable quantityi being used to control the loop. Note that thex1[] array was initialised prior to this and is declared as static. If you fail initialise the array variable prior to using it, you will get a compiler error about an uninitialised variable, likewise, failure to declare thex1 object as static, risks producing an error about trying to reference a non-static method from a static one, which if you recall is what themain() method is.