Monday, 8 June 2015

Java Other modifiers for interface members

Other modifiers for data members

Besides the visibility modifier public, we can also use modifiers static and final. Although we can use these modifiers but it is redundant as all data members are implicitly public, static and final.

Other modifiers for methods

Besides the visibility modifier public, we can also use modifier abstract. Although we can use abstract modifier but it is redundant as all methods are implicitly public, and abstract.

Java Other modifiers for top-level interfaces

(a) abstract

This is the only modifier other than visibility modifiers, which can be used with interface.

Interfaces just specify the method prototypes and not any implementation: they are, by their nature, implicitly abstract (i.e. they cannot be instantiated). We can declare an interface as abstract but it is redundant as interface is always abstract.

Java Other modifiers for top-level classes

Besides visibility modifiers, we can also use following modifiers before a top-class:

(a) abstract, and (b) final

(a) abstract

A class can be specified with the keyword abstract to indicate that it cannot be instantiated. A class containing abstract method must be declared as abstract otherwise it won’t compile. A class not containing any abstract method can also be declared abstract. Such a class can serve as a base class for a number of sub-classes.

(b) final

A class can be declared final to indicate that it cannot be extended. The final class marks the lower boundary of its implementation inheritance hierarchy. Only a class whose definition is complete can be declared final. A class cannot be both final and abstract at the same time.

Here are few important characteristics of the final class.

  • All the methods of a final class are also final i.e. they have the concrete implementation and cannot be over-ridden.
  • Some type checks become faster with final classes. In fact, many type checks become compile time checks and errors can be caught earlier. If the compiler encounters a reference to a final class, it knows that the object referred to is exactly of that type.

  • The compiler is able to perform certain code optimizations for final methods, because certain assumptions can be made about such members. When a non-final method is invoked, the run time system determines the actual class of the object, binds the method invocation to the correct implementation of the method for that type, and then invokes the implementation. In case of a final method we are sure that sub-class cannot override the method so the binding is done at the compile time as in case of private and static methods, which would definitely improve the performance.

  • In case of a final method the compiler may replace an invocation with the actual body of the method like Macro. This mechanism is known as ‘inlining’. In C++, we have the option of declaring a function as inline (although final decision is taken by the compiler) but in Java, the compiler takes the decision.

Java Member accessibility/visibility modifiers for interfaces

The only member accessibility/visibility modifier that can be used with data members and methods of an interface is public

The public is also the implicit accessibility/visibility modifier for interface members i.e. the members are always implicitly assumed to be public even if we do not use the modifier public.

Java Member accessibility/visibility modifiers for classes

By specifying member accessibility modifiers a class can control what information is accessible to clients (i.e. other classes). These modifiers help a class to define a contract so that clients know exactly what services are offered by the class.

Accessibility/visibility of members can be one of the following:

  • public
  • protected
  • default (also called package accessibility)
  • private

Note: Member accessibility modifier only has meaning if the class (or one of its subclasses) is accessible to the client. Also note that only one accessibility modifier can be specified for a member. The discussion applies to both instance and static members of classes.

Java Accessibility modifiers for Top-level classes and interfaces

  • public
  • default (package) accessibility

Sunday, 7 June 2015

Java Modifiers

Introduction

Modifiers are Java keywords that give the compiler information about the nature of code, data, classes or interfaces. For example, we have been using visibility modifiers public, private, protected, package etc. to specify the visibility of class members.  Beside visibility we have also used the modifiers static and abstract.

Classification

  • For the purpose of clear understanding, modifiers can be categorized as:
  • Accessibility modifiers for top-level classes and interfaces.
  • Member accessibility/visibility modifiers for classes.
  • Member accessibility/visibility modifiers for interfaces.
  • Other modifiers for top-level classes.
  • Other modifiers for top-level interfaces.
  • Other modifiers for interface members.
  • Other modifiers for class members.

Java Creating user-defined Exception/Error sub-classes

This is quite easy to do, just define a sub class of Exception/Error class. Your sub-classes do not need to actually implement anything. It is their existence in the type system that allows you to use them as exceptions/errors. The Exception/Error class does not define any methods of its own.

It does, of course, inherit methods provided by Thorwable class.

Extending RunTimeException or any of its sub-classes will create a user-defined unchecked-exception and extending Exception and any other sub-class of exception will create a user-defined checked-exception.  

Example: The following example demonstrates the use of a user-defined checked-exception.

class InvalidMarksException extends Exception

{ InvalidMarksException(String msg)

{ super(msg);

}

}

class MyExceptionDemo

{ static void dispGrade(int marks) throws InvalidMarksException

{ if(marks < 0 || marks > 100)

throw new InvalidMarksException

if(marks >= 75) System.out.println("S");

else if(marks >= 60) System.out.println("A");

else if(marks >= 50) System.out.println("B");

else if(marks >= 33) System.out.println("C");

else System.out.println("F");

("Marks should be in the range 0 to 100");

}

public static void main(String args[])

{ try

{ int marks = Integer.parseInt(args[0]);

dispGrade(marks);

}

catch(InvalidMarksException e)

{ System.out.println(e);

}

}

}


Example: The following example is rewritten here so as to display the marks entered as command line argument along with the error message.

class InvalidMarksException extends Exception

{ int marks;

InvalidMarksException(int marks, String msg)

{ super(msg);

}

public String toString()

{

}

}

class MyExceptionDemo1

{ static void dispGrade(int marks) throws InvalidMarksException

{ if(marks < 0 || marks > 100)

this.marks = marks;

return("InvalidMarksException["+marks+"]:"+getMessage());

throw new InvalidMarksException

if(marks >= 75) System.out.println("S");

else if(marks >= 60) System.out.println("A");

else if(marks >= 50) System.out.println("B");

else if(marks >= 33) System.out.println("C");

else System.out.println("F");

(marks, "Marks should be in the range 0 to 100");

}

public static void main(String args[])

{ try

{ int marks = Integer.parseInt(args[0]);

dispGrade(marks);

}

catch(InvalidMarksException e)

{ System.out.println(e);

}

}

}

Chained Exceptions

The chained exception feature allows you to associate another exception with an exception. This second exception describes the cause of the first exception. For example, imagine a situation in which a method throws an ArithmeticException because of an attempt to divide by zero.

However, the actual cause of the problem was that an I/O error occurred, which caused the divisor to be set improperly.

Although the method must certainly throw an ArithmeticException, since that is the error that occurred. You might also want to let the calling code know that the underlying cause was an I/O error.

To allow chained exceptions, Java 2, version 1.4 added two constructors and two methods to Throwable class. The constructors are shown here:

Throwable(Throwable causeExc)

Throwable(String msg, Throwable causeExc)

In the first form, causeExc is the exception that causes the current exception. That is, causeExc is the underlying reason that an exception occurred. The second form allows you to specify a description at the same time that you specify a cause exception. These two constructors have also been added to the Error, Exception, and RuntimeException classes.

The chained exception methods added to Throwable class are getCause() and init Cause():

Throwable getCause()

Throwable initCause(Throwable causeExc)

The getCause() method return the exception that underlies the current exception. If there is no underlying exception, null is returned. The initCause() method associates causeExc with the invoking exception and returns a reference to the exception. Thus, you can associate a cause with an exception after the exception has been created. However, the cause exception can be set only once. Thus, you can call initCause() only once for each exception object. Furthermore, if the
cause exception was set by a constructor, then you cannot set it again using initCause() method.

