Posts Tagged ‘Java basics’

Java inheritance

February 19, 2014

Inheritance

We will use the simple example most used:

class BaseEmployee {
    String name;
    String address;
    String phoneNumber;
    float yearsExperience;
}

class Manager extends BaseEmployee {
    int teamSize;
    void reportProjectStatus() {}
}

This and Super

this always points to its own instance of itself. Most common example is using this to differentiate instance from local variables:

class Example {

    String value1;             //Instance
    String value2;             //variables

    Example (String value1) {
        this.value1=value1;   //makes clear that the instance variable with the this.
    }


}

class Programmer extends BaseEmployee {
    String[] programmingLanguages;
    void writeCode() {}
}

Here we can see the two different types of employee, Manager and Programmer. Both of these inherit from the BaseEmployee class, and then each of them adds their own methods. These two classes are called subclasses, derived classes, extended classes or child classes, where as BaseEmployee can be referred to Base class, superclass or parent class.

Consider this, a method which accepts a class of BaseEmployee will also accept a subclass of BaseEmployee, meaning you could pass in Manager, for example.

Inheritance allows you to specialise a class by it extending (inheriting) other variables / methods from the parent. This means you are reusing code already defined, rather than re-inventing the wheel.

In the example above, the child class programmer has access to the variables from the parent so you can set the value of name in the child class even though it belongs to the parent class. Oh course there are the access limitations:

