Вы находитесь на странице: 1из 18

Initialization & Cleanup

Guaranteed initialization with the constructor

Constructor = Guaranteed initialization If not constructor is written default is written and called. If parameterized constructor is written default constructor is not called.

Method overloading
identified by different parameter list Not identified by different return types because if return value was not caught compiler wouldn't know what value it was referring to.

Cleanup: finalization and garbage collection

Finalize 1. finalize is called when garbage collection is done. 2. Finalize can be used to deallocated memory allocated using non-Java Code 3. Can be used to check a terminating condition like dont call garbage collector till file is closed 4. System.gc() increases priority of the garbage collector.

Member initialization
1. Class variables can be left uninitialized (they are automatically initialized) but primitive ones used in methods should always be initialized. 2. If you create an object without initializing reference is created and it is initialized to null. 3. Using uninitialized references causes runtime exceltions 4. Compiler complains about forward referencing if uninitialized things are used in initialization 5. Constructor initialization does not preclude automatic initialization for a class 6. Order of initialization for variables = Order in which they are defined. Variables are initialized even before constructor is called. 7. Static - whenever a static object is declared it is created first before the constructor and before the non static objects. Its created once only when the class is loaded. Static block of code is also executed. Again only once when the class is loaded.

8. Then non static objects are initialised. Initialization code is enclosed in braces without a label and is executed before the constructor.

Array initialization
1. Creation int a1[] 2. Careful with references int a2[]; a2=a1 point to same data on the heap 3. For primitive type array construction can be done using one new. For non primitive type use new's=no of elements in a loop. 4. Varargs

Hiding the Implementation

Package is a collection of classes. Package myPackage Available using import keyword Put all classfiles in one directory structure to form a package. Or add the directory containing packages to be used in the classpath Each .java program is a compilation unit. Each compilation unit can contain only one public class For each class a .class file is made Collision - 2 classes in a program from different packages have the same name. Use the full name package.class You can import a package to change behavior without changing any code

Access Specifiers
Public access Everyone has access.

Package access - All classes in package have access to class members and methods How to provide access to other classes if you want to? Use public or get set methods If nothing is specified the member has package access All classes in the same directory are treated as a default package

Private access - No class except class that contains members and methods has access. Purpose - 1) Insulating class against yourself 2) Hiding implementation from user allowing you to change implementation without the user knowing of it 3)If a method is just a helper method 4)Make constructor private if you want to stop the client from making an object of it. Protected access - Class and derived class have access. Inheriting from another package will give access to protected variables but not to default package ones. Classes can be public or default package makes no sense to have private or protected classes

Reusing Classes
Composition syntax
toString() - Just returns string representation of an object Composition - has a relationship The class holds objects of different classes. It "has" objects of different classes.

Inheritance syntax
Class B has behavior similar to that of Class B extends class A Inheritance can be used to change behavior or add additional behavior To plan for inheritance make all fields private and methods public super() Calls constructor of superclass super.method accesses method of superclass When you create an object of subclass within it it contains an object of the superclass. Therefore it should be initialized correctly. Therefore to do this Java always calls super() before calling any other constructor. If a parameterized constructor exists in superclass you should explicitly call it else compiler will complain

Combining composition and inheritance

For proper clean up use try catch finally Composition - When you want features but not the interface. It is explicit. "Has-a" type of relationship Inheritance - When you want to make a special version of the class. It is implicit. "Is-a" type of relationship.

You can access all methods of superclass using an object of subclass (except private ones) if you upcast it. Class B extends Class A. Every object of Class B is an object of Class A. So you can access class A's methods using A.method if its static or explicit upcast if its non static

The final keyword

Final data values that never change. These are either compile time constants or initialized at runtime. Java allows blank finals. They should just be initialized before use. Therefore the compiler complains if you do not initalize a final in a constructor. Final reference is a constant reference. The data it points to can change but the reference cannot be changed. Final arguments - Methods cannot change what the argument points to. (Cannot changed the reference) Final methods - behavior is retained during inheritance and cannot be overridden. Increase efficiency by inline calls. private methods are implicitly final Final class - It cannot be inherited.

Initialization and class loading

Class is loaded as and when it is needed. When class is loaded first it is initialized (static members, static block and then other members when an object is created)