In general, initCause() is used to set a cause for legacy exception classes which do not support the two additional constructors described earlier. Most of Java's built-in exceptions do not define the additional constructors. Thus, you will use initCause() if you need to add an exception chain to these exceptions.

Chained exceptions are not something that every program will need. However, in chases in which knowledge of an underlying cause is useful, they offer an elegant solution.

Example:

class ChainExecDemo

{

static void demoproc()

{

NullPointerException e = new NullPointerException("top layer");

e.initCause(new ArithmeticException("Cause"));

throw e;

}

public static void main(String agrs[])

{

char a = 'a';

try

{

demoproc();

}

catch(NullPointerException e)

{

System.out.println(a);

System.out.println(e);

System.out.println("Original Cause : " +e.getCause());

}

}

}

Output:


Note: The NullPointerException constructor is not overloaded to receive cause so the only way to associate cause with it is to make use of initCause() method.

Java finally clause

finally creates a block of code that will be executed after a try/catch block has completed and before the code following the try/catch block.

The finally block will execute whether or not exception is thrown. If an exception is thrown, the finally block will execute even if no catch statement matches the exception.

Any time a method is about to return to the caller from inside a try/catch block, via an uncaught exception or an explicit return statement, the finally clause is also executed just before the method returns. This can be useful for closing file handlers and freeing up any other resources that might have been allocated at the beginning of a method with the intent of disposing of them before returning.

The finally clause is optional. However, each try statement requires at least one catch or a finally clause.

Example:

class FinallyDemo

{ static void procA()

{ try

{ System.out.println("inside procA()");

throw new RuntimeException("Demo");

}

finally

{ System.out.println("procA()'s finally"); }

}

static int procB()

{ try

{ System.out.println("inside procB()");

return(5);

}

finally

{ System.out.println("procB()'s finally"); return(10);

}

}

static void procC()

{ try

{ System.out.println("inside procC()"); }

finally

{ System.out.println("procC()'s finally"); }

}

public static void main(String args[])

{ try

{ procA(); }

catch(Exception e)

{ System.out.println("! Exception caught:"+e); }

int x = procB();

System.out.println("x= "+x);

procC();

}

}

Output:

inside procA()

procA()'s finally

! Exception caught:java.lang.RuntimeException: Demo

inside procB()

procB()'s finally

x= 10

inside procC()
procC()'s finally

Java throw statement

Example: Normally built-in exceptions are thrown by the JVM but user can also create and throw any exception although this is normally not done. The throw statement is needed for throwing user-defined exceptions, which is discussed in a later section.

The following program creates and throws an exception

class ThrowDemo {

static void demoproc() {

try {

int c = 0, a = 0;

if (a == 0)

int b = c / a;

} catch (ArithmeticException e) {

System.out.println("Caught inside demporoc.");

throw e;

}

throw new ArithmeticException("Division by zero");

}

public static void main(String args[]) {

try {

demoproc();

} catch (ArithmeticException e) {

System.out.println("Recaught: " + e);

}

}

}

Output:

Caught inside demporoc.

Recaught: java.lang.ArithmeticException: Division by zero

Example: The following example demonstrates that if a checked-exception is thrown using throw statement then it must either be caught or declared in the throws clause.

import java.io.*;

class ThrowsDemo {

static void throwOne() throws IOException {

System.out.println("inside throwOne");

throw new IOException("Demo");

}

public static void main(String args[]) {

}

}

Output: above program will not compile and result in following compile time error.

throwOne();


Example: The above example is re-written such that the method throwOne() is called in a try block.

import java.io.*;

class ThrowsDemo

{ static void throwOne() throws IOException

{ System.out.println("inside throwOne");

}

public static void main(String args[])

{ try

throw new IOException("Demo");

{ throwOne();

}

catch(IOException e)

{ e.printStackTrace();

}

}

}

Output: results in an exception at run-time.


Friday, 5 June 2015

Java Handling Checked Exceptions

Example: This program also handles the Checked Exceptions. The following program takes names of two files as input and copies the file specified by the first argument to the file specified by the second argument. The number of bytes copied are displayed in the finally block. So number of bytes copied will be displayed even if some abnormal condition terminates the program. The files are also closed in the finally block so that they will always be closed.

It has three handlers to handle the abnormal conditions:

  • One handler will print the usage of the program when the user does not provide both input and output file names.
  • The next handler will notify the user when the input file does not exist.
  • Another handler will print an error message when other I/O exceptions occur.
import java.io.*;

class MyCopy

{ public static void main(String args[])

{ int byte_count = 0;

byte buffer[] = new byte[512];

String input_file = null;

String output_file = null;

FileInputStream fin = null;

FileOutputStream fout = null;

try

{ input_file  = args[0];

output_file = args[1];

fin  = new FileInputStream(input_file);

fout = new FileOutputStream(output_file);

int bytes_in_one_read;

while((bytes_in_one_read = fin.read(buffer)) != -1)

{ fout.write(buffer,0,bytes_in_one_read);

}

}

catch(ArrayIndexOutOfBoundsException e)

{ System.out.println("Use:java MyCopy source target");

}

catch(FileNotFoundException e)//Checked Exception

{ System.out.println("Can't open input file:"+input_file);

}

byte_count = byte_count + bytes_in_one_read;

catch(IOException e) //Checked Exception

{ System.out.println("I/O Exception occurs");

}

finally

{ if(byte_count > 0)

if(fin != null)

if(fout != null)

}

System.out.println(byte_count + " bytes written");

fin.close();

fout.close();

} // end main

} // end class

Note:

1. FileNotFoundException and IOException are checked exceptions and must be handled.

2. It is possible that we handle only IOException as this will also indirectly handle the FileNotFoundException, which is its sub-class.

3. If both IOException and FileNotFoundException are handled then FileNotFoundException must be caught before IOException as it is sub-class of IOException.

Example: The previous example is rewritten to use method:

int copyFile(String input-file, String output-file)

We want that caller of this method should handle the abnormal conditions by itself. Method will not have any error handler for I/O Exception. A throws clause is added to the method declaration to indicate that method can throw exception and caller has to handle this exception. The caller can also throw the exception if it does not want to handle itself.

import java.io.*;

class MyCopy1