Inherited base members:

  • Default access, this means the base and derived class must belong to the same package
  • protected access, this means the derived class can access regardless of package which the base and derived class belong
  • public – well every class can access these
  • Not inherited base members:

  • private access, the derived class does not see these when defined in the base
  • A derived class does not inherit the base class’s constructor – it can call them though
  • Derived classes can also define their own constructor, static methods, variables etc as well as overriding or hiding the base class’s methods / variables etc.

    Abstract base class

    You cannot instantiate abstract classes
    An abstract class does not have to have abstract methods, however an abstract method in a class means it has to be an abstract class
    A derived class extending a abstract base class has to implement all the abstract methods of the base class

    Summarise the rules:

  • A base class / Superclass / Parent class is inherited (extended) by other classes
  • A derived class / subclass / Extended class / child class inherits / extends from a base class
  • Interface

    Interfaces are similar to abstract classes, an interface defines abstract methods (which are all public) and constants.

    Taking the example from before we can apply some interfaces. With the subclasses of Manager and Programmer we can define interfaces which force these classes to implement.

    
    interface Training {
        public void attendTraining();
    }
    
    interface Interview {
        public void conductInterview();
    }
    
    class BaseEmployee {
        String name;
        String address;
        String phoneNumber;
        float yearsExperience;
    }
    
    class Manager extends BaseEmployee implements Interview, Training {
        int teamSize;
        void reportProjectStatus() {}
        public void conductInterview() {                //Have to implement this
               System.out.println("I, manager, am conducting an interview");
        }
        public void attendTraining() {                //Have to implement this
               System.out.println("I, manager, am attending training");
        }
    }
    
    class Programmer extends BaseEmployee implements Training {
        String[] programmingLanguages;
        void writeCode() {}
        public void attendTraining() {                //Have to implement this
               System.out.println("I, programmer, am attending training");
        }
    }
    
    

    NB: the method signatures implemented in the class which is implementing an interface must match. Otherwise this a compile error.

    interface Training {
        public void attendTraining(String[] topics);    //By adding String[] topics, I need to change the implementation
    
    class Manager extends BaseEmployee implements Interview, Training {
        int teamSize;
        void reportProjectStatus() {}
        public void conductInterview() {                //Have to implement this
               System.out.println("I, manager, am conducting an interview");
        }
        public void attendTraining(String[] topics) {                //Have to implement this
               System.out.println("I, manager, am attending training");
        }
    }
    
    class Programmer extends BaseEmployee implements Training {
        String[] programmingLanguages;
        void writeCode() {}
        public void attendTraining(String[] topics) {                //Have to implement this
               System.out.println("I, programmer, am attending training");
        }
    }
    

    A class can only inherit from one class. The reason for this, each class could have the same method but a different meaning, so then which of these methods is inherited?

    
    class Example1 {
         public String greeting() {
             return new Sting("Why hello there");
         }
    }
    
    class Example2 {
         public String greeting() {
             return new Sting("How do");
         }
    }
    
    Class Employee extends Example1, Example2 {
          //Which greeting is called?
    }
    
    

    However, a class can implement many interfaces!

    
    interface ExampleInterface1 {
          String greeting();
    }
    
    interface ExampleInterface2 {
          String greeting();
    }
    
    class Employee implements ExampleInterface1, ExampleInterface2 {
         //Even though we are implementing two interfaces, both define the same method - this is fine as we just need to implement this method
    }
    

    Some rules:

  • A class implements a interface, an interface cannot inherit a class
  • An interface can extend / inherit another interface
  • Abstract class can extend a concrete class, and the other way
  • Abstract class can implement interfaces
  • Abstract class can extend another Abstract class
  • Reference and object types
    class Employee {
    	String name;
    	String address;
    	String phoneNumber;
    	float experience;
    }
    
     interface Training {
     	public void attendTraining();
     }
    
    class Programmer extends Employee implements Training {
    	String[] languages;
    	public void attendTraining() {
    		System.out.println("Programmer attending training");
    	}
    }
    
    class ExampleSpace {
    	public static void main(String[] args) {
    		Programmer p = new Programmer();
    		p.languages = new String[] {"Java", "JavaFX"};
    		
    		System.out.println(p.languages[0]);  //Java
    		
    		p.name = "Test";
    		
    		System.out.println(p.name);  //Test
    		
    		p.attendTraining();
    		
    		//All fine and Dandy, I have created a programmer object and I can access everything.
    		
    		Employee e1 = new Programmer(); //Wait what is this?
    		
    		//e1 is refering to an object of class Programmer, as this extends Employee.
    		
    		/*
    		However, this does not mean it can access everything that Programmer has, e.g.
    		
    			e1.languages = new String[] {"Java", "JavaFX"};
    		
    			System.out.println(e1.languages[0]);
    
    		This will not work as these are specific to the class Programmer. This code will not compile.
    		*/
    
    		//This is fine though, as these belong to the class Employee		
    		e1.name = "Test";
    		
    		System.out.println(e1.name);
    
    		/*
    		Employee does not implement an interface, so this will not work
    		
    			e1.attendTraining();
    		
    		*/
    		
    		//You can also refer to Programmer via the interface!
    		
    		Training t1 = new Programmer();
    		
    		/*
    		Guess what Training cannot do?
    		
    			t1.languages = new String[] {"Java", "JavaFX"};
    		
    			System.out.println(t1.languages[0]);
    			
    			t1.name = "Test";
    		
    			System.out.println(t1.name);
    		
    		It cannot see any of these as it's type is the interface Training. This would not compile.
    		*/
    		
    		//But it can do
    		
    		t1.attendTraining();
    		
    		//All well and good.
    		//Lets just take a look at these:
    		
    		//Programmer p2 = new Employee();  -- this will NOT compile. You cannot refer to a base class using a derived class.
    		//Programmer p3 = new Training(); -- this will NOT compile. You cannot create an object of the type interface.
    	}
    }
    

    You can create an Array of objects, based on a common class, in this case Training which is implemented by Programmer and Manager:

    
    Training[] t1 = new Training[] {
           new Programmer()
           , new Manager()
    };
    
    for (Training tt : t1) {
         tt.attendTraining();
    }
    
    //NB: The base class cannot be added as it does not implement Training, and Training cannot be added.
    
    Casting

    In the example above I place objects of types Programmer and Manager into an array of Training. I can use Casting to reference those objects.

    
    Manager m1 = new Manager();
    m1.teamSize = 5;
    Manager m2 = new Manager();
    m2.teamSize = 15;		
    Training[] t = new Training[] {
    	m1
    	, m2
    	, new Programmer()
    };
    		
    for (Training t1 : t) {
          if (t1 instanceof Manager) {
    	    Manager m = (Manager)t1;  //Casting t1 as a manager as it is of the type manager
    	    if (m.teamSize > 10) {
    		  System.out.println("Why are you on training?");
    		  continue;           //Move on to the next iteration of the loop
    	    }
          }
          t1.attendTraining();
    }
    
    

    This and Super

    this refers to the entity of itself. This is commonly used to distiguish instance variables from method. Example:

    class Example {
         String name;      //Instance
         String address;   //variables
    
         Example(String name) {  
             this.name = name;    //distinguish instance from method variable
         }
    
         Example(String name, String address) {
             this(name);                          //Calls the constructor which only takes name
             this.address = address;              //sets address
         }
    
    }
    

    Another example of using this to call the “default” constructor.

    class Example {
         String name;      //Instance
         String address;   //variables
         String postcode;
    
         Example() {                            	//Constructor which does not take any arguments
              name = "No data";
              address = "No data";
              postcode = "No date";
         }
    
    
         Example(String name, String address, String postcode) {
              this();				//This must be the first line of the method
              if (name != null) this.name = name;
              if (address != null) this.address = address;
              if (postcode != null) this.postcode = postcode;
              
         }
              
    }
    

    this can also be used to access inherited members of a base class in the derived class.

    Super

    This is normally used when a derived class define methods already present in the base class.

    class Employee {
    	String name;
    }
    
    class Programmer extends Employee {
    	String name;
    	
    	void setNames() {
    		this.name = "Programmer";
    		super.name = "Employee";
    	}
    	
    	void printNames() {
    		System.out.println(this.name);
    		SYstem.out.println(super.name);
    	}
    }
    

    You can also refer to constructors with super:

    class Employee {
    	String name;
    	Employee(String name) {
    		this.name = name;
    	}
    }
    
    class Programmer extends Employee {
    	String[] languages;
    	
    	Programmer(String name, String[] languages) {
    		super(name);                    //As with the this example, this call to the constructor must be the first line of code.
    		this.languages = languages;
    	}	
    }
    

    You can’t use this and super in static methods, the code will fail to compile!

    Polymorphism

    It means of many forms, think of a method e.g. talk, which depending on the object it belongs to you get a “different” result, but nevertheless the result is talking.

    abstract class Employee {
    	String name;
    	
    	public void reachOffice() {
    		System.out.println("Reached the office");
    	}
    	
    	public abstract void startProjectWork();  //Here we have defined a method which has to be implemented when employee is extended. Each object will deal with this in thier own way.
    }
    
    class Programmer extends Employee {
    	public void startProjectWork() { //This is also referred to as a overridden method
    		writeCode();
    		writeUnitTests();
    	}
    
    	private void writeCode() {
    		System.out.println("writing code");
    	}
    	
    	private void writeUnitTests() {
    		System.out.println("writing unit tests");
    	}
    }
    
    class Manager extends Employee {
    	public void startProjectWork() { //Have to implement this as I have extended Employee!
    		meetClients();
    		defineProject();
    		assignTeam();
    	}
    	
    	private void meetClients() {
    		System.out.println("Meeting with clients");
    	}
    	
    	private void defineProject() {
    		System.out.println("defining project");
    	}
    	
    	private void assignTeam() {
    		System.out.println("assigning team");
    	}
    }
    
    class PolyMorphism {
    	public static void main(String[] args) {
    		Employee e1 = new Programmer();   //creates object of Programmer and assigns to Employee
    		Employee e2 = new Manager();	//create object of Manager and assigns to Employee
    		
    		e1.reachOffice();  //This is defined in the Employee class
    		e2.reachOffice();
    		
    		e1.startProjectWork();  //Method from the programmer
    		e2.startProjectWork();  //Method from the manager
    	}
    }
    

    Note above, the reference variables of type Employee when the method startProjectWork is called they behave in accordance to the classes defined. startProjectWork is polymorphic in the same way talk is.

    The method in the abstract class means you have to implement it, in doing so you are actually overriding it. This method can be either abstract or not, and the access modifiers can be the same or less.

    NB: This is overridden methods – this is a method with the same name, number and type of arguments. Do not confuse with overloaded methods which accept a different number or type of parameters.

    The difference between variables bound at compile time and runtime:

    class Employee {
    	String name = "employee";
    
    	void printName() {
    		System.out.println(name);
    	}
    }
    
    class Programmer extends Employee {
    	String name = "programmer";
    
    	void printName() {
    		System.out.println(name);
    	}
    }
    
    class BindingExample {
    	public static void main(String[] args) {
    		Employee emp = new Employee();
    		Employee programmer = new Programmer();
    		
    		System.out.println(emp.name);         //prints employee
    		System.out.println(programmer.name);  //prints employee - Because the type of the variable is employee - this is bound at compile time
    		emp.printName();			//prints employee - accesses method within Employee
    		programmer.printName();			//prints programmer - access overridden method in Programmer
    	}
    }
    
    Interfaces

    Lets implement Polymorphism with interfaces, if we stay with the same objects as before (Employee, Programmer, and Manager) we shall implement finishWork().

    
    interface Project {
    	void finishWork();
    }
    
    class Programmer extends Employee implements Project {
    	public void finishWork() {
    		System.out.println("Coding complete");
    		System.out.println("unit tests complete");
    	}
    }
    
    class Manager extends Employee implements Project {
    	public void finishWork() {
    		System.out.println("QA complete");
    		System.out.println("Documentation done");
    	}
    }
    
    class PolyMorphWithInterfaces {
    	public static void main(String[] args) {
    		Project p1 = new Programmer();   //Because programmer and manager implement Project
    		Project p2 = new Manager();	//then the type of the variable can be Project
    		//If you stored these objects as type Employee you would not be able to call this method
    		
    		p1.finishWork() //returns "Coding complete" and "unit tests complete"
    		p2.finishWork() //returns "QA complete" and "Documentation done"
    	}
    }
    

    All fine and Dandy. A little disappointing that you have to define the type as Project, this limits us somewhat. We can address this by having Employee implement Project which, because Programmer and Manager extend Employee, means Employee types can call finishWork().

    interface Project {
    	void finishWork();
    }
    
    class Employee implements Project {
    	public void finishWork() {
    		System.out.println("Employee is done");
    	}
    }
    
    class Programmer extends Employee {
    	public void finishWork() {
    		System.out.println("Coding complete");
    		System.out.println("unit tests complete");
    	}
    }
    
    class Manager extends Employee {
    	public void finishWork() {
    		System.out.println("QA complete");
    		System.out.println("Documentation done");
    	}
    }
    
    class PolyMorphWithInterfaces {
    	public static void main(String[] args) {
    		Employee p1 = new Programmer();   
    		Employee p2 = new Manager();	
    		
    		p1.finishWork() //returns "Coding complete" and "unit tests complete"
    		p2.finishWork() //returns "QA complete" and "Documentation done"
    	}
    }
    

    Nice and clean…

    Remember, Polymorphism is overridden methods, not overloaded.

    reference: http://www.manning.com/gupta/

    Java exceptions code and rules

    February 19, 2014

    try – catch – finally

    
    try {
    
    //This is where you try your code
    
    }
    catch (Exception e) {
    
    //If an exception occurs, it is caught here
    //You can have multiple catch blocks for each different Exception, e.g. ArrayOutOfBoundsException, FileNotFoundException, etc.
    
    }
    finally {
    
    //This is where you tidy up, close files that sort of thing
    //This code ALWAYS executes, regardless if an exception is thrown
    //There is only ever one instance of the finally in a try-catch-finally block
    
    }
    
    

    There are Java Exception, stack overflow, array index out of bounds, etc, but you can also create your own. Exceptions are thrown, hence they are caught when you try the code. You can stack try-catch-finally, e.g. try some code, and then try code within that code.

    public class ExceptionExample {
    	public static void main(String[] args) {
    		int counter = 0;
    		int[] arr = new int[] {1,2,3,4};
    		
    		try {
    			System.out.println(arr[4]);
    			counter = 1;
    		}
    		catch (ArrayIndexOutOfBoundsException ae) {
    			System.out.println("An exception has been caught!");
    		}
    		finally {
    			counter = counter + 10;
    		}
    		
    		System.out.println(counter); //this prints 10 because the exception was thrown, otherwise it would print 11
    	}
    }
    

    If there is a return statement in the catch, the finally is still executed!

    The finally does not execute only when:

    Application termination (try or catch execute Sysem.exit())
    Fatal errors – the JVM crashes

    
    public class ExceptionExample {
    
    	int getInt() {
    		int res = 0;
    		int[] arr = new int[] {1,2,3,4};
    		
    		try {
    			System.out.println(arr[4]);
    			
    		}
    		catch (ArrayIndexOutOfBoundsException ae) {
    			res = 1;
    			System.out.println("An exception has been caught!");
    			return res;    //Because this is here, even though finally is executed the value returned will be 1 as this is the designated return value.
    		}
    		finally {
    			res = res + 100;
    		}
    		return res;
    	}
    	public static void main(String[] args) {
    		
    		ExceptionExample t = new ExceptionExample();
    		System.out.println(t.getInt());
    	}
    }
    
    

    The above applies to a primitive. For an object, the finally does affect the value returned because you are referencing the object. It can’t modify the primitive return type.

    
    	StringBuilder getValue() {
    		StringBuilder res = new StringBuilder("10");
    		int[] arr = new int[] {1,2,3,4};
    		
    		try {
    			System.out.println(arr[4]);
    		}
    		catch (ArrayIndexOutOfBoundsException ae) {
    			System.out.println("An exception has been caught!");
    			return res;    
    		}
    		finally {
    			res.append(100);
    		}
    		return res;
    	}
    	public static void main(String[] args) {
    		
    		ExceptionExample t = new ExceptionExample();
    		System.out.println(t.getInt());    //This returns 10100
    	}
    

    Some rules:

    A try block can be followed by a catch or finally block, or both. However, if the code in the try can throw a checked exception then this needs to be thrown by your method.
    A finally block cannot appear before a catch

    The order of the exceptions do matter when the classes are related. If you try to catch an exception of the base before the derived then the code will not compile. As an example, FileNotFound would come before IOException, as this reflects both the hierarchy and logic 🙂

    You can catch and/or throw exceptions, so your code can try, then catch an exception and re-throw it. However if your code does re-throw it you must declare this.

    import java.io.*;
    
    public class ExceptionExample {
    	FileInputStream fis;
    	
    	public void load() throws FileNotFoundException {  //You need to declare this otherwise it fails to compile
    		try {
    			fis = new FileInputStream("file.txt");
    		}
    		catch (FileNotFoundException fnf) {
    			throw fnf;
    		}
    	}
    }
    

    Alternatively you can just throw, without having to check anything:

    public void load() throws IOException {
    	fis = new FileInputStream("file.txt");
    	fis.close();
    }
    
    Categories

    There are three categories:

  • Checked
  • Runtime
  • Errors
  • FileNotFound is a checked exception, it is thrown if the file cannot be found. A checked exception is a subclass of the java.lang.Exception class, but not a subclass of java.lang.RuntimeException.

    If a method uses a method which may throw a checked exception, it must

  • use try-catch block
  • and/or

  • throw the exception in the methods signature
  • Not doing this means the code will fail to compile.

    By declaring these exceptions, the user is aware of the exception that could occur and writes code to handle this.

    Runtime exceptions, also known as unchecked exceptions, an example is NullPointerExeption. These represent a programming error (e.g. you didn’t instantiate an object). It is a subclass of java.lang.RuntimeException.

    You can catch runtime exceptions. Saying that you can prevent runtime exceptions by using code as well.

    
    //This code will through a runtime exception
    
    int[] arr = new int[] {0,2,4,6,8};
    
    System.out.println(arr[5]);  //This is the runtimeexception!
    
    //This code uses a try-catch block
    
    try {
    	System.out.println(arr[5]);
    }
    catch (ArrayIndexOutOfBoundsException e) {
    	System.out.println("the array is not as big as you think...");
    }
    
    //However, you could just use logic....
    
    if (arr.length > 5) {
    	System.out.println(arr[5]);
    }
    

    Finally there are Errors. An example of which is StackOverflowError, this is thrown by the JVM when the size of the memory required is too large. It is a serious exception.
    Errors are a subclass of java.lang.Error.
    Errors are not part of a method signature.
    Errors can be caught by an exception handler, but should not be.

    Common exceptions
    ArrayIndexOutOfBoundException

    As previously covered, you are trying to reference an array entry outside of the limits (positive or negative).

    
    int[] arr = new int[] {0,2,3,5,6};
    
    System.out.println(arr[5]);
    System.out.println(arr[-1]);
    
    
    IndexOutOfBoundsException

    You are trying to reference an ArrayList entry outside of the limits (positive or negative).

    
    ArrayList<String> as = new ArrayList<String>();
    
    as.add("hello");
    as.add("world");
    
    System.out.println(as.get(100));
    System.out.println(as.get(-1));  //Both throw IndexOutOfBoundsException
    
    

    Simply, check the size of your Array / ArrayList before referencing entry.

    ClassCastException

    This is caused when you try and cast an object into something it is not part of:

    ArrayList<Employee> ees = new ArrayList<Employee>();
    ees.add(new Programmer());
    ees.add(new Manager());
    		
    Employee e1 = (Manager)ees.get(0);
    

    This can be easily resolved by validating the instanceof the object before casting:

    ArrayList<Employee> ees = new ArrayList<Employee>();
    ees.add(new Programmer());
    ees.add(new Manager());
    	
    if (ees.get(0) instanceof Manager) {
    	Employee e1 = (Manager)ees.get(0);
    }
    
    IllegalArgumentException

    This is thrown when the wrong value is passed into an argument. Think password, it must be 6 characters long:

    
    ...
    
    public void checkPassword(String password) throws IllegalArgumentException {
    	
    	if (password == null || password.length() < 6) {
    		throw new IllegalArgumentException("Password incorrect, please enter a password which is atleast 6 characters long");
    	}
    }
    
    ...
    
    public static void main(String[] args) {
    	try {
    		t.checkPassword(null);
    	}
    	catch (IllegalArgumentException ia)
    	{
    		System.out.println(ia.getMessage());   //This will print the message from the method
    	}
    }
    
    IllegalStateException

    From the Java API documentation, this “signals that a method has been invoked at an illegal or inappropriate time”.

    An example, a transfer:

    class Account {
    	private int accountNumber;
    	private double totalAmount;
    	private double transferAmount;
    	private boolean transfer;
    	
    	public void createTransfer(double amt) {
    		if (amt < totalAmount) {
                            totalAmount = totalAmount - amt;
    			transferAmount = amt;
    		}
    	}
    	
    	public void transfer() {
    		//code to send the money
    		transfer = true;
    	}
    	
    	public void modifyTransfer(float amt) {
    		if (!transfer) {
    			createTransfer(amt);
    		}
    		else {
    			throw new IllegalStateException("Money already being transferred");
    		}
    	}
    }
    
    public class ExceptionExample {
    	public static void main(String[] args) {
    		Account a = new Account();
    		try {
             		a.createTransfer(100.00);
    	        	a.transfer();
    		        a.modifyTransfer(150.00);
    		}
    		catch (IllegalStateException is) {
    			System.out.println(is.getMessage());
    		}
    	}
    }
    
    NullPointerException

    It occurs when:

  • reference variable that is explicitly assigned a null value
  • reference variable which has not been initialised
  • An unitialised local variable
  • Accessing nonexistent array positions
  • Using members of an array where the element is null
  • Some examples:

    class ExampleException {
    	static ArrayList<String> list = null;
    	public static void main(String[] args) {
    		list.add("Hello"); // this will throw a null pointer exception
    
    		//You can prevent null pointer by checking the object
    
    		if (list != null) {
    			list.add("hello");
    		}
    
    		//However, if list was defined here:
    		ArrayList<String> list2;
    		if (list2 != null) {           //This would fail to compile - as local variables are not assigned a value
    			list2.add("hello");
    		}
    

    Another:

    class ExampleException {
    	static String[] strArr;
    	public static void main(String[] args) {
    		System.out.println(artArr[1]);  //This will throw a NullPointerException
    		//strArr is assigned null as it is a static. It's elements are not initialised
    		
    		String[] secondArr = new String[4];
    		
    		System.out.println(secondArr[1].toString()); //This will throw a NullPointerException
    		//This is because you are calling the method toString() on the null string
    		System.out.println(secondArr[1]); //this is fine, it will print null
    	}
    }
    

    NumberFormatException

    This is thrown when an invalid string, for example, is converted to a “number”:

    
    System.out.println(Interger.parseInt("ABCD"));  //This will throw a NumberFormatException
    System.out.println(Interger.parseInt("24_68"));  //This will throw a NumberFormatException, the underscore in the string
    System.out.println(Interger.parseInt("+246")) //All fine.
    
    //If we take the first example, this can be parsed by passing in a parameter:
    
    System.out.println(Interger.parseInt("ABCD", 16));
    
    
    ExceptionInInitializerError

    Thrown when a static initializer in the code throws a runtimeexception:

    //An example
    static {
    	int number = Integer.parseInt("65v", 16);
    }
    

    This error can only be caused by runtimeexceptions.

    StackOverflowError

    This should be managed by the JVM, it is thrown when the program calls itself too many times.

    NoClassDefFoundError

    A really annoying error when your classpath is not set, or not inclusive. You do not handle this with code, you just suffer trying to set the classpath 🙂

    OutOfMemoryError

    Thrown when you have exhausted the memory on the heap.

    reference: http://www.manning.com/gupta/

    Java String, StringBuilder, Arrays, and ArrayList code and rules

    February 19, 2014

    String class

    
    String s1 = new String("Hello");
    String s2 = new String("Hello");   //Using the new operator means these are separate objects
    
    System.out.println(s1 == s2);  // print false - because you are comparing the objects addresses
    
    String s3 = "Goodbye";
    String s4 = "Goodbye";
    
    System.out.println(s3 == s4); // prints true - s3 and s4 are referring the same object, as they have the same sequence of characters. s4 is pointing to the same object as s3 (s3 created the object)
    
    String m1 = "morning";
    System.out.println("morning" == m1);   // prints true, referring to the same object
    
    String m2 = new String("morning");
    System.out.println("morning" == m2);   // prints false, different objects
    
    

    String has overloaded constructors!

    
    String s1 = new String("hello");
    
    char[] c1 = new char[] {'H','e','l','l','o'};
    String s2 = new String(c1);
    
    StringBuilder sb1 = new StringBuilder("hello");
    String s3 = new String(sb1);
    
    StringBuffer sbf1 = new StringBuffer("hello");
    String s4 = new String(sbf1);
    
    //A literal value for a String is null
    
    String s5 = null;
    
    

    To recap String objects created versus references, let me show you where String objects are created

    
    String s1 = new String("a string");  //object created
    String s2 = "a string";              //object created
    System.out.println("a string");      //reference 
    System.out.println("different string");  //object created
    System.out.println("different string" == "A string") //references (different string) and create (A string)
    String different_string = new String("a string");  //object created
    
    //This creates a total of five objects
    
    

    Strings are immutable

    Once created they can never be modified. String uses a char[] array to store the value “hello”.

    
    String exampleValue = "hello";
    
    //This is stored as a char[] e.g.
    
    char[] exampleValue = new char[]{'h','e','l','l','o'};
    
    

    It uses a final variable to store the value. This variable is private, meaning all methods of String appear to modify the string but in fact return a new String.

    Methods of String
    String example = new String("Hello World");
    
    //charAt(int index)
    System.out.println(example.charAt(0));   //returns H
    System.out.println(example.charAt(2));   //returns l
    
    //indexOf(char or String)
    System.out.println(example.indexOf('W'));  //6
    System.out.println(example.indexOf("rl")); //8 - start of rl
    System.out.println(example.indexOf("z"));  //-1 - not there
    System.out.println(example.indexOf('l'));  //2 first occurrence of l
    
    //substring(int start position, [int length])
    
    System.out.println(example.substring(6)); //World
    System.out.println(example.substring(0,5)); //Hello
    //NB: substring does not include the character at the end of the string
    
    //trim()
    
    String trimExample = new String("  Hello World  ");
    System.out.println(":"+trimExample+":");          //returns - :  Hello World  :
    System.out.println(":"+trimExample.trim()+":");   //returns - :Hello World:
    
    //replace(char, char) or replace(String, String)
    
    System.out.println(example.replace('o','P');            //returns - HellP WPrld
    System.out.println(example.replace("Hello","GOODBYE");  //returns - GOODBYE World
    
    //length()
    
    System.out.println(example.length()); //returns - 11 (remember length-1 gives you the position
    
    //startsWith() and endsWith()
    //startsWith(String, [int position])
    
    System.out.println(example.startsWith("H");   //return true
    System.out.println(example.startsWith("o",4); //returns true
    
    System.out.println(example.endsWith("d"));     //returns true
    System.out.println(example.endsWith("worlD")); //returns false
    
    //Methods can be chained together, when this is the case they are evaluated left to right
    
    System.out.println(example.replace(' ','X').substring(0,5)); //returns Hello
    System.out.println(example.replace(' ','Y').substring(5));   //returns YWorld
    
    //Nasty one!!!
    
    System.out.println(example.substring(0,2).startsWith('H'));  //this will not compile!!!!
    
    System.out.println(example.substring(0,2).startsWith("H")); //this returns true!!!!
    
    
    String concatenation and Equality
    
    int intValue1 = 10;
    int intValue2 = 20;
    
    String strValue1 = "abcde";
    
    String strValue2 = intValue1 + intValue2 + strValue1;  //evaluation is from left to right, so adds then concatenates
    
    System.out.println(strValue2);  //returns 30abcde
    
    String strValue3 = strValue1 + intValue1 + intValue2;
    
    System.out.println(strValue3);   // returns abcde1020
    
    String strValue4 = strValue1 + (intValue1 + intValue2);
    
    System.out.println(strValue4);   // returns abcde30
    
    //then there is the += to concatenate
    
    String example2 = "Hello";
    
    example2 += " world";
    
    String example3 = null;
    example3 += "example3";
    System.out.println(example3); //returns nullexample3
    
    

    For equality, lets look at the equals method from the class String

    public boolean equals(Object anObject) {
        if (this == anObject) {     //if the objects are the same, then return ture
            return true;
        }
        
        if (anObject instanceof String) {               //Object is a string
            String anotherString = (String)anObject;
            int n = count;
            if (n == anotherString.count) {   //checks if the length of the string in the two objects are the same
                 char v1[] = value;
                 char v2[] = anotherString.value;
                 int i = offset;
                 int j = anotherString.offset;
                 while (n-- != 0) {              //Iterate through each string comparing char by char
                      if (v1[i++] != v2[j++])
                      return false;              //If one does not match the other then false
                 }
                 return true;                    //If both match then true
         }
         return false;
    }
    

    Quite interesting, lets look at some examples:

    String example1 = new String("Hello");
    String example2 = new String("Hello");
    
    System.out.println(example1.equals(example2));  // returns true
    
    System.out.println(example1 == example2);       // return false - they are two different objects
    System.out.println(example1 != example2);       // return true - they are two different objects
    
    
    String example3 = "Goodbye";
    String example4 = "Goodbye";
    
    System.out.println(example3.equals(example4));  // returns true
    
    System.out.println(example3 == example4);       // returns true - they are the same objects (reference!)
    
    //== compares reference objects
    //equals compares String values
    
    

    StringBuilder

    Creating StringBuilder:

    StringBuilder sb1 = new StringBuilder();

    StringBuilder sb2 = new StringBuilder(sb1); //Constructor takes StringBuilder object (default length is 16)

    StringBuilder sb3 = new StringBuilder(100); //Constructor takes length of String

    StringBuilder sb4 = new StringBuilder(“Hello World”); //Constructor takes String (length is String + 16)
    [/code]

    Methods of StringBuilder
    
    //APPEND() - accepts String, char array and Object
    StringBuilder sbExample = new StringBuilder();
    sbExample.append(true);
    sbExample.append(100);
    sbExample.append('b');
    sbExample.append(39.99);
    sbExample.append("Hello");
    
    System.out.println(sbExample);  //returns true100b39.99Hello
    
    char[] c = {'H','e','l','l','o',' ','W','o','r','l','d'};
    sbExample.append(c,5,6);         //takes char array, start pos, and length
    System.out.println(sbExample);  //returns true100b39.99Hello World
    
    //Remember my class Example? Well it is mentioned on another posting, a simple class
    
    sbExample.append(new Example());  //Appends this object to the stringbuilder object
    
    

    The stringbuilder append method will call the .toString() method on the object, if you have not overwritten this (as in this case) it use the default implementation.

    Example of the append code:

    public AbstractStringBuilder append(boolean b) {
    if (b) {
    int newCount = count + 4; //adds 4 (length of “true”) to count – which is the number of characters held in the StringBuilder object
    if (newCount > value.length) expandCapacity(newCount); //If the array is not long enough then it expands it

    value[count++] = ‘t’;
    value[count++] = ‘r’;
    value[count++] = ‘u’;
    value[count++] = ‘e’;
    }
    else {

    }
    return this;
    }
    [/code]

    Next up is Insert.

    StringBuilder example = new StringBuilder("bot");
    
    example.insert("a",2);    //inserts the a before the t which is at position 2
    
    System.out.println(example); //returns boat
    
    

    You can also insert strings, and substrings of strings

    StringBuilder example2 = new StringBuilder("Hello my friend");
    
    char[] value = new char[]{'G','o','o','d','b','y','e',' ','w','o','r','l','d'};
    
    example2.insert(5,value,7,6);
    
    System.out.println(example2); // returns Hello world my friend
    
    

    How about Deleting, persisting example2

    
    example2.delete(5,11);   //5 is the start position, 11 is the length (6) added onto the start position
    System.out.println(example2);
    
    

    There is NO TRIM() method with StringBuilder

    reverse()

    Lets use a palindrome to demonstrate reverse 🙂 I mean, it is the best way to see it no?

    StringBuilder palinDrome = "Man o nam";
    
    palinDrome.reverse();
    
    System.out.println(palinDrome); //return man o naM
    
    
    replace()

    Replaces a sequence of characters based on their position, with another String.

    
    StringBuilder example = new StringBuilder("Hello my good friend");
    
    example.replace(6,20,"World");   //where 6 is the start position, and 20 is the end position, and World is the text to replace that space
    
    System.out.println(example);  //returns Hello World
    
    
    subSequence()

    Returns a CharSequence, which can easily be cast as a String if you want of the String in the StringBuilder

    
    StringBuilder exampleSubSeq = new StringBuilder("0123456789");
    CharSequence subr = exampleSubSeq.subSequence(5,8);     //start position is 5 and end position is 8 (everything before the end position)
    System.out.println(subr);                               //returns 567
    System.out.println(exampleSubSeq);                      //returns 0123456789
    
    

    Arrays

    What is an Array?

    A collection of primitive types, and/or a collection of objects.

    
    int primitiveArray[] = new int[] {1,2,3,4};
    String objectArray[] = new String[] {"Hello", "World", "Goodbye", "all"};
    
    
    Declaring arrays
    
    int primitiveArray[];
    
    int[] primitiveArray;  //Both of these are the same
    
    int[] primitiveArray[]; //is the same as:
    int[][] primitiveArray; //which is the same as:
    int primitiveArray[][]; //These are multi-dimensional arrays
    
    //You cannot define the size of the array in declaration
    int primitiveArray[2];
    int[3] primitiveArray;
    int[4] primitiveArray[4];
    //None of the above will compile
    
    
    Array allocation

    This is when specify the size of the array, please remember the size cannot change!!

    int primitiveArray[];
    String multiDArray[][];
    
    primitiveArray = new int[100];
    multiDArray = new String[5][5];
    
    //The following are incorrect and will not compile
    primitiveArray = new int[];
    //or
    primitiveArray[200] = new int;
    
    //You can pass in variables for array allocation
    
    int i = 100, j = 20;
    String objectArray[] = new String[i*j]; //an array with 2000 elements
    
    String objectArray[] = new String[Math.min(i,j)]; //an array of 20 elements
    
    //Multi-dimensional arrays
    
    int[] multi[];
    multi = new int[100][];   //This is fine - in the first bracket
    
    multi = new int[][100];   //This is not fine, it will not compile
    
    
    Array Initialisation

    Arrays can be initialised directly or through a loop.

    
    String[] stringArray = new String[4];
    
    for (int i = 0; i < stringArray.length; i++) {
        stringArray[i] = "Hello " + i;
    }
    
    //alternatively, you can set each value - in this instance the Hello string are overwritten
    
    stringArray[0] = "goodbye";
    stringArray[1] = "fairwell";
    stringArray[2] = "see ya";
    stringArray[3] = "ciao";
    
    // the following will compile but generate a runtime exception
    
    stringArray[4] = "oh dear";
    
    // code will fail to compile if you don't pass in a char, byte, short or int
    
    // You can combine all three, declaration, allocation, and initialisation e.g.
    
    String[] strArray = {"a","b","c"}; //declares an array of size 3 with the values. NB no need for new operator
    //You can use new, but you can't specify the size as well
    String[] strArray = new String[]{"a","b","c"}; //fine
    String[] strArray = new String[3]{"a","b","c"}; //fails to compile
    
    //the following does not compile
    String[] strArray;
    strArray = {"a","b"};
    
    //You need a new
    String[] strArray;
    strArray = new String[]{"a","b"};
    
    

    Asymmetrical multidimensional arrays, are multidimensional arrays which are not symmetrical – no surprise really. What does this mean?

    String multiAsymArr[][] = new String[][] {
                  {"1","2"},
                  null,
                  {"a","b","c"},
                  {"Z","Y",null,"x"},
           };
    
    //note the above does not have the same number of columns
    
    Interface, abstract, and object class arrays

    You can define an array type as an interface, abstract class, or a object class.

    
    interface exampleInterface { }
    class ExampleClass1 implements exampleInterface {}
    class ExampleClass2 implements exampleInterface {}
    
    ...
    
    exampleInterface[] exampleArray = new exampleInterface[] {
                                                  new ExampleClass1(),
                                                  new ExampleClass2(),
                                                  null
                                           };
    
    //This array can hold objects which implement the interface or nulls
    
    

    For Abstract class it is the same as interface, create the abstractclass. Create an array of the type the same as the abstract class and then it can hold objects which extend the abstract class or nulls.

    Finally Objects. Well every object extends Object, so an array of Object can hold any Object:

    interface exampleInterface { }
    class ExampleClass1 implements exampleInterface { }
    abstract class exampleAbstract{ }
    class ExampleClass3 extends exampleAbstract{ }
    
    ...
    
    Object[] objectArrayExample = new Object[] {
                                 new ExampleClass1(),
                                 new ExampleClass3(),
                                 new java.util.Date(),
                                 new String("hello world"),
                                 null,
                                 new Integer[10]
                         };
    
    //As you can see an Object array can hold all different types of objects - including null.
    

    To determine the number of elements in an array, use the method length. String has the method length() which returns the length of the string value.

    ArrayList

    Easier to use than an array. It automatically increases/decreases it’s size (unlike an Array). You don’t have to specify the initial size of the ArrayList. Some further pointers

  • null values can be added
  • interface List implemented
  • operators add, modify, and delete implemented
  • holds duplicate values
  • maintains order of values inserted
  • To iterate over an ArrayList you can use Iterator or ListIterator
  • Supports generics
  • declaring
    //you need to import ArrayList!!!!
    import java.util.ArrayList;
    
    public class ExampleCreateArrayList {
          public static void main(String[] args) {
                 ArrayList<String> example = new ArrayList<String>();
                 //As of Java version 7 you can create an arraylist like so:
                 ArrayList<String> example = new ArrayList<>();  //note the removal of String? Only Java 7 and higher
          }
    }
    //The initial size of an ArrayList is 10
    
    Adding elements

    We will stick with example now that it has been created as a ArrayList of String:

    //already done this
    //ArrayList<String> example = new ArrayList<String>();
    
    example.add("Hello");
    example.add("world");
    example.add("how");
    example.add("are");
    example.add("you");
    //all fine and dandy.
    //however we can add a value at a specified position.....
    example.add(3,"this is position three");
    
    //Accessing elements in an array is done via the enhanced for loop
    
    for (String element : example) {
         System.out.println(element);
    }
    
    /*This will output
    Hello
    world
    how
    this is position three
    are 
    you
    */
    
    //You can also use a ListIterator to access the elements
    ListIterator<String> exampleIterator = example.listIterator();
    
    while(exampleIterator.hasNext()) {
        System.out.println(exampleIterator.next());
    }
    
    

    NB: An Iterator or ListIterator, allows you to remove elements as you iterate over – this is not possible using a enhanced for loop.

    Modifying values
    import java.util.ArrayList;
    public class ModifyArrayListExample {
        public static void main(String[] args) {
            //So what we are going to do is create an arraylist, and then modify each value
            //rather than String, we will use StringBuilder as Strings are immutable
    
            ArrayList<StringBuilder> examArrList = new ArrayList<StringBuilder>();
            examArrList.add(new StringBuilder("First"));
            examArrList.add(new StringBuilder("Second"));
            examArrList.add(new StringBuilder("Third"));
    
            for (StringBuilder element : examArrList) {
                  element.append(" "+element.length());
            }
    
    
            //Now lets have a look at what we have done
    
            for (StringBuilder element : examArrList) {
                  System.out.println(element);
            }
    
            /*
                 First 5
                 Second 6
                 Third 5           
            */
    
            //Another nice little one.... You can replace/change a value:
            examArrList.set(2,new StringBuilder("This is position two!"));
    
            for (StringBuilder element : examArrList) {
                  System.out.println(element);
            }
    
            /*
                 First 5
                 Second 6
                 This is position two!
            */
    
        }
    }
    
    Removing elements

    There are two ways to remove elements:

  • remove(int index)
  • remove(Object o) — Only the first occurrence of the object
  • Lets continue with the example above.

    
            //In the first instance lets remove an entry....
            examArrList.remove(2);
            for (StringBuilder element : examArrList) {
                  System.out.println(element);
            }
    
            StringBuilder exampleSB1 = new StringBuilder("example StringBuilder object");
    
            examArrList.add(exampleSB1);
            for (StringBuilder element : examArrList) {
                  System.out.println(element);
            }
            
            examArrList.remove(exampleSB1);
    
            for (StringBuilder element : examArrList) {
                  System.out.println(element);
            }
    
            //The new string is no longer in the list
    
    

    More methods to look at are

  • addAll(Collection c) – appends the collection to the end of the list
  • addAll(int index, Collection c) – appends all of the elements from the collection from position index to the end of the list
  • You can clear down your arraylist with the method .clear()

    
    ArrayList<String> example = new ArrayList<String>();
    example.add("Hello");
    example.add("world");
    example.add("goodbye");
    example.add("my friend");
    
    String val1 = example.get(1);
    System.out.println(val1); // return world
    
    int arrSize = example.size();
    System.out.println(arrSize); //return the size of the arraylist 4
    
    

    Other methods which are quite interesting… contains, indexof and lastIndexOf.

    //Create a Example Car class
    class Car {
        String model;
        Car(String model) {
            this.model = model;
        }
    
        @Override
        public boolean equals(Object obj) {
            if (obj instanceof Car) {
                Car t = (Car)obj;
                boolean res = t.model.equals(this.model);
                return res;
            }
            else return false;
       }
    }
    
    public class Example {
        public static void main(String[] args) {
           ArrayList<Car> myArrayList = new ArrayList<Car>();
    
           Car c1 = new Car("316");
           Car c2 = new Car("Micra");
    
           myArrayList.add(c1);
           myArrayList.add(c2);
           myArrayList.add(c2);
    
           System.out.println(myArrayList.contains(new Car("316")); //returns true - this is because we have overridden equals
           System.out.println(myArrayList.contains(c1); //returns true
    
           System.out.println(myArrayList.indexOf(new Car("Micra"));  //return 1 - this is because we have overridden equals
           System.out.println(myArrayList.indexOf(c2));  //returns 1
    
           System.out.println(MyArrayList.lastIndexOf(new Car("Micra"));  //returns 2 - this is because we have overridden equals
           System.out.println(MyArrayList.lastIndexOf(c2)); //returns 2
      }
    }
    

    You can clone an ArrayList, as well as return a Array of an ArrayList. Below is an example showing both the toArray in action and noting how referencing an object can come into play.

    import java.util.ArrayList;
    
    class ExampleArray {
    
    	static ArrayList als; // = new ArrayList();
    	static ArrayList alsb; // = new ArrayList();		
    	static String[] sarr;
    	static StringBuilder[] sbarr;
    
    	public static void displayAL() {
    		System.out.println("Displaying Array Lists");
    		
    		for (String val: als)
    			System.out.println(val);
    			
    		for (StringBuilder val: alsb)
    			System.out.println(val);	
    	}
    	
    	public static void displayA() {
    		System.out.println("Displaying Arrays");
    		
    		for (int i = 0; i &lt; sarr.length; i++) {
    			System.out.println(sarr[i]);
    		}
    
    		for (int i = 0; i &lt; sbarr.length; i++) {
    			System.out.println(sbarr[i]);
    		}	
    	}
    
    	public static void main(String[] args) {
    		
    		
    		String s1 = new String(&quot;hello&quot;);
    		String s2 = new String(&quot;there&quot;);
    		
    		StringBuilder sb1 = new StringBuilder(&quot;good&quot;);
    		StringBuilder sb2 = new StringBuilder(&quot;day&quot;);
    		
    		als = new ArrayList();
    		alsb = new ArrayList();
    		
    		als.add(s1);
    		als.add(s2);
    		
    		alsb.add(sb1);
    		alsb.add(sb2);
    		
    		System.out.println("first run through");
    		displayAL();
    		
    		sarr = new String[als.size()];	
    
    		sarr = als.toArray(sarr);
    
    		sbarr = new StringBuilder[alsb.size()];
    
    		sbarr = alsb.toArray(sbarr);
    		
    		System.out.println("second run through");
    		displayAL();
    		displayA();
    		
    		System.out.print("Changed s1 from "+s1);
    		
    		
    		s1 = "zzzzz";
    		
    		
    		System.out.println(" to "+s1);
    		System.out.println("s1 is in Array List and String Array");
    		System.out.print("changed sb1 from "+sb1);
    		
    		
    		sb1.append(" my dear old ");
    		
    		
    		System.out.println(" to "+sb1);
    		System.out.println("sb1 is in Array List and String Array - what will we see?");
    		
    		System.out.println("third run through");
    		displayAL();
    		displayA();
    	}
    }
    

    The output from this is:

    first run through
    Displaying Array Lists
    hello
    there
    good
    day
    second run through
    Displaying Array Lists
    hello
    there
    good
    day
    Displaying Arrays
    hello
    there
    good
    day
    Changed s1 from hello to zzzzz
    s1 is in Array List and String Array
    changed sb1 from good to good my dear old
    sb1 is in Array List and String Array – what will we see?
    third run through
    Displaying Array Lists
    hello
    there
    good my dear old
    day
    Displaying Arrays
    hello
    there
    good my dear old
    day

    NB: how the change to the StringBuilder variable is reflected in both the ArrayList and the Array, this is because both the ArrayList and Array are holding references to the object.

    Equals, how objects are compared

    Let’s take an example of expanding the functionality of the equals methodology.

    import java.util.Date;
    import java.text.DateFormat;
    import java.util.Locale;
    import java.util.ArrayList;
    
    class ExampleEquals {
    	private String name;
    	private Date dob;
    	
    	ExampleEquals(String n, Date b) {
    		name = n;
    		dob = b;
    	}
    	
    	public String getName() {
    		return name;
    	}
    	
    	public Date getDOB() {
    		return dob;
    	}
    	
    	public boolean equals(Object o) {	   //NB: The equals method accepts a Object, not a ExampleEquals.
    		if (o instanceof ExampleEquals) {  //NB: You then evaluate the object to see if it is of the instance you want
    			ExampleEquals t = (ExampleEquals)o;  //NB: Then you can instantiate it
    			return (name.equals(t.getName()) && dob.equals(t.getDOB()));
    		}
    		
    		return false;
    	}
    }
    
    class TestExampleEquals {
    	public static void main(String args[]) throws Exception {
    
    		DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, Locale.UK);
    		
    		ExampleEquals e1 = new ExampleEquals("test", df.parse("25/12/1950"));
    		
    		ExampleEquals e2 = new ExampleEquals("tess", df.parse("25/12/1950"));
    		
    		ExampleEquals e3 = new ExampleEquals("test", df.parse("25/12/1950"));
    		
    		System.out.println("e1 compared to e2 == "+e1.equals(e2));
    		System.out.println("e2 compared to e3 == "+e2.equals(e3));
    		System.out.println("e3 compared to e1 == "+e3.equals(e1));
    		
    		//As you can see, comparing these objects uses our definition of the equals method
    		
    		//Lets us throw an ArrayList into the mix
    		
    		ArrayList<ExampleEquals> al = new ArrayList<ExampleEquals>();
    		al.add(e1);
    		al.add(e2);
    		al.add(e3);
    		
    		ExampleEquals e4 = new ExampleEquals("tess", df.parse("25/12/1950"));
    		
    		System.out.println("ArrayList contains e2 == "+al.contains(e2));
    		
    		System.out.println("ArrayList contains e4 == "+al.contains(e4));
    		
    	}
    }
    

    Output from this is:

    e1 compared to e2 == false
    e2 compared to e3 == false
    e3 compared to e1 == true
    ArrayList contains e2 == true
    ArrayList contains e4 == true

    Always be sure the equals takes an Object and not the actual class.

    The equals contract:

  • It is reflexive – any non-null reference value x, x.equals(x) should return true;
  • It is symmetric – any non-null reference value x and y, x.equals(y) should return true if and only if y.equals(x) returns true.
  • It is transitive – any non-null reference value x, y, and z, if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) should return true.
  • It is consistent – any non-null reference value x and y, multiple invocations of x.equals(y) consistently return true or consistently return false, provided no information used in equals() comparisons on the objects is modified.
  • for any non-null reference value x, x.equals(null) should return false.
  • The following violates the contract:

    public boolean equals(Object o) {
          return false;
    }
    

    A method which returns true (for equals) when passed a null violates this contract. The equals method cannot touch the values it is comparing, just compare them.

    reference: http://www.manning.com/gupta/

    Java Basics code and rules

    February 17, 2014

    Components of a class:

    Package statement
    
    Import statements
    
    /*
      Comments
    */
    
    class declaration {
      Variables
      //Comments
      Constructors()
      Methods()
      Nested classes {}
      Nested interfaces {}
      Enum
    }
    

    A comment can precede a package statement.

    Class declaration:

    Compulsory:

    Keyword class – case sensitive
    Name of the class
    class body – {}

    Optional:

    Access modifier, e.g. public
    Nonaccess modifier, e.g. final
    Keyword extends
    Keyword implements

    Within a class you have:

    Variables, these are instance variables or instance attributes – apply to the object only
    Methods, used to manipulate the instance variables
    Constructors, used to create and initialise the objects of a class

    You can define a class in a single file or multiple classes in one file, these (classes and interfaces) can be defined in any order.

    If you have a file (example.java) with the following:

    interface myInterface1 {
    
    }
    class MyClass1 {
    
    }
    interface myInterface2 {
    
    }
    public class MyClass2 {
    
    }
    public interface myInterface3 {
    
    }
    

    This will NOT compile because:
    1 – defining a public class of MyClass2 should be in a file of MyClass2.java
    2 – defining a public interface myInterface3 should be in a file of myInterface3.java

    You can either:

    1 – rename the class and interface to example
    2 – change the access to non-public

    Example:

    interface myInterface1 {
    
    }
    class MyClass1 {
    
    }
    interface myInterface2 {
    
    }
    class MyClass2 {
    
    }
    public interface example {
    
    }
    

    Only one package per source file.

    Executable classes are those which contain a main method.

    public class MyExecutableClass {
           public static void main(String args[]) {
                System.out.println("Hello, I am an executable class!!!");
           }
    }
    

    main method rules:
    Must be public
    Must be static
    Must be named main
    Must be a void
    Must accept String array or variable e.g.

    public class MyExecutableClass {
    	public static void main(String... args) { 
    		System.out.println("Hello, I am an executable class!!!");
    	}
    }
    

    Other examples:

    public static void main(String[] callMeAnything)
    public static void main(String callMeAnything[])
    
    //Also this works
    static public void main(String callMeAnything[])
    

    These produce errors:

    //This is a runtime error
    static public void main(String[] arguments[])
    //This is a compile error
    static void public main(String args[])
    
    Packages

    The rules:
    package names should be lowercase
    package and subpackage names separated by ‘.’
    com is commercial, followed by company name, then categories and subcategories
    package statement is the first in a source file (classes and interfaces) //Comments can appear though
    one package statement per file
    All classes and interfaces belong to the package defined in the file

    The import statement enables you to use simple names instead of using fully qualified names.

    importing classes with the same name won’t compile:

    import java.util.Date;
    import java.sql.Date;
    
    class example {
         
    }
    

    Unlike C or C++ importing a class doesn’t add to the size of a .class file.

    import java.util.*  //imports all classes and interfaces
    

    However it is not recursive, you cannot import classes / interfaces from a subpackage with the *.

    If you don’t specify a package then there is the default package, so if the class is in the same directory it can be referenced, e.g.:

    filename person.java

    class person {
    
    }
    

    filename house.java

    class house {
         person p;
    }
    

    This compiles because the files are in the same directory (or referenced) e.g.:

    javac tt/person.java house.java //this compiles
    

    import static used to import individual static members of a class, e.g.

    import static java.lang.Math.PI;
    
    public class example {
        public static void main(String[] args) {
             System.out.println(PI);
       }
    }
    
    Access modifiers

    There are four access modifiers:

    public
    protected
    default
    private

    Public access table:

    Anyone can see.

    Same package Separate package
    Derived classes true true
    Unrelated classes true true

    Protected access table:

    Accessible only to classes and interfaces in the same package
    And all derived classes

    Example:

    file …/people/Person.java

    package people;
    
    public class Person {
         protected String name;
    }
    

    file …/Home.java

    package building;
    
    import people.Person;
    
    public class Home {
         public Home() {
               Person p = new Person();
    
               p.name = "test";  //compile error as this is protected and in another package
         }
    }
    
    Same package Separate package
    Derived classes true true
    Unrelated classes true false

    Default access table:

    Only accessible to classes and interfaces in the same package.

    file …/people/Person.java

    package people;
    
    public class Person {
         int age;
         protected String name;
    }
    

    file …/Home.java

    package building;
    
    import people.Person;
    
    public class Home {
         public Home() {
               Person p = new Person();
               p.age = 100; //compile error as this is default, we are in a different package
               p.name = "test";  //compile error as this is protected and in another package
         }
    }
    
    Same package Separate package
    Derived classes true false
    Unrelated classes true false

    If you define a class as default, it cannot be accessed outside of that package (the default one) – like an inaccessible island.

    Private access table:

    Private members defined within a class are only accessible within that class.

    file …/people/Person.java

    package people;
    
    public class Person {
         private void countHairs() {}
         int age;
         protected String name;
    }
    

    file …/Home.java

    package building;
    
    import people.Person;
    
    public class Home {
         public Home() {
               Person p = new Person();
               p.countHairs(); //compile error as this is a private to Person
               p.age = 100; //compile error as this is default, we are in a different package
               p.name = "test";  //compile error as this is protected and in another package
         }
    }
    
    Same package Separate package
    Derived classes false false
    Unrelated classes false false
    Nonaccess modifiers

    Specifically:

    abstract
    final
    static

    Abstract

    prefixing abstract to the definition of a class makes it a abstract class, which cannot be instantiated. A abstract class may or may not have abstract methods.

    An interface is an abstract object by default. The compiler adds abstract to the definition of an interface, you can if you want.

    An abstract method does not have a body:

    abstract class example {
        private string name;
        public void getName() {}  //This is NOT an abstract method, it has an empty body
        public abstract void jump();  //This is a abstract method
    }
    

    Final

    A class marked as final cannot be extended by another class:

    final class Person {}
    class Worker extends Person {}
    //This code will not compile because Person is final
    

    An interface cannot be marked final, it is abstract.

    A final variable is assigned a value once, and cannot be changed. You can call methods on a final variable e.g.

    class Example {
        final StringBuilder test = new StringBuilder("abc");
        Example() {
            test.append("xyz"); //all fine
            test = new StringBuilder();  //Won't compile!
        }
    }
    

    A final method in a base case cannot be overwritten e.g.

      class Person {
        final void greeting() {
            System.out.println("Why hello there");
        }
      }
    
      class Worker extends Person {
        void greeting() {
            System.out.println("How do");  //This fails to compile
        }
      }
    }
    

    Static

    Makes the variable in a class applicable to all instances of the class, e.g.

    class Example {
       String name;
       static int amount;
    }
    
    class test {
       public static void main(String[] args) {
           Example e1 = new Example();
           Example e2 = new Example();
    
           e1.name = "Example One";
           e2.name = "Example Two";
    
           e1.amount = 100;
           e2.amount = 200;
    
           System.out.println(e1.name);     //This will print Example One
           System.out.println(e2.name);     //This will print Example Two
           System.out.println(e1.amount);   //This will print 200
           System.out.println(e2.amount);  //This will print 200
           System.out.println(Example.amount);  //What does this print? Well it prints 200!
       }
    }
    

    Static and final can be used to define a constant:

    class Example {
         public static final int WIDTH = 100;  //This is standard practice for constants
    }
    
    class Test {
        public static void Main (String[] args) {
             int w = Example.WIDTH;
        }
    }
    

    Static Methods

    class Example {
        String name;
        private static int amount;
    
        static int getAmount() {
            return amount;
        }
    }
    

    Static methods and variables cannot access non-static variables:

    class Example_static {
       String name;
    
       String getName() {
          return name;
       }
    
       static String staticName = getName();  //This fails to compile!
    }
    

    However, non-static can access static:

    class Example_static {
       String name;
       private static int amount;
    
       static int getAmount() {
          return amount;
       }
    
       int nonStaticGetAmount() {
           return amount;
       }
    }
    

    Static methods/variables cannot access the instance members.

    reference: http://www.manning.com/gupta/

    Java Data types code and rules

    February 17, 2014

    Primitive variables

    Boolean

    boolean result = false;
    

    Only have two states, true or false.

    Numeric (Integers and Floating point)

    Integers made up of byte, int, short, long

    type bits min/max value
    byte 8 -128 to 127
    short 16 -32,768 to 32,767
    int 32 -2,147,483,648 to 2,147,483,647
    long 64 -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807

    You can store integers in four bases:

    Base value range example
    2, binary 0 and 1
    int binaryValue = 0b1011;
    8, octal 0 and 7
    int octalValue = 0413;
    10, decimal 0 and 9
    int decimalValue = 10;
    16, hex 0 and 9 and A to F
    int hexValue = 0x1B;

    To help, Java 7 allows the use of underscores in the values, making it more readable:

    class Example_intergers {
    	public static void main(String[] args) {
    		long valueDecimal=101_256_202;
    		System.out.println("101_256_202 == "+valueDecimal);  //101256202
    		long valueOct=04_21;
    		System.out.println("04_21 == "+valueOct);  //273
    		long valueHex=0x20_CD_89;
    		System.out.println("0x20_CD_89 == "+valueHex);  //2149769
    		long valueBin=0b10_11;
    		System.out.println("0b10_11 == "+valueBin);  //11
    	}
    }
    

    There are rules for these underscores:

    int lit1 = _100;  // Cannot start
    int lit2 = 100_;  // or end with a underscore!
    
    long lit3 = 999_L; //cannot place before suffix
    
    long octV = 0_4; //cannot place straight after 0 prefix for Octal
    
    long binV = 0b_1; //cannot place straight after 0b prefix
    long hexV = 0x_CD; //cannot place straight after 0x prefix
    
    int t = Integer.parseInt("1234_567"); //cannot use in string of digits
    

    further examples:

    //Which of these will work?
    long v0 = 0_100_267_760; //This is fine
    //long v1 = 0_x_4_13; //No - compile error == ';' expected, illegal underscore
    //long v2 = 0b_x10_BA_75; //No - compile error == binary numbers must contain at least one binary digit, not a statement, illegal underscore
    //long v3 = 0b_10000_10_11; //No - compile error == illegal underscore
    //long v4 = 0xa10_AG_75; //No, not valid hex (G) - compile error == ';' expected
    long v5 = 0x1_0000_10; //fine
    long v6 = 100__12_12; //double __ but think it is still valid?
    

    Floating-Point (float and double) numbers

    type bits min/max value
    float 32 +/-1.4E-45 to +/-3.4028235E+38
    double 64 +/-4.9E-324 to +/-1.7976931348623157E+308

    You can tell the compiler it is a float:

    float v1 = 100.9824F;  //All floats must be declared with F or f
    float v2 = 1833.23456f;
    double v3 = 42356.23456;
    
    //You can use scientific notation
    double v4 = 123.1882e2;
    
    //You can use those underscores again
    
    float v5 = 1_000_000.45678f;
    
    float v6 = 1_000_000._45678f; //cannot use next to decimal point
    float v7 = 1_000_000_.45678F; //as above
    
    float v8 = 1_000_000.45678_f; //cannot use next to suffix f or d
    

    Character

    Stores a single 16-bit Unicode character. Stored as a unsigned integer.

    Examples are:

    char v1 = 'T';
    char v2 = 123;  //should be positive, negative fails to compile
    char v3 = '\u0123';
    

    variable names:

    int EXAMPLE-V1; //won't compile because of hyphen
    int example.v2; //won't compile because of '.'
    int %example;   //won't compile because of %
    
    int $example; //works
    int _example; //works
    

    Object reference variables

    class Example {}
    
    Example e0 = new Example();
    
    //e0 is the object reference variable - which is the heap-memory address value to the object
    
    int v0 = 100; //this value is stored in memory, rather than the reference
    

    Operator assignment

    class Assignment {
    
    	static int v1 = 10;
    	static int v2 = v1;
    
    	static void showValues() {
    		System.out.println("v1 == "+v1);
                    System.out.println("v2 == "+v2);
    	}
    
    	public static void main(String[] args) {
    
    		showValues(); // v1 == 10 v2 == 10
    
    		v2 += v1;
    		System.out.println("v2 += v1");
    		showValues(); // v1 == 10 v2 == 20
    		
    		v1 = v2 = 10;
    		showValues(); // v1 == 10 v2 == 10
    
    		v2 *= v1;
    		System.out.println("v2 *= v1");
    		showValues(); // v1 == 10 v2 == 100
    
    		v1 = v2 = 10;
    		showValues(); // v1 == 10 v2 == 10
    
    		v2 /= v1;
    		System.out.println("v2 /= v1");
    		showValues(); // v1 == 10 v2 == 1
    
    	}
    }
    

    Invalid assignments

    double v1 = true; //no can do!
    boolean v2 = 'c'; //no can do!
    boolean v3 = 0; //no can do!
    boolean v4 -= v3; //no can do (you can't add or subtract booleans)
    
    long v5 = 123456789012L;
    int v6 = v5; //no can do
    
    int v7 = 1234;
    long v8 = v7; //all good
    
    boolean v9 = true;
    int v10 = v9; //no can do
    

    More examples

    public class ExampleAssignment {
    	public static void main (String[] args) {
    		boolean v1, v2, v3, v4, v5, v6; //all fine
    		v1 = v2 = v3 = true; //all fine
    		v4 = 0; //no can do!
    		v5 = 'false' //no can do!
    		v6 = yes; //no can do!
    	}
    }
    

    Arithmetic operators

    class Assignment {
    
    	static int v1;
    	static int v2;
    
    	static double d1;
    	static double d2;
    
    	static void setIntValues() {
    		v1 = 20;
    		v2 = 10;
    	}
    
    	static void setDoubleValues() {
    		d1 = 20.0;
    		d2 = 10.0;
    	}
    
    	static void showIntValues() {
    		System.out.println("v1 == "+v1);
                    System.out.println("v2 == "+v2);
    	}
    
    	static void showIntValues(int v) {
    		showIntValues();
    		System.out.println("v3 == "+v);
    	}
    
    	static void showDoubleValues() {
    		System.out.println("d1 == "+d1);
                    System.out.println("d2 == "+d2);
    	}
    
    	static void showDoubleValues(double v) {
    		showDoubleValues();
    		System.out.println("d3 == "+v);
    	}
    
    
    	public static void main(String[] args) {
    
    		setIntValues();
    		showIntValues(); // v1 == 10 v2 == 20
    
    		++v1;
    		v2++;
    		System.out.println("++v1 and v2++");
    		showIntValues(); // v1 == 21 v2 == 11 - they are not part of an expression so behave the same way
    		
    		setIntValues();
    		int v3 = v1 - ++v2;
    		System.out.println("v1 - ++v2");
    		showIntValues(v3); // v1 == 20 v2 == 11 v3 == 9
    
    		setIntValues();
    
    		v3 = v1 - v2++;
    		System.out.println("v1 - v2++");
    		showIntValues(v3); // v1 == 20 v2 == 11 v3 == 10
    
    		
    
    		setDoubleValues();
    		double d3 = d1 * d2--;
    		System.out.println("d1 * d2--");
    		showDoubleValues(d3); // d1 == 20.0 d2 == 9.0 d3 == 200.0
    
    
    		setDoubleValues();
    		d3 = d1 * --d2;
    		System.out.println("d1 * --d2");
    		showDoubleValues(d3); // d1 == 20.0 d2 == 9.0 d3 == 180.0
    
    		int z = 10;
    		z = z++ + z + z-- - z-- + ++z;
    		//equivalent to
    		//10 + 11 + 11 - 10 + 10
    		System.out.println("z == "+z);  //32
    
    		z = 10;
    		z = ++z + z + --z - --z + z++;
    		//equivalent to
    		//11 + 11 + 10 - 9 + 9
    		System.out.println("z == "+z);  //32
    		
    	}
    }
    

    Relational operators

    class RelationalExample {
    	public static void main (String[] args) {
    		int v1 = 10;
    		int v2 = 20;
    
    		long v3 = 10;
    		long v4 = 20;
    
                    boolean v5 = false;
    
    		System.out.println("v1 >= v2 is "+(v1 >= v2)); //prints false
    
    		System.out.println("v4 >= v3 is "+(v4 >= v3)); //prints true
    
    		//Cannot compare different types, e.g. String versus long
    
    		System.out.println("v1 == v2 is "+(v1 == v2)); //false
    		System.out.println("v1 != v2 is "+(v1 != v2)); //true
    
    		System.out.println("v5 == true is "+(v5 == true)); //false
    		System.out.println("v5 != true is "+(v5 != true)); //true
    
    		System.out.println("v5 == false is "+(v5 == false)); //true
    		System.out.println("v5 != false is "+(v5 != false)); //false
    
    		System.out.println("v5 = true is "+(v5 = true)); //true
    		System.out.println("v5 = false is "+(v5 = false)); //false
    	}
    }
    

    Logical operators

    class LogicalExamples {
    	public static void main(String[] args) {
    		int v1 = 10;
    		int v2 = 20;
    		
    		System.out.println("10 > 20 && 20 > 10 is "+(v1 > 20 && v2 > 10)); //prints false
    		System.out.println("10 > 20 || 20 > 10 is "+(v1 > 20 || v2 > 10)); //prints true
    
    		System.out.println("!(20 > 10) is "+(!(v2 > 10))); //prints false
    		System.out.println("!(10 > 20) is "+(!(v1 > 20))); //prints true
    
    		//Logical AND (&&) is true if ALL operands equates to true
    		//Logical OR (||) is true if ONE operands equates to true
    		//Logical NOT (!) is true if operand is false (i.e. the oposite)
    
    		int v3 = 80;
    		int v4 = 100;
    
    		System.out.println(v3+", "+v4); //80, 100
    		System.out.println("v4 < v3 AND ++v3 > 50 is "+(v4 < v3 && ++v3 > 50)); //false
    		System.out.println(v3); //80
    		System.out.println("v4 == 100 OR ++v3 > 100 is "+(v4 == 100 || ++v3 > 100)); //true
    		System.out.println(v3); //80
    		
    		//Reason v3 does not get touched, lazy evaluation, once you know one you don't need to do the rest
    
    		int a = 10;
    		int b = 20;
    		int c = 40;
    		
    		System.out.println(a++ > 10 || ++b < 30); //true
    		 
    		System.out.println(" a == "+a+", b == "+b+", c == "+c); //a will be 11, b 21, c40
    		
    		System.out.println(a > 90 && ++b < 30); //false a still 11 b not touched
    		
    		System.out.println(" a == "+a+", b == "+b+", c == "+c); //a will be 11, b 21, c40
    		
    		System.out.println(!(c>20) && a==10); //false a not evaluated
    		
    		System.out.println(" a == "+a+", b == "+b+", c == "+c); //a will be 11, b 21, c40
    		
    		System.out.println(a >= 99 || a <=30 && b == 10); //false
    		
    		System.out.println(" a == "+a+", b == "+b+", c == "+c);	//a will be 11, b 21, c40	
    		
    		System.out.println(a >= 99 && a <= 33 || b == 10); //false
    		
    		System.out.println(" a == "+a+", b == "+b+", c == "+c);	//a will be 11, b 21, c40	
    	}
    }
    

    Operator precedence

    Order is

  • Postfix
  • Unary
  • Multiplication
  • Addition
  • Relational
  • Equality
  • Logical AND
  • Logical OR
  • Assignment
  • int a = 10, b = 20, c = 30;
    System.out.println(a % b * c + a / b);
    
    /*
    
    (((a % b) * c)) + (a / b)
    (((10 % 20) * 30)) + (10 / 20)
    ( (10       * 30)) + (0)
    (300)
    
    */
    
    //You can use parentheses to change the order
    
    System.out.println(a % b * (c + a) / b);
    
    /*
    ((10 % 20) * ((30 + 10) / 20)
    ((10     ) * ( 40       / 20)
    ((10     ) * ( 2            )
    (20)
    */
    

    reference: http://www.manning.com/gupta/