Polymorphism is basically decoupling of subclasses from the superclass. Polymorphism is late binding. When you have a single method that takes the argument of superclass (forget the derived classes for a moment) Java identifies each object of derived class at runtime and calls its method Method call binding is connecting a method call to the body (code) Java does this at runtime (except for final methods that are inlined) Polymorphism leads to extensibility you can add as many subclasses you want without changing the method taking the superclass argument

Abstract methods and classes

Abstract methods - establish a common interface that has no implementation. Each subclass provides a different implementation

Abstract class contains one or more abstract method. You can have an abstract class that contains no abstract method. An object of abstract class cannot be created. If inherited either all implementations should be provided or inheriting class should be declared abstract.

Constructors and polymorphism

Dont call any polymorphic methods inside constructors

Downcasting and RTTI

Downcasting is difficult because it is difficult to understand if a shape is a circle or traingle. Java checks type everytime you downcast. This is called RTTI. If the class is not correct you get a ClassCastException. Use Object(O).getClass to get class

Interface has no implementation at all. Use - Multiple inheritance

Interface has Name Methods Argument Lists Return Type but no method bodies. All fields in an interface are implicitly static and final. All classes that implement the interface must provide implementation for the methods. Interface is just used to establish a 'protocol' between classes. If a class implements an interface user just knows what methods are present in the class, if he knows the interface. The interface is what is looks like but the class says how it works. Methods from the interface - should be defined as public otherwise they would be package access by default and this would reduce the accessibility of the method during inheritance. Interface has no implementation at all. Implies that it has no storage at all. There is nothing to prevent the interfaces from being combined. Therefore it is used for multiple inheritance. Class A extends B implements C, D, E Concrete class must come first then the interfaces otherwise there is a compiler error. Added protection - User cannot create an object of the interface hence it is better to define a base class as an interface instead of an abstract class. Name collision - This happens when method from a superclass and interface have the same name. Avoid that. Initializing fields in an interface - Fields in an interface are static and final. Therefore they cannot be 'blank finals' but they can be initialized with non constatnt expressions. - Fields are static therefore they are initialized when the class is first loaded.

Nesting interfaces - Interfaces can be nested within a class - Interfaces can be nested within interfacws however private interfaces cannot be nested