{ static FileInputStream fin = null;

static FileOutputStream fout = null;

public static int CopyFile(String input_file, String output_file)

{ int byte_count = 0;

throws IOException, FileNotFoundException

 fout = new FileOutputStream(output_file);

int bytes_in_one_read;

byte buffer[] = new byte[512];

fin  = new FileInputStream(input_file);

while((bytes_in_one_read = fin.read(buffer)) != -1)

{ fout.write(buffer,0,bytes_in_one_read);

byte_count = byte_count + bytes_in_one_read;

import java.io.*;

class MyCopy1

{ static FileInputStream fin = null;

static FileOutputStream fout = null;

public static int CopyFile(String input_file, String output_file)

{ int byte_count = 0;

throws IOException, FileNotFoundException

 fout = new FileOutputStream(output_file);

int bytes_in_one_read;

byte buffer[] = new byte[512];

fin  = new FileInputStream(input_file);

while((bytes_in_one_read = fin.read(buffer)) != -1)

{ fout.write(buffer,0,bytes_in_one_read);

byte_count = byte_count + bytes_in_one_read;

{ int a = args.length;

int b = 42/a;

System.out.println("a = " + a);

try

{ if(a == 1)

a = a/(a-a);

if(a == 2)

{

int c[] = {1};

c[42] = 99;

}

}

catch(ArrayIndexOutOfBoundsException e)

{ System.out.println("Array index out-of-bounds:"+e);

}

System.out.println("Outer Try");

}

catch(ArithmeticException e)

{ System.out.println(e);

}

System.out.println("After Outer Try");

}

}

Note: Nesting of try statement can occur in less obvious ways when method calls are involved.

For example, you can enclose a call to a method within a try block. Inside that method is another try statement. In this case, the try within the method is still nested inside the outer try block, which calls the method.

Example: Previous program is re-written so that the nested try block is moved inside the method nesttry().

class NestTry1

{ static void nesttry(int a)

{ try

{ if(a == 1)

if(a == 2)

{ int c[] = {1};

}

}

catch(ArrayIndexOutOfBoundsException e)

{

System.out.println("Array index out-of-bounds:" + e);

}

a = a/(a-a);

c[42] = 99;

}

public static void main(String args[])

{ try

{ int a = args.length;

int b = 42/a;

System.out.println("a = " + a);

nesttry(a);

}

catch(ArithmeticException e)

{

System.out.println(e);

}

}

}


Java Exception Handling Example

Example: This example demonstrates the action taken by the default error/exception handler when an exception/error occurs and is not handled.

class Exc0

{ public static void main(String args[])

{ int d = 0;

int a = 42/d;

System.out.println("This will not be printed");

}

}

When the Java run-time system detects the attempt to divide by zero, it constructs a new exception object and then throws this exception. This causes the execution of Exc0 class to stop,

because once an exception has been thrown, it must be caught by an exception handler and dealt with immediately.

In this example, we have not supplied any exception handlers of our own, so the default handler provided by the Java run-time system catches the exception. The default handler displays a string describing the exception, prints a stack trace from the point at which the exception occurred, and terminates the program.

Here is the output generated when this example is executed:

Exception in thread "main" java.lang.ArithmeticException: / by zero at Exc0.main(Exc0.java:4)

Example: This example demonstrates the action taken by the default error/exception handler when an exception/error occurs in a method other then main() and is not handled.

class Exc1

{ public static void subroutine()

{ int d = 0;

int a = 42/d;

}

public static void main(String args[])

{ Exc1.subroutine();

}

Output:

Exception in thread "main" java.lang.ArithmeticException: / by zero at Exc1.subroutine(Exc1.java:4) at Exc1.main(Exc1.java:7)

The resulting stack trace from the default exception handler shows how the entire call stack is displayed

System.out.println("This will not be printed");

Using try and catch

Although the default exception handler provided by the Java run-time system is useful for debugging, you will usually want to handle an exception yourself. Doing so provides two

benefits:

  • First, it allows you to fix the error
  • It prevents the program from automatically terminating

Example:

class Exc2

{ public static void main(String args[])

{ int d,a;

try

{ d = 0;

a = 42/d;

System.out.println("This will not be printed");

}

catch(ArithmeticException e)

{ //e.printStackTrace();

//System.out.println(e);

System.out.println(e.getMessage());

}

System.out.println("After catch statement");

}

}

Output

/ by zero
After catch statement

Note: The scope of the catch clause is restricted to those statements specified by the immediately preceding try statement. A catch statement can not catch an exception thrown by another try statement (except in the case of nested try statements). The statements that are protected by try must be surrounded by curly braces.

Example: This example demonstrates that we can continue execution after handling the exception and can execute the code of same try block again if it is part of a loop.

Recovery.java

import java.util.Random;

class HandleError

{

public static void main(String args[])

{

int a=0, b=0, c=0;

Random r = new Random();

for(int i=0; i < 5; i++)

{

try

{

b = r.nextInt();

c = r.nextInt();

System.out.println(b);

System.out.println(c);

a = 12345/ (b/c);

}catch(AirthmeticException e)

{ System.out.println(e.getMessage());

}

System.out.println("a : " + a);

}

a = 0;

}

}

Example:  The following example demonstrates the use of multiple catch clauses.

class MultiCatch

{ public static void main(String args[])

{ try

{ int a=args.length;

System.out.println("a = " + a);

int b = 42/a;

int c[] = {1};

c[42] = 99;

}

catch(ArithmeticException e)

{ System.out.println("Divide by 0: " + e);

}

catch(ArrayIndexOutOfBoundsException e)

{ System.out.println("Array Index Out Of Bound: " + e);

}

System.out.println("After try/catch blocks.");

}

}

Example: The following example throws four types of Runtime Exceptions:

  • ArithmeticException: integer division by zero.
  • NullPointerException: for accessing a field or invoking a method of a ‘null’ object.
  • ArrayIndexOutOfBoundsException: for accessing an array element by providing an index value less than zero or greater than or equal to array size.
  • StringIndexOutOfBoundsException: for accessing a character of a String or StringBuffer with index less than zero or greater than or equal to length of String.

class ExceptionTest

{ public static void main(String args[])

{ for(int i=0; i<4; i++)

{ int k = 0;

try

{ switch(i)

{ case 0: int zero = 0;

case 1: int b[] = null;

case 2: int[] c = new int[2];

case 3: char ch = "abc".charAt(3);

}

k = 911/zero;

break;

k = b[0];

break;

k = c[9];

break;

break;

}

catch (Exception e)

{ System.out.println(e);

}

}

}

}

Output:

java.lang.ArithmeticException: / by zero
java.lang.NullPointerException
java.lang.ArrayIndexOutOfBoundsException: 9
java.lang.StringIndexOutOfBoundsException: String index out of range: 3

Note: In the above example all the exceptions are handled using only one catch block. This is possible because all the exceptions are sub-classes of the Exception class.

Example: The previous example is slightly modified so that all the exceptions are handled separately. This approach allows us to take separate actions for each exception.

class ExceptionTest1

{ public static void main(String args[])

{ for(int i=0; i<4; i++)

{ int k = 0;

try

{ switch(i)

{ case 0: int zero = 0;

case 1: int b[] = null;

case 2: int[] c = new int[2];

case 3: char ch = "abc".charAt(3);

}

k = 911/zero;

break;

k = b[0];

break;

k = c[9];

break;

break;

}catch (ArithmeticException e)

{ System.out.println(e); }

catch (NullPointerException e)

{ System.out.println(e); }

catch (ArrayIndexOutOfBoundsException e)

{ System.out.println(e); }

catch (StringIndexOutOfBoundsException e)

{ System.out.println(e); }

}

}

}

Output:

java.lang.ArithmeticException: / by zero
java.lang.NullPointerException
java.lang.ArrayIndexOutOfBoundsException: 9
java.lang.StringIndexOutOfBoundsException: String index out of range: 3

Example: In case of multiple catches, exception subclasses must come before any of their super classes. This is because a catch statement that uses a super class will catch exceptions of that type plus any of its sub classes. Thus, a sub class would never be reached if it comes after its super class. Further, in java unreachable code is an error.

class ExceptionTest2

{ public static void main(String args[])

{ for(int i=0; i<4; i++)

{ int k = 0;

try

{ switch(i)

{ case 0: int zero = 0;

case 1: int b[] = null;

case 2: int[] c = new int[2];

case 3: char ch = "abc".charAt(3);

}

k = 911/zero;

break;

k = b[0];

break;

k = c[9];

break;

break;

}

catch (Exception e) //Will not compile

{ System.out.println(e);

}

catch (ArithmeticException e)

{ System.out.println(e);

}

}

}

}

Output:

ExceptionTest2.java:23: exception java.lang.ArithmeticException has already been caught

catch (ArithmeticException e)


Java Exception - throw Statement

It is possible for your program to throw an exception/error explicitly, using the throw statement.

The general form of throw is shown here:

throw ThrowableInstance;

Here, ThrowableInstance must be an object of type Throwable or a sub-class of Throwable.

Simple types, such as int or char as well as non-Throwable classes, such as String and Object, cannot be used as exceptions.

There are two ways you can obtain a Throwable object:
  • Using a parameter into a catch clause.
  • Creating one with the new operator.

Java Exception - throws clause

If a method is capable of causing an exception that it does not handle, it must specify this behavior so that callers of the method can guard themselves against that exception. You do this by including a throws clause in the method’s declaration.

A throws clause lists the types of exception that a method might throw.

This is necessary for all exceptions, except those of type Error or RuntimeException, or any of their subclasses. All other exceptions that a method can throw must be declared in the throws clause. If they are not, a compile-time error will result.

General form of method declaration that includes a throws clause is:

modifiers return-type method-name(parameter-list) throws Exception-list

{

//body of method

}

Here exception-list is a comma-separated list of exceptions that a method can throw.

Java Methods available in Throwable class


Java types of Exception

Exceptions can be categorized in two types:

  • Unchecked Exception
  • Checked Exception

Checked Exception

If it is must to check an exception then it is called a checked exception. The program will not compile if there is a possibility of occurring checked exception in a try block and it is not handled.

The compiler ensures that if a method can throw a checked exception, directly or indirectly, then the method must explicitly deal with it. The method must either catch the exception and take the appropriate action, or pass the exception on to its caller.

Note:
Exception and all of its sub-classes (Excluding RuntimeException and its sub-classes) are checked exceptions and must be caught.

Unchecked Exception

If it is not must to check an exception then it is called an unchecked exception. The program will compile even if the unchecked exception is not handled.

If any unchecked exception occurs in a program which is not handled then the program execution will terminate at that point. But if exception is handled then program will not terminate because of exception.

Note:
  • Error and all of its subclasses are unchecked exceptions and need not be caught.
  • RunTimeException and all of its sub-classes are unchecked exceptions and need not be caught.

Java Exception Handling Construct

Java exception/error handling is managed via five keywords: try, catch, throw, throws, and finally.

The general form of an exception-handling block is:

try

{

//block of code to be monitored for errors.

}

catch(ExceptionType1 exOb1)

{

//exception handler for ExceptionType1

}

catch(ExceptionType2 exOb2)

{

//exception handler for ExceptionType1

}

.

.

.

finally

{

//block of code to be executed before try block ends

}

The code, which is to be monitored for run-time errors, is put inside a try block. The try block must be enclosed between braces even if there is only one statement in it. There can be zero or more catch statements and zero or one finally statement. Both catch and finally blocks are optional but either one catch block or one finally block is must.

The code in the try block is executed like any other Java code. If the code inside the try block executes successfully then the control goes to finally block if it is present and then the execution continues from the statement just after the end of finally block (i.e. after the end of try statement). If the finally block is not present then the execution continues from the statement just after the last catch block (i.e. after the end of try statement).

If some run-time error occurs while executing the code in try block then JVM throws an Exception/Error. This means an object of type Exception/Error or one of its sub-classes is created depending on the type of the run-time error. This is then compared with the Exception/Error types of the catch blocks in top to bottom order. If a matching catch block is found then the exception/error is handled i.e. program will not terminate. The execution continues with the first statement in the catch block. On completion of the catch block, excution continues with the statement just after the end of try statement. At the most one catch block is executed irrespective of the number of catch blocks. On completion of the catch block, excution continues with the statement just after the end of try statement. At the most one catch block is executed irrespective of the number of catch blocks.

If exception/error does not match with exception/error type of any of the catch blocks, then we say that it is not handled. The execution will immediately return from try block. The code in the finally block will be executed even if the exception/error is not handled. The exception/error will then be handled by outer try block if there is one otherwise it must be handled in the method which called the current method. The exception/error percolates up the hierarchy till it is handled or it is passed to JVM unhandled if not handled even in the main() method which is the first method from which the execution starts. The JVM then simply terminates the program and displays the exception/error details on the monitor/console.



Java Hierarchy of Exception Classes

  • Exceptions/Errors are also objects in Java.
  • Root class of all exception/error classes is the Throwable class, which is an immediate sub-class of the Object class.
  • Methods are defined in Throwable class to retrieve error message associated with the error/exception and to print the stack trace showing where the error/exception occurs.
  • There are two immediate sub classes of class Throwable:
            o Error
            o Exception
  • Sub classes of Exception have the suffix Exception.
  • Sub classes of Error have the suffix Error (normally).

Error

The sub classes of Error class are basically used for signaling abnormal system conditions like:
  • OutOfMemoryError signals that the Java VM has run out of memory and that the garbage collector is unable to claim any free memory.
  • StackOverflowError signals a stack overflow in the interpreter.

The errors are, in general, unrecoverable and should not be handled.

Exception

The sub classes of Exception class are, in general recoverable. For example, EOFException signals that a file you have opened has no more data for reading. FileNotFoundException signals that a file you want to open does not exist in the file system.

Hierarchy of common Exceptions




Java Exception Handling

An exception/error is an abnormal condition that breaks/disrupts the normal program flow. The abnormal condition occurs at run-time i.e. during code execution.

For example, a C program gets terminated when division by zero is encountered at the run-time as this is not a defined operation and results in run-time error. The other familiar example in case of C-language is that of null pointer exception, which occurs when we try to access a memory location through an un-initialized pointer. The program gets terminated in this case also.

Java has a separate construct for exception/error handling like C++. It is possible to recover from an exception/error at run-time and continue the program execution using the exception-handling construct.

A Java exception/error is an object of class Exception/Error or one of its sub-classes. JVM creates an object of class Exception/Error or one of their sub-classes whenever exception/error occurs at the run-time. The exception/error object contains details about the exception/error, which can be accessed using the public methods provided for this purpose.

Traditional Approach of Exception/Error Handling:

Use of if(), goto and return codes for propagating error back to calling method.

Advantage of Exception/Error Handling

  • Error-handling code is separated from the normal program flow to increase the

    readability and maintainability.

    We can easily say where the exception/error will be handled. Exceptions/Errors
    propagate up the call stack at runtime- first up the enclosing try blocks and then back to the calling method- until an exception handler catches them.
     
  • The location of the exception/error is known exactly as entire stack trace is available to the user. This is very helpful in debugging.
     
  • Programmer gets a chance to recover from the error/abnormal condition.
     
  • With Java, it is not must to test if an exception/error condition happens. Adding more error/exception handlers simply requires adding more catch clauses, but the original program flow need not be touched.

When Exceptions/Errors can occur?

There are many cases where abnormal conditions occur during program execution, such as:

  • The class file you want to load may be missing or in the wrong format.
  • Integer division by zero.
  • Array index is not in the valid range (i.e. from 0 to length-1).
  • The file you are trying to open may not exist.
  • The String, which you want to convert to a number, is having invalid characters so that it cannot be converted to a number.
  • You want to create an object but no more memory is available.

Java Interface Examples

Example: This example is covered when discussing abstract classes. The example is modified such that instead of declaring Shape class as an abstract class it is declared as an interface. We cannot have any implementation in the Shape interface. The interface declares two methods, which must be implemented by all sub-classes of this interface. This would duplicate the code of
method calCost() in all the implementing classes.

interface Shape

{

double puCost = 100;

double area();

double calCost();

}

class Triangle implements Shape

{

double s1,s2,s3;

Triangle(double a, double b, double c)

{

}

public double calCost()

{

}

public double area()

{

s1 = a; s2 = b; s3 = c;

return puCost * area();

double s = (s1+s2+s3)/2;

return Math.sqrt(s*(s-s1)*(s-s2)*(s-s3));

}

}

class Rectangle implements Shape

{ double s1,s2;

Rectangle(double a, double b)

{

}

public double calCost()

{

}

public double area()

{

}

}

class Square implements Shape

{ double s;

Square(double a)

{ s = a;

}

public double calCost()

{

}

public double area()

{ return s * s;

s1 = a; s2 = b;

return puCost * area();

return s1 * s2;

return puCost * area();

}

}

class ShapeTest2

{ static public void main(String args[])

{ Shape s1 = new Triangle(3,4,5);

Shape s2 = new Rectangle(3,4);

Shape s3 = new Square(3);

System.out.println(s1.area());

System.out.println(s2.area());

System.out.println(s3.area());

System.out.println(s1.calCost());

System.out.println(s2.calCost());

System.out.println(s3.calCost());

}

}

Output:

6.0

12.0

9.0

600.0

1200.0

900.0

Example: This example improves the previous one by introducing additional sub-class AbstractShape between interface Shape and its sub-classes. This sub-class can contain the generic code for method calCost().

interface Shape

{
double area();

double calCost();

}

abstract class AbstractShape implements Shape

{ double puCost;

AbstractShape(double puCost)

{ this.puCost = puCost;

}

public double calCost()

{ return puCost * area();

}

}

class Triangle extends AbstractShape

{ double s1,s2,s3;

Triangle(double a, double b, double c, double puCost)

{ super(puCost);

}

public double area()

{ double s = (s1+s2+s3)/2;

}

}

class Rectangle extends AbstractShape

{ double s1,s2;

Rectangle(double a, double b, double puCost)

{ super(puCost);

}

public double area()

{ return s1 * s2;

}

}

class Square extends AbstractShape

{ double s;

Square(double a, double puCost)

{ super(puCost); 

}

public double area()

{ return s * s;

}

}

s1 = a; s2 = b; s3 = c;

return Math.sqrt(s*(s-s1)*(s-s2)*(s-s3));

s1 = a; s2 = b;

s = a;

class ShapeTest3

{ static public void main(String args[])

{ Shape s1 = new Triangle(3,4,5,10);

Shape s2 = new Rectangle(3,4,100);

Shape s3 = new Square(3,1000);

System.out.println(s1.area());

System.out.println(s2.area());

System.out.println(s3.area());

System.out.println(s1.calCost());

System.out.println(s2.calCost());

System.out.println(s3.calCost());

}

}

Output:
6.0
12.0
9.0
60.0
1200.0
9000.0

Example: The following example demonstrates that interface of the stack could be kept separate from its implementation by abstracting it using the interface StackInterface.

interface StackInterface

{ void push(int x);

int pop();

}

class Stack implements StackInterface

{ int top = -1; int a[] = new int[10];

public void push(int x)

{ if(top == 9)

{ System.out.println("Stack Full");

return;

}

top = top + 1; a[top] = x;

}

public int pop()

{ if(top ==  -1)

{ System.out.println("Stack Empty");

return -1; //assuming that -1 is not a valid data

}

int x = a[top]; top = top - 1; return x;

}

}

class StackTest

{ public static void main(String args[])

{ Stack st1=new Stack();

Stack st2=new Stack();

for(int i=1;i<5;i++)

{ st1.push(i);

}

for(int i=1;i<5;i++)

{ st2.push(i+10);

}

for(int i=1;i<5;i++)

{ System.out.println(st1.pop());

}

for(int i=1;i<5;i++)

{ System.out.println(st2.pop());

}

}

}

Output:
4
3
2
1
14
13
12
11

Example: This example demonstrates that an interface can be extended. This example also illustrates that a class implementing the extended interface must implement methods in base interface as well as methods in the extended interface.

interface ExtStackInterface extends StackInterface

{ public boolean isStackEmpty();

public boolean isStackFull();

public void display();

}

class ExtStack implements ExtStackInterface

{ int top = -1; int a[] = new int[10];

public void push(int x)

{ if(top == 9)

{ System.out.println("Stack Full"); return;

}

top = top + 1; a[top] = x;

}

public int pop()

{ if(top ==  -1)

{ System.out.println("Stack Empty");

return -1; //assuming that -1 is not a valid data

}

}

public void display()

{ for(int i = top; i >= 0; i--)

int x = a[top]; top = top - 1; return x;

{ System.out.println(a[i]);

}

}

public boolean isStackEmpty()

{ if(top == -1)

return(true);

else

return(false);

}

public boolean isStackFull()

{ if(top == 9)

return(true);

else

return(false);

}

}

Example: This example demonstrates that a class implementing the interface can also extend a base class. The implementing class must provide the implementation of all the methods in the interface. But the methods defined in the super-class need not be implemented as their definition is inherited from the super-class.

class ExtStack extends Stack implements ExtStackInterface

{ public void display()

{ for(int i = top; i >= 0; i--)

{ System.out.println(a[i]);

}

}

public boolean isStackEmpty()

{ if(top == -1)

return(true);

else

return(false);

}

public boolean isStackFull()

{ if(top == 9)

return(true);

else

return(false);

}

}

Thursday, 4 June 2015

Java Interface Characteristics

  1. Interface can be declared as abstract but it is superfluous and seldom done.
  2. Since interfaces are meant to be implemented by classes, interface members implicitly have public accessibility and the public modifier is omitted.
  3. The methods in an interface are all implicitly abstract and public. A method prototype has the same syntax as an abstract method. However, only the modifiers abstract and public are allowed, but these are normally omitted.
  4. A class can neither narrow the accessibility of an interface method nor specify new exceptions in method’s throws clause; as attempting to do so would amount to altering the interfaces contract, which is illegal. The criteria for overriding methods also apply when implementing interface methods.
  5. Interface methods cannot be declared as static. They are always implemented as instance methods.
  6. Regardless of how many interfaces a class implements directly or indirectly, it only provides a single implementation of a method that might have multiple declarations in the interfaces.
  7. Method prototype declarations can also be overloaded as in the case of classes.
  8. An interface can also define named constants. Such constants are defined by field declarations and are considered to be public, static and final. These modifiers are usually omitted from the declaration. Such a constant must be initialized with an initializer expression.
  9. An interface constant can be accessed by any client (a class or interface) using its fully qualified name, regardless of whether the client extends or implements its interface.
    However, if a client is a class that implements this interface or an interface that extends this interface, then the client can also access such constants directly without using the fully qualified name. Such a client inherits the interface constants.
  10. In the case of multiple inheritance of interface constants, any name conflicts can be resolved using fully qualified names for the constants involved.

Java accessing Interface Variables

The variables defined in an interface are implicitly public, static and final as discussed earlier.

The variables can be accessed just like static variables by using name of the interface and dot operator. The following example demonstrates this.

Example:

interface Constants

{

double PI = 3.1415;

double E = 2.712;

float INT_RATE = 10.0f;

}

These constants can be referred from other classes as follows:

Constants.PI, Constants.E, Constants.INT_RATE

The constants defined in the interface Constants can be accessed simply by using their names as PI, E and INT_RATE in the class, which implements the interface Constants.

You can use interfaces to import shared constants into multiple classes by simply declaring an interface that contains variables, which are initialized to the desired values.

When you include that interface in a class (i.e., when you “implement the interface”), all of these variables name will be in scope as constants. This is similar to using header file in C/C++ to create a large number of #defined constants or const declarations.

If an interface contains no methods, then any class that includes such an interface does not actually implement anything. It is as if that class was importing the constant variables into the class name space as final variables.

Example:

interface SharedConstants

{

int NO = 0;

int YES = 1;

int MAYBE = 2;

int LATER = 3;

int SOON = 4;

int NEVER = 5;

}

class ConstantsDemo implements SharedConstants

{

public static void main(String args[])

{

System.out.println(NO);

System.out.println(YES);

System.out.println(MAYBE);

System.out.println(LATER);

System.out.println(SOON);

System.out.println(NEVER);

}

}

class ConstantsDemo1

{

public static void main(String args[])

{

System.out.println(SharedConstants.NO);

System.out.println(SharedConstants.YES);

System.out.println(SharedConstants.MAYBE);

System.out.println(SharedConstants.LATER);

System.out.println(SharedConstants.SOON);

System.out.println(SharedConstants.NEVER);

}

}

Output: Output of executing both classes will be same as shown below:

0
1
2
3
4
5

Note: Class “ConstantsDemo” can use the constants defines in the interface  “SharedConstants” without qualifying with the interface name as it implements the interface “SharedConstants”. But class “ConstantsDemo1” can use the constants defined in the interface “SharedConstants” only after qualifying with the interface name, as it does not implement the interface “SharedConstants”.

Java extending an Interface

One interface can inherit another by use of keyword extends. The syntax is the same as for inheriting classes. When a class implements an interface that inherits another interfaces, it must provide implementations for all methods defined within the interface inheritance chain.

Example:

interface A

  void m1();
  void m2();
}

interface B extends A //interface can be extended
{
  void m3();
}

class MyClass implements B
{
   public void m1()
  {
    System.out.println("m1");
  }

public void m2()
{
   System.out.println("m2");
}

public void m3()
{
   System.out.println("m3");
}

}

class InterfaceExtendDemo
{

public static void main(String args[])

{

MyClass ob=new MyClass();

ob.m1();

ob.m2();

ob.m3();

}

}

Output:
m1
m2
m3

Java implementing an Interface

Once an interface has been defined, one or more classes can implement that interface. To implement an interface, include the implements clause in a class definition, and then create the methods defined by the interface.

The simplest form of a class implementing an interface is:

modifiers class <class-name> implements <interface-name>

{

body of the class

}

The body of the class must provide implementations of the methods declared in the interface.

You can also add additional features in the implementing class.

The methods that implement an interface must be declared public. Also, the signature of the implementing methods must match exactly the signature specified in the interface definition.

Java does not support multiple-inheritance but it supports multiple interface inheritance i.e. a class can implement any number of interfaces as shown below:

modifiers class <class-name> implements <interface-1>, <interface-2>, ……..<interface-n>

{

body of the class

}

The implementing class must provide body of all the methods in all the interfaces otherwise it must be declared as abstract.

The implementing class may also extend a class and can implement multiple interfaces. The most general form of a class that includes the implements clause looks like this:

modifiers class className [extends super-class] [implements interface1, interface2...]

{

class-body

}

Example:

interface Callback

{

void callback(int x);

}

Following is an implementation of the Callback interface

class Client1 implements Callback

{ public void callback(int x)

{ System.out.println(“Client1: ”+x);

}

}

Notice that callback method is declared using public access specifier. When you implement an interface method, it must be declared as public. The implementing an interface method is like over-riding so we cannot decrease the visibility.

1. Non Interface Methods

It is both permissible and common for classes that implement interfaces to define additional members of their own. For example, the following version of client implements callback() and adds the method m1():

class Client2 implements Callback

{ public void callback(int x)

{ System.out.println("Cleint2: " + 2*x);

}

public void m1()

{ System.out.println("m1 of Client2");

}

}

2. Accessing Implementations through Interface References

You can declare variables as object references that use an interface rather than a class type. Any instance of any class that implements the declared interface can be referred to by such a variable.

When you call a method through one of these references, the correct version will be called based on the actual instance of the interface being referred to. This is one of the key features of interfaces.

The method to be executed is looked up dynamically at run time, allowing classes to be created later than the code, which calls methods on them. The calling code can dispatch through an interface without having to know anything about the “callee”. This process is similar to using a super class reference to access a sub class object.

Note: Because dynamic lookup of a method at run time incurs a significant overhead when compared with the normal method invocation in Java, you should be careful not to use interface casually in performance-critical code.

Example: The following example demonstrates invoking method via an interface reference variable:

interface Callback

{ void callback(int x);

}

class Client1 implements Callback

{ public void callback(int x)

{ System.out.println("Client1: "+x);

}

}

class Client2 implements Callback

{ public void callback(int x)

{ System.out.println("Cleint2: " + 2*x);

}

public void m1()

{ System.out.println("m1 of Client2");

}

}

class InterfaceDemo1 //Accessing implementation through interface

{ public static void main(String args[])

{ Callback c = new Client1();

c.callback(10);

Callback c1 = new Client2();

c1.callback(10);

//c1.m1();

Client2 c2 = (Client2)c1;

c2.m1();

}

}

Output:

Client1: 10

Cleint2: 20

m1 of Client2

Notice that variable c is declared to be of interface type Callback, yet it is assigned an instance of Client1.

Although c1 can be used to access the callback() method, it cannot access any other members of the class Client2. An interface reference variable only has knowledge of the methods declared by its interface declaration.

Thus, c1 could not be used to access m1() method since it is defined by Client2 but not by Callback interface.

3. Polymorphic Power of Interface Reference Variable

The following example demonstrates the Polymorphic power of interface reference variable:

class InterfaceDemo2 //Polymorphic power of interface reference

{ public static void main(String args[])

{ Callback c;

Client1 c1  = new Client1();

Client2 c2  = new Client2();

c = c1;

c.callback(10);

c = c2;

c.callback(10);

}

}

Output:

Client1: 10
Cleint2: 20

4. Partial Implementation

If a class implements an interface but does not fully implement the methods defined by that interface, then that class must be declared as abstract.

Example:

abstract class Incomplete implements Callback

{ private int x;

void show()

{ System.out.println(x);

}

}

Here, the class Incomplete does not implement callback() method and must be declared as abstract. Any class that inherits Incomplete must implement callback() or be declared abstract itself.

Java defining an Interface

The general form of an interface is like class as shown below.

modifiers interface <interfac_name>

{ modifiers return_type method1(parameter-list);

modifiers return_type method2(parameter-list);

.

modifiers type final_var1 = value1;

modifiers type final_var2 = value2;

.

}

1. Modifiers for Top-Level Interface

The only modifiers that can be used with the top-level interfaces are abstract and public.

Even if we do not use abstract modifier, the interface is implicitly declared to be abstract so use of modifier abstract is redundant.

The visibility of a top-level interface can be either package or public just like top-level class. If no visibility modifier is used then the visibility of the interface is assumed to be package.

2. Interface Methods

Methods declared in an interface have no body. They end with a semicolon after the parameter list. They are, essentially, abstract methods and there can be no default implementation of any method specified within an interface.

All the methods declared in an interface have two modifiers, which are implicit:

abstract public method(parameter-list);

Methods are always abstract, which means they do not have any body and have public access.

All the methods declared in an interface are instance methods to be defined in the sub-classes.

We cannot declare static methods in interfaces.

3. Interface Data Members

We can define only constants in the interfaces.  All the variables in an interface are implicitly public, final and static meaning they cannot be changed by the implementing class. They must also be initialized with constant value.

Variables in an interface have implicit modifiers as shown below:

public static final int x = 10;

The variable x is public, static and final. It means it is a static variable with public access. The variable is also declared final, which means that it must be assigned a value at the time of declaration, which cannot be modified later on. The keyword final is like const in C/C++.

Example: The following program defines an interface for a stack i.e. it abstracts the public part of the stack.

interface StackInterface

{ void push(int x);

int pop();

}

The interface specifies that the stack has just two operations and any class sub-classing (implementing) this interface must provide bodies of push() and pop() methods.

Java Interface introduction

The purpose of the interface is to separate a class’s interface from its implementation. Interface just defines what a class must do without saying anything about the implementation. Interfaces define only method signatures and they do not have any instance variables. Interfaces are very good tool for designing as you can just define signatures of public methods without going into
implementation details, which are left for the person implementing the interface.

Using the keyword interface, you can fully abstract a class‘s interface from its implementation. That is, using interface, you can specify what a class must do, but not how it does it.

Interfaces are syntactically similar to classes, but they lack instance variables, and their methods are declared without any body. In practice, this means that you can define interfaces, which do not make assumptions about how they are implemented. Once it is defined, any number of classes can implement an interface. Also, one class can implement any number of interfaces.

To implement an interface, a class must create the complete set of methods defined by the interface. However, each class is free to determine the details of its own implementation. By providing the interface keyword, Java allows you to fully utilize the “one interface, multiple methods” aspect of polymorphism.

Interfaces are designed to support dynamic method resolution at run time. They disconnect the definition of a method or set of methods from the inheritance hierarchy. Since interfaces are in a different hierarchy from classes, it is possible for classes that are unrelated in terms of class hierarchy to implement the same interface. This is where the real power of interfaces is realized.

Note: Interfaces add most of the functionality that is required for many applications, which would normally resort to using multiple inheritance in a language such as C++.

Sunday, 31 May 2015

Java Importing packages

We discuss this concept with reference to previous example. Given that packages exist and are a good mechanism for compartmentalizing diverse classes from each other, it is easy to see why all of the built in Java classes are stored in packages.

There are no core java classes in the unnamed default package; all of the standard classes are stored in some named package.

Since classes within packages must be fully qualified with their package name or names, it could become tedious to type the long dot-separated package path name for every class you want to use. For this reason, Java includes the import statement to bring certain classes, or entire package into visibility. Once imported, a class can be referred to directly, using only its name.

Note: The import statement is a convenience to the programmer and is not technically needed to write a complete Java program. If you are going to refer to a few dozen classes in your application, however, the import statement will save a lot of typing.

In Java source file, import statements occur immediately following the package statement. (if it exists) and before any class/interface definitions.

The geneal form of import statement:

import pkg1 [.pkg2] [.pkg3].[classname | *];

Note: 

1. The star form may increase compilation time. However, the star form has absolutely no effect on the run-time performance or size of your classes.

2. All of the standard Java classes included with Java are stored in a package called java. The basic language functionality is stored in a package inside of the java package called java.lang. Normally, you have to import every package or class that you want to use, but since Java is useless without much of the functionalities in java.lang, it is implicitly imported by the compiler for all programs. This is equivalent to the following line being at the top of all of your programs:

import java.lang.*;

3. If a class with the same name exists in two different packages that you import using the star form, the compiler will remain silent, unless you try to use one of the classes. In that case, you will get a compile-time error and have to explicitly name the class specifying its package.

4. Any place you use a class name, you can use its fully qualified name, which includes its full package hierarchy. When a package is imported, only those items within the package declared as public will be available to non-subclasses in the importing code.

Java visibility of class members

Classes and packages are both means of encapsulating and containing the name space and scope of variables and methods. Packages act as containers for classes and other subordinate packages. Class act as container for data and method code. The class is Java’s smallest unit of abstraction. Because of the interplay between classes and packages, Java addresses five categories of visibility for class members:

1. Visibility within the class

2. Visibility in sub-classes in the same package

3. Visibility in non-sub classes in the same package

4. Visibility in sub-classes in different package

5. Visibility in classes that are neither in the same package nor are sub classes.

A top-level class or interface has only two possible access levels: default and public. When a class is declared public, it is accessible by any other code. If a class has default access, then it can only be accessed by other code within the same package.

The visibility of class members is summarized in the following table:


Note: The member visibility has meaning only if the class is visible. If visibility modifier of the class is default then even public members of the class will be visible only within the package.

Example:

Protection.java

package p1;

public class Protection

{

int n = 1;

private int n_pri = 2;

protected int n_pro = 3;

public int n_pub = 4;

public Protection()

{

System.out.println("Base Constructor");

System.out.println(n);

System.out.println(n_pri);

System.out.println(n_pro);

System.out.println(n_pub);

}

}

To compile: javac –d . Protection.java

Derived.java

package p1;

class Derived extends Protection

{

public Derived()

{

 System.out.println(n);

System.out.println("Derived Constructor");

//System.out.println(n_pri);

System.out.println(n_pro);

System.out.println(n_pub);

  }

}

To compile: javac –d . Derived.java

SamePackage.java

package p1;

class SamePackage

{

public SamePackage()

  {

Protection p = new Protection();

System.out.println("Same Package constructor");

System.out.println(p.n);

//System.out.println(p.n_pri);

System.out.println(p.n_pro);

System.out.println(p.n_pub);

}

}

To compile: javac –d . SamePackage.java

Protection2.java

package p2;

class Protection2 extends p1.Protection

{

Protection2()

{

System.out.println("Protection2 Constructor");

//System.out.println(n);

//System.out.println(n_pri);

System.out.println(n_pro);

System.out.println(n_pub);

}

}

To compile: javac –d . Protection2.java

OtherPackage.java

package p2;

class OtherPackage

{

OtherPackage()

{

p1.Protection p = new p1.Protection();

System.out.println("OtherPackage Constructor");

//System.out.println(p.n);

//System.out.println(p.n_pri);

//System.out.println(p.n_pro);

System.out.println(p.n_pub);

}

}

To Compile: javac –d . OtherPackage.java

Test1.java

package p1;

class Demo

{

public static void main(String args[])

{

Protection ob1 = new Protection();

Derived ob2 = new  Derived();

SamePackage ob3 = new SamePackage();

}

}

To Compile: javac –d . Test1.java

Output:

Base Constructor1234
Base Constructor1234
Derived Constructor134
Base Constructor1234
Same Package Constructor134

Test2.java

package p2;

class Demo

{

public static void main(String args[])

{

Protection2 ob1 = new Protection2();

OtherPackage ob2 = new OtherPackage();

}

}

To Compile: javac –d . Test2.java

Output:

Base Constructor1234
Protection2 Constructor
34
Base Constructor1234
OtherPackage Constructor
4

Java Packages

If no package name is specified in any java file then the class is part of the unnamed package. This requires that every class must have a unique name to avoid collisions. After a while, without some way to manage the namespace, you could run out of convenient descriptive names for individual classes.

You also need some way to be assured that the name you choose for a class will be reasonably unique and not collide with class names chosen by other programmers.

Java provides a mechanism for partitioning the class name space into more manageable chunks. This mechanism is the package.

The package is both a naming and visibility control mechanism.
You can define classes inside a package that are not accessible by code outside that package.
You can also define class members that are only exposed to other members of the same package.
This allows your classes to have intimate knowledge of each other, but not expose that knowledge to the rest of the world.

Defining a package

To create a package, include a package command as the first statement in a Java source file. Any classes declared within that file will belong to the specified package. The package statement defines a name space in which classes are stored. If you omit the package statement, the class names are put into the default package, which has no name and is called un-named package.

This is the general form of package statement:

package pkg_name;

Java uses file system directories to store packages. Remember that case is significant, and directory name must match the package name exactly. More than one file can include the same package statement.

You can create a hierarchy of packages. To do so, simply separate each package name from the one above it by use of a period. The general form of a multi-leveled package statement is shown here:

package pkg_name1 [.pkg_name2] [.pkg_name3];


A package hierarchy must be reflected in the file system of your Java development system.

For example a package declared as:

package java.awt.image;

needs to be stored in java/awt/image, java\awt\image, or java:awt:image on your Unix, Windows, or Macintosh file system, respectively.

A global naming scheme has been proposed to use the reverse Internet domain names to uniquely identify packages.

For example the apache’s domain name is www.apache.org. So to store classes in package tomcat, preferably you should use the package hierarchy:

org.apache.tomcat

which would be unique.

A package hierarchy represents an organization of Java classes and interfaces. It does not represent the source code organization of the classes and interfaces. Each Java source file (also called compilation unit) can contain zero or more definitions of classes and interfaces, but the compiler provides a separate class file containing the Java byte code for each of them. A class or interface can indicate that its java byte code be placed in a particular package, using a package declaration.

At most one package statement can appear in a source file, and it must be the first statement in the unit.

Note that this scheme has two consequences. First, all classes and interfaces in a source file will be placed in the same package. Secondly, several source files can be used to specify the contents of a package.

Finding packages and CLASSPATH

As discussed, packages are mirrored by directories. This raises an important question. How does the Java run-time system know where to look for packages that you create?

There can be two approaches:

First, by default, the Java run-time system uses the current working directory as its starting point. Thus, if your package is in the current directory, or a subdirectory of the current directory, it will be found.

Second, you can specify a directory path or paths by setting the CLASSPATH environment variable. For example, consider the following package specification:

package mypack;

In order for a program to find mypack, one of the two things must be true. Either the program is executed from a directory immediately above mypack, or CLASSPATH must be set to include the path to mypack.

Jar File

If you are developing a complex system or using third party libraries then instead of creating a directory hierarchy for class files you can use .jar files by including them in the CLASSPATH.

The JVM searches for the packages and classes in .jar file as it does searches in the file system.
Instead of .jar file you can also use a .zip file created by any popular software like winzip, winrar etc. Jar files can be created using jar utility that is part of JDK. To include the current directory and all the sub-directories below it in a jar file give the following command:

jar -cf myjar.jar *

here, c stands for creating a new .jar file.

         f stands for name of the .jar file.

The above command will create myjar.jar file in the current folder.

Example:

package mypack;

public class MyProg

{ public static void main(String args[])

{ System.out.println("Yes, Its working!");

}

}

To compile the following program give following command:

C:\totest>javac -d . MyProg.java

Here -d is used to create a directory ‘mypack’ in the current folder and put the class file in this folder automatically. When we compile the program, ‘mypack’ directory is created in the current folder (which is assumed to be c:\totest).

We can run above program in following different ways:

1. Running from the current directory: 

Give the following command from the directory where the package directory is created i.e from folder c:\totest.

java mypack.MyProg

This is because, MyProg file is part of package mypack.

Output:

Yes, Its working!

2. Running using classpath:

Give the following command at the command prompt:

SET CLASSPATH = %CLASSPATH%;C:\totest;

Then give the following command from any directory/folder:

java mypack.MyProg

3. Running by specifying classpath as parameter

Give the following command:

 java –classpath c:\totest mypack.MyProg

4. Running using jar file: Go to C:\totest folder and give the following command:

 jar –cf myjar.jar mypack (or jar -cf myjar.jar mypack)

and then give the following command:

java -classpath c:\totest\myjar.jar mypack.MyProg

After creating the .jar file, you can also set the classpath as follows:

set classpath=%classpath%;c:\totest\myjar.jar

Note: you can use –d option to copy the class file in any desired folder. For example, use the following command to create folder ‘mypack’ in C:\myclasses:

javac –d C:\myclasses MyProg.java

This will create a folder mypack below myclassses, if not already present and put the MyProg.class file in it.

Java Abstract Classes

There are situations in which you will want to define a super class that declares the structure of a given abstraction without providing a complete implementation of every method. That is, sometimes you will want to create a super class that only defines a generalized form that will be shared by all of its subclasses, leaving it to each sub class to fill in the details. Such a class determines the nature of the methods that the sub classes must implement. One way this situation can occur is when a super class is unable to create a meaningful implementation for a method.

This is the case with the class Shape used in the preceding example. The definition of area() is simply placeholder. It will not compute and display the area of any type of object. When you create your own class libraries, it is not uncommon for a method to have no meaningful definition in the context of its super-class.

You can handle this situation in two ways: 

One way, as shown in the previous example, is to simply have it report a warning message. While this approach can be useful in certain situations- such as debugging. It is not usually appropriate. You may have methods, which must be overridden by the sub class in order for the sub class to have any meaning.

Consider the class triangle. It has no meaning if area() is not defined. In this case, you want some way to ensure that a sub class does, indeed, override all necessary methods.

Java’s solution to this problem is the abstract method. You can require that certain methods be overridden by subclasses by specifying the abstract type modifier. These methods are sometimes referred to as subclass responsibility because they have no implementation specified in the super class. Thus a sub class must override them – it can not simply use the version defined in the super class. To declare an abstract method, use this general form:

abstract return_type name(parameter-list);

As you can see, no method body is present. Any class that contains one or more abstract methods must also be declared abstract. To declare a class abstract, you simply use the abstract keyword in front of the class keyword at the beginning of the declaration.

There can be no object of an abstract class. That is, an abstract class can not be directly instantiated with the new operator. Such objects would be useless, because an abstract class is not fully defined. Also you cannot declare abstract constructors or abstract static methods. Any subclass of an abstract class must either implement all of the abstract methods in super class, or be itself declared abstract. Here, is a simple example of a class with an abstract method, followed by a class which implements that method.

Example:

1 abstract class Shape //abstract class

2 { double puCost = 100;

3 abstract double area(); //abstract method.

4 double calCost()

5 {  return puCost * area();

6 }

7 }

1 class Triangle extends Shape

2 {

3 double s1,s2,s3;

4 Triangle(double a, double b, double c)

5 {

6   s1 = a; s2 = b; s3 = c;

7 }

8 double area()

9 {

10 double s = (s1+s2+s3)/2;

11 return Math.sqrt(s*(s-s1)*(s-s2)*(s-s3));

12 }

13 }

1 class Rectangle extends Shape

2 { double s1,s2;

3 Rectangle(double a, double b)

4 {

5  s1 = a; s2 = b;

6 }

7 double area()

8 {

9 return s1 * s2;

10 }

11 }

1 class Square extends Shape

2 {

3 double s;

4 Square(double a)

5 {

6   s = a;

7 }

8 double area()

9 {

10 return s * s;

11 }

12 }

1 class ShapeTest1

2 { static public void main(String args[])

3     { //Shape s = new Shape();

4   Shape s1 = new Triangle(3,4,5);

5   Shape s2 = new Rectangle(3,4);

6   Shape s3 = new Square(3);

7   //System.out.println(s.area());

8   System.out.println(s1.area());

9   System.out.println(s2.area());

10   System.out.println(s3.area());

11   //System.out.println(s.calCost());

12   System.out.println(s1.calCost());

13   System.out.println(s2.calCost());

14   System.out.println(s3.calCost());

15 }

16 }

Output:

6.0
12.0
9.0
600.0
1200.0
900