Inner Classes Class within a class. Use - when inner class has no meaning without the outer class - Groups classes logically - Controls the visibility of one class within the other. - When upcasting to a base class or interface Referencing inner classes Parcel2.Contents c = q.cont(); Parcel2.Destination d = q.to("Borneo"); Contents and destination are inner classes to Parcel2 Get the whole code in next comment For any non static method of the outer class you must specify OuterClassName.InnerClassName
Returning a reference to an inner class. public class Parcel2 { class Contents { private int i = 11; public int value() { return i; } } class Destination { private String label; Destination(String whereTo) { label = whereTo; } String readLabel() { return label; } } public Destination to(String s) { return new Destination(s); } public Contents cont() { return new Contents(); } public void ship(String dest) { Contents c = cont(); Destination d = to(dest); System.out.println(d.readLabel()); } public static void main(String[] args) { Parcel2 p = new Parcel2(); p.ship("Tanzania"); Parcel2 q = new Parcel2(); // Defining references to inner classes: Parcel2.Contents c = q.cont(); Parcel2.Destination d = q.to("Borneo"); } }

Inner classes modifications 1. inside a method 2. within a scope inside a method

3. anonymous class implementing an interface 4. anonymous class extending a class that has a non default constructor 5. anonymous class that performs field initialization 6. anonymouse class that performs construction using instance initialization

Exception Handling
Exception is a problem that prevents continutation of scope/method. When an exception occurs control jumps out of the current context and is relegated to a higher context.

Flow of exception.
When an exception is thrown 1. Exception object is created 2. Current path of execution is stopped 3. Reference for the exception object is ejected from the current context. 4. Exception Handling mechanism takes over and looks for an appropriate place to continue executing the program. 5. Generally the appropriate place to continue execution is exception handler whose job is to recover from the problem so the program can try another track or just continue.

Throwing an exception
if(t==null) throw new NullPointerException();

All exceptions have two constructors.

One, default constructor Two, Constructor that takes a string argument. The string can be later extracted using methods

Keyword 'throw'
new creates an object of type exception and gives the resulting reference to throw.

Keyword 'Throwable'
You can throw any type of Throwable object Typically you throw a different class of exception for each different type of error.

Guarded region - Code that might produce exceptions If you dont want a throw to exit a method you should try a try catch block

try { Code that generates exceptions } catch (Type1 Id) { Handle exceptions of type1 } catch (Type2 Id) { Handle exceptions of type 2 } etc

Exception Handling is done by the catch block. The catch blocks should immediately follow the try. If an exception is thrown the exception handling mechanism goes hunting for the first handler with an argument that matches the type of the exception.

In a try if different methods generate same exception only one handler is required.

Two approaches to exception handling 1. Termination (C++, Java approach) 2. Resumption (Put try block inside a while block)

Creating your own exceptions

Creating an exception class SimpleException extends Exception {} Throwing an exception throw new SimpleException() Result of the exception is printed to the console standard error stream by writing to System.err printStackTrace() produces information about the sequence of methods that were called to get to the point where the exception happened. Code from slides

public class GPTreeChildPositionException extends Exception { } public abstract class Node{ public abstract void setChild(int position, Node n) throws GPTreeChildPositionException { : } public abstract class Binop extends Node { public void setChild(int position, Node n) throws GPTreeChildPositionException {//We throw exception in setChild therefore we should let compiler and user know that this method throws an exception. Hence the throws GPTreeChildPositionException. We have to do this in the abstract super class as well otherwise compiler gives an error. if (position == 1) lChild = n; else if (position == 2) rChild = n; else throw new GPTreeChildPositionException(); } : }

Exception specification use keyword throws after a method with a list of all the exceptions that it can throw. If code within your method throws an exception you should either 1. Handle the exception OR 2. Indicate with an exception specification that it may be thrown from method. Exceptions from abstract classes and interfaces should also be handled. Exceptions that are checked and enforced at compile time are called checked exceptions. Catching any exception catch(Exception e)

Rethrowing an exception
Rethrowing an exception causes the exception to go to the next higher context that catches the specific exception type that can extract all the information from that object. If you rethrow an exception printStackTrace about the exception will pertain to the exception's origin and not the place where you rethrow it.

Exception Chaining You can chain three exception classes Error, Exception and RuntimeException.

A class that extends Exception can throw a specific exception. For example, getFieldNumber (String id) throws NoSuchFieldException. In the catch block for this exception, we can do exception chaining and throw a new RuntimeException(e)

The same effect can be achieved with initCause(new NullPounterException())

Standard Java Exceptions

Error - compile time and system errors Exception - basic type that can be thrown from any of the standard Java Library class methods and from your methods and run-time accidents. Exceptions are in libraries .lang, .util, .net and .io RuntimeException - RuntimeExceptions are unchecked exceptions. RuntimeExceptions represent 1. An error you cannot anticipate 2. An error you should have checked in code. Whenever a RuntimeException occurs the printStackTrace is automatically called for it.

Finally Finally holds code that you want to be executed inspite of the exceptions. try () catch (A a1) {} finally {}

Whether or not exception is thrown finally clause is always executed. Finally is necessary for cleanup like an open file or network connection or erasing something you've drawn on the screen. If something in a finally block throws an exception the exceptions thrown by try are lost.

Exception Restrictions When you override a method you can throw only the exceptions that have been specified in the baseclass version of the method. The fclose() Problem

Exception matching

Exception is caught by the first class that matches it. Put base class last and the dervied classes first.

Need for collections - You dont know how many objects or what type of objects you need. - you need to be able to create any number of objects anytime, anywhere. -Answer - Container Classes.

Arrays Advantages of Arrays to hold objects Efficiency - Simple linear sequence. Therefore element access is fast. - (Downside) Size is fixed and cannot be changed at runtine. -(Work Around) Create an array of particular size, then if you run out of space create a new one and move all references from old one to new one. This is the behavior of the ArrayList class. Type Checking Can hold objects of only one type. Compile time type checking

Generic Container Classes ArrayList List Set Map

They treat objects as Object. (Advantage) Only one container and all objects go into that container. (Downside) No compile time type checking

Array of Objects Weeble[] a; null reference to array Weeble[] b= new Weeble[5]; array of null references to objects Weeble[] c=new Weeble[4]; for (..) {c[i]=new Weeble();} Aggregate initialization a=new Weeble[] {new Weeble(), new Weeble()}; //Dynamic initialization

Note - You get a compile error if you use array name.length on a primitive type without initializaing it. But it works fine on an array of objects. a is null reference and compiler prevents it from doing anything until its initialized. b is initialized to point to array of null references. But b.length works. (Drawback) we cannot find how many objects are actually there.

You cannot directly place primitive values inside Container you have to use wrapping. Returning an array Returning an array is just like returning any other object, it returns a reference.

Arrays Class
java.util holds a set of static methods Four basic methods equals() - compares two methods for equality fill()-fills an array with a value sort() - Sorts the array binarySearch()-find an element in a sorted array.

These methods are overloaded for all primitive types and Objects. asList() takes any array and turns it into a List container. Arrays.fill() Takes a single value and puts it in each location in the array. System.arraycopy() - makes a copy of the array. System.arraycopy(source array, offset into source array, destination array, offest into destination array, numberofelements) System. arraycopy() makes a shallow copy.

Arrays.equals() Arrays must have same number of elements and each element must be equivalent to each corresponding element in the other array using equals for each element.


Java has two ways to provide comparison functionality. "Natural" Comparison imparted by Comparable interface. Uses compareTo() method.

Arrays.sort() - Sorts the array. - Can sort any array that implements Comparable or has an associated Comparator. - Gives an array if class does not implement Comparable. You can overwrite compareTo() if you want a different behavior. - Arrays.sort(arrayname) natural ordering on Comparable interface. - Arrays.sort(arrayname, comparator object) using Comparator interface.

Arrays.binarySearch() - fast searching a sorted array. - Arrays.binarySearch(Collection, key to be found) if key found returns the position, if not -ve value representing where the key should be inserted. - (Drawback) Duplicate elements. No guarantee which one will be found. - If the array was sorted using a Comparator, mention the comparator as an argument. - Arrays.binarySearch(arrayname,key,comparator)

Container Library
is divided into two parts Collection - List of individual elemets. - List - holds elements in a particular sequence. (order of insertion) - Set - cannot hold duplicate elements, (uses its order) Map - key-value pairs. Printing collections - System.out.println(m); - m=collection object Adding an item to a collection - add(Object) Adding an item to a Map - put(key, value) Collection is printed as - [a1, a2, ....] Map is printed as - {key=value, key=value,.....} fill() is useless

- puts the same value in every elemetnt. - Cannot add new elements, only replaces existing ones Container disadvantage Unknown type - Container holds references to Object, to become a general purpose tool. - No restriction on the type of Object that can be put in the container (No Type Checking) - Since type information is lost the container only holds a reference to an object. It must be type casted to the correct type before you use it. Exception where it works When compiler expects a String object and does not get one it calls the toString() method for the object it has. Solution - Making a type conscious ArrayList

is an object whose job its to move through a sequence of objects and select each object without caring about the underlying type.

How it works Ask container to hand you an iterator. Iterator i=container.iterator() Get next object in sequence with iter.next() See if there are any more next objects using iter.hasNext() Remove the last element returned by the iterator with remove()

Collection functionality add(Object) addAll(Collection) clear() contains(Object) - if Collection contains object containsAll(collection) isEmplty() iterator()

remove(Object) removeAll(Collection) retainAll(Collection) size() toArray()

List functionality List ArrayList LinkedList

Set(interface) - no guarantee that order of elements will be preserved. HashSet TreeSet LinkedHashSet

SortedSet - elements are guaranteed to be in a particular order.

Map Functionality put(Object key, Object value) containsKey(key) containsValue(Value)

HashMap speeds up the search using hashCode() method printKeys() printValues() keySet() procues a key Set

SortedMap (TreeMap) Comparator comparator() - returns the comparator Object firstKey() Object lastKey() SortedMap subMap(fromKey, toKey) SortedMap headMap(toKey) SortedMap tailMap(fromKey)

HashMap performance factors Capacity = number of buckets in the table Initial Capacity - Number of buckest when table is created Size - The number of entries currently in the table Load factor=size/capacity Homework Code

Map<Character,Integer> charCounter = new HashMap<Character,Integer>(); //Declaring a hash map that has character keys and integer values if (charCounter.containsKey(chr)) //if key already exists in the map increment count charCounter.put(chr,charCounter.get(chr)+1); else //if key does not exist add the key charCounter.put(chr,1);