Module 4
• Packages are containers for classes that are used to keep
the class name space compartmentalized.
• For example, a package allows you to create a class
named List, which you can store in your own package
without concern that it will collide with some other
class named List stored elsewhere.
• Packages are stored in a hierarchical manner and are
explicitly imported into new class definitions.
• Java provides a mechanism for partitioning the class name
Packages space into more manageable chunks. This mechanism is
the package.
• The package is both a naming and a visibility control
mechanism.
• You can define classes inside a package that are not
accessible by code outside that package.
➢ A package can hide certain classes/methods from the outside world.
Inside a package:
•Classes can communicate deeply
•Internal logic can remain hidden
•Only selected classes are exposed to users (API design)
➢ This is similar to having:
•public → available to everyone
•default (no modifier) → available only inside the same package
•protected → package + subclasses
•private → inside class only
Packages help structure large applications properly.
• Preventing naming conflicts.
• For example there can be two classes with name
Employee in two packages,
[Link] and
[Link]
• Making searching/locating and usage of classes, interfaces,
enumerations and annotations easier
Packages are • Providing controlled access: protected and default have
package level access control.
used for, • A protected member is accessible by classes in the same
package and its subclasses. A default member (without any
access specifier) is accessible by classes in the same package
only.
• Packages can be considered as data encapsulation (or data-
hiding).
• 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
Defining a Package
default package, which has no name.
• Syntax: package pkg;
Here, pkg is the name of the package.
package MyPackage;
• Java uses file system directories to store packages.
• For example, the .class files for any classes you declare to be
part of MyPackage must be stored in a directory called MyPackage.
• More than one file can include the same package statement.
➢ What Java Does Internal
The package mypackage; statement tells Java:
•"This file belongs to the mypackage folder."
•If someone imports it, they must write:
•import [Link];
Defining a ➢ You can create a hierarchy of packages. To do so, simply
separate each package name from the one above it by
Package use of a period.
package pkg1[.pkg2[.pkg3]];
package [Link]; → java/awt/image.
➢ needs to be stored in java\awt\image in a Windows
environment.
Two types
1. Built-in Packages
Packages that are already created and provided by Java (JDK).
You don’t write them — you just import and use them.
[Link]: Contains language support classes [Link]:
Types of Contains classed for supporting input / output
packages operations.
[Link]: Contains classes for creating
Applets.
Ex:[Link], [Link], [Link]
2. User-defined packages
These are the packages that are defined by the user.
• How does the Java run-time system know where to
look for packages that you create?
• CLASSPATH tells Java where to look for:
• The answer has three parts.
Finding • First, by default, the Java run-time system uses the
current working directory as its starting point. Thus, if
Packages and your package is in a subdirectory of the current
CLASSPATH directory, it will be found.
If CLASSPATH includes C:\JavaProjects\, Java can find your
package.
• Second, you can specify a directory path or paths by
setting the CLASSPATH environmental variable.
• Third, you can use the -classpath option with
java and javac to specify the path to your classes.
• When the second two options are used, the
class path must not include MyPack, itself.
• It must simply specify the path to MyPack.
Finding • For example, in a Windows environment, if the
Packages and path to MyPack is
CLASSPATH C:\MyPrograms\Java\MyPack
• Then the class path to MyPack is
C:\MyPrograms\Java
Java wants to protect data and methods.
So Java checks two things whenever you try to access something:
[Link] is the access modifier?
[Link] are you accessing from?
(same class? same package? subclass? different package?)
Java combines two visibility systems:
Class-based visibility
(what a subclass can see)
Package-based visibility
(what classes inside same package can see)
• 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.
• Classes act as containers
Packages • Java addresses four categories of visibility for class
members:
and – Subclasses in the same package
Member – Non-subclasses in the same package
– Subclasses in different packages
Access – Classes that are neither in the same package nor subclasses
for data and code.
Same Different
Same Difference
Access package package
Same class package Package
Modifier non- non-
subclass subclass
subclass subclass
Default Yes Yes Yes No No
Private Yes No No No No
Protected Yes Yes Yes Yes No
Public Yes Yes Yes Yes Yes
//This is file [Link]:
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() {
[Link]("base constructor");
[Link]("n = " + n);
[Link]("n_pri = " + n_pri);
[Link]("n_pro = " + n_pro);
[Link]("n_pub = " + n_pub);
}
}
//This is file [Link]:
package p1;
class Derived extends Protection {
Derived() {
[Link]("derived constructor");
[Link]("n = " + n);
// [Link]("n_pri = "4 + n_pri);
[Link]("n_pro = " + n_pro);
[Link]("n_pub = " + n_pub);
}
}
//This is file [Link]:
package p1;
class SamePackage {
SamePackage() {
Protection p = new Protection();
[Link]("same package constructor");
[Link]("n = " + p.n);
// [Link]("n_pri = " + p.n_pri);
[Link]("n_pro = " + p.n_pro);
[Link]("n_pub = " + p.n_pub);
}
}
// Demo package p1.
package p1;
// Instantiate the various classes in p1.
public class Demo {
public static void main(String args[]) {
Protection ob1 = new Protection();
Derived ob2 = new Derived();
SamePackage ob3 = new SamePackage();
}
}
//This is file [Link]:
package p2;
class Protection2 extends [Link] {
Protection2() {
[Link]("derived other package constructor");
// class or package only
// [Link]("n = " + n);
// class only
// [Link]("n_pri = " + n_pri);
[Link]("n_pro = " + n_pro);
[Link]("n_pub = " + n_pub);
}
}
This is file [Link]:
package p2;
class OtherPackage {
OtherPackage() {
[Link] p = new [Link]();
[Link]("other package constructor");
// class or package only
// [Link]("n = " + p.n);
// class only
// [Link]("n_pri = " + p.n_pri);
// class, subclass or package only
// [Link]("n_pro = " + p.n_pro);
[Link]("n_pub = " + p.n_pub);
}
}
// Demo package p2.
package p2;
// Instantiate the various classes in p2.
public class Demo {
public static void main(String args[]) {
Protection2 ob1 = new Protection2();
OtherPackage ob2 = new OtherPackage();
}
}
QUESTION 1: Are you in the SAME PACKAGE?
|
|-- YES --> default + protected + public (private )
|
|-- NO --> QUESTION 2
|
|-- Are you a SUBCLASS?
| |
| |-- YES --> protected + public
| |
| |-- NO --> public only
• Java includes the import statement to bring certain classes, or entire
packages, into visibility.
• Once imported, a class can be referred to directly, using only its name.
• The import statement is a convenience to the programmer and is not
technically needed to write a complete Java program.
• In a Java source file, import statements occur immediately following
the package statement (if it exists) and before any class definitions.
Importing import pkg1[.pkg2].(classname*);
• Here, pkg1 is the name of a top-level package, and pkg2 is the name
Packages of a subordinate package inside the outer package separated by a
dot (.).
• There is no practical limit on the depth of a package hierarchy, except
that imposed by the file system.
• Specify either an explicit classname or a star (*), which indicates that
the Java compiler should import the entire package.
import [Link];
import [Link].*;
• If you import a package, subpackages will not be
imported.
• There are three ways to access the package from
outside the package.
Importing 1. import package.*;
Packages 2. import [Link];
3. fully qualified name.
import package.*;
//save by [Link]
package pack;
public class A{
public void msg(){[Link]("Hello");}
}
//save by [Link]
import pack.*;
package mypack;
class B{
public static void main(String args[]){
A obj = new A();
[Link]();
}
}
Output:Hello
//save by [Link]
package pack;
public class A{
public void msg(){[Link]("Hello");}
}
import //save by [Link]
package mypack;
package. import pack.A;
classname; class B{
public static void main(String args[]){
A obj = new A();
[Link]();
}
}
Output:Hello
//save by [Link] package
pack; public class A{
public void msg(){[Link]("Hello");}
}
//save by [Link]
package mypack;
fully qualified
name class B{
public static void main(String args[]){
pack.A obj = new pack.A(); // using fully qualified name
[Link]();
}
}
OUTPUT:Hello
fully qualified name
import [Link].*;
class MyDate extends Date {
}
The same example without the import statement looks
like this:
class MyDate extends [Link] {
}
Example of Subpackage
package [Link];
class Simple{
public static void main(String args[]){
[Link]("Hello subpackage");
}
}
To Compile: javac -d . [Link]
To Run: java [Link]
Output:Hello subpackage
How to send the class file to another directory or drive
//save as [Link] package
mypack;
public class Simple{
public static void main(String args[]){
[Link]("Welcome to package");
}
}
To Compile:
e:\sources> javac -d c:\classes [Link]
To Run:
To run this program from e:\source directory, you need to set
classpath of the directory where the class file resides.
e:\sources> set classpath=c:\classes;.;
e:\sources> java [Link]
Another way to run this program by -classpath switch of java:
e:\sources> java -classpath c:\classes [Link]
Exception handling - Fundamentals
• An exception is an abnormal condition that arises in a code
sequence at run time. In other words, an exception is a run-
time error.
• When an exceptional condition arises, an object representing
that exception is created and thrown in the method that caused
the error. That method may choose to handle the exception
itself, or pass it on. Either way, at some point, the exception is
caught and processed.
• Exceptions can be generated by the Java run-time system, or
they can be manually generated by your code.
• In Java, an exception is an event that disrupts the normal
flow of the program. It is an object which is thrown at
runtime.
• Exception Handling is a mechanism to handle runtime errors
such as ClassNotFoundException, IOException, SQLException,
RemoteException, etc.
Examples:
•Divide by zero
•Accessing an array with an invalid index
•Opening a file that doesn’t exist
•Passing invalid input to a method.
Instead of crashing blindly or returning error codes, Java wraps the problem
into an object and throws it.
An exception is an object that represents an error.
Why Java needed exception handling Java’s exception system:
Before exceptions: •Separates normal logic from error logic
•You had to manually check return values •Forces important errors to be handled
•Error codes were easy to forget •Fits perfectly with OOP (errors = objects)
•Logic became messy and unreadable
• Java exception handling is managed via five keywords: try,
catch, throw, throws, and finally.
• Program statements that you want to monitor for exceptions
are contained within a try block.
• If an exception occurs within the try block, it is thrown.
• Your code can catch this exception (using catch) and handle
it in some rational manner.
• System-generated exceptions are automatically thrown by
the Java run-time system.
• To manually throw an exception, use the keyword throw.
• Any exception that is thrown out of a method must be
specified as such by a throws clause.
Any code that absolutely must be executed after a try block completes is put in a
finally block.
Keyword Meaning
try Code that might fail
catch Code that handles the failure
Manually create & throw an
throw
exception
Declare that a method may pass an
throws
exception
finally Code that always runs
Java watches this block Multiple catch blocks:
If something abnormal happens → exception is created •Java checks top to bottom
Normal execution stops immediately •First matching type wins
Java jumps to a matching catch
•Runs only if that exception occurs
•ex is the exception object
•You can inspect it ([Link]())
try { try {
int x = 10 / 0;
// block of code to monitor for errors
}
}
catch (ExceptionType1 exOb) {
catch (ArithmeticException ex) {
// exception handler for ExceptionType1 [Link]("Division by zero!");
} }
catch (ExceptionType2 exOb) {
// exception handler for ExceptionType2
}
// ...
finally { finally {
// block of code to be executed after try block ends [Link]("Cleanup code");
}
}
Full mental flow (very important)
[Link] occurs inside try
[Link] object is created
[Link] looks for a matching catch
[Link] found → handler runs
[Link] runs
[Link] continues (if possible)
If no catch matches:
•Program terminates
•JVM prints stack trace
Why this is object-oriented
•Exceptions are classes catch (Exception e) {
•They form a hierarchy // catches everything
}
•You can create custom exceptions
Exception types
• All exception types are subclasses of the built-in
class Throwable. Object
└── Throwable
• Thus, Throwable is at the top of the exception ├── Error
└── Exception
class hierarchy.
• The [Link] class is the root class of
Java Exception hierarchy which is inherited by
two subclasses:
1. Exception
2. Error
Errors are problems that:
•Are not meant to be handled
•Occur due to JVM or system failure
•Usually crash the program
Examples:
•OutOfMemoryError
•StackOverflowError
•VirtualMachineError
Exceptions are problems that:
•Can be handled
•Occur due to program logic or user input
• There are mainly two types of exceptions:
1. checked exceptions.(compile)
2. Unchecked exceptions.(runtime)
• Here, an error is considered as the unchecked exception
What are they?
•Checked at compile time FileInputStream f = new FileInputStream("[Link]"); // compile-time error
•Compiler forces you to handle them
•Must use try-catch or throws try {
Examples: FileInputStream f = new FileInputStream("[Link]");
•IOException } catch (FileNotFoundException e) {
•FileNotFoundException [Link]("File not found");
•SQLException }
•ClassNotFoundException
Why this split exists (important concept)
Checked exceptions → external problems
Things you cannot control
•File missing
•Network down
•Database unavailable
Unchecked exceptions → coding mistakes
Things you should fix in code
•Null checks
•Array bounds
•Divide by zero
• Checked Exception
– The classes which directly inherit Throwable class except
RuntimeException and Error are known as checked exceptions
e.g. IOException, SQLException etc.
– Checked exceptions are checked at compile-time.
• Unchecked Exception
– The classes which inherit RuntimeException are known as
unchecked exceptions e.g. ArithmeticException,
NullPointerException, ArrayIndexOutOfBoundsException etc.
– Unchecked exceptions are not checked at compile-time, but
they are checked at runtime.
• Error
– Error is irrecoverable e.g. OutOfMemoryError,
VirtualMachineError, AssertionError etc.
What happens when you don’t handle exceptions
- Uncaught Exceptions
class Exc0 {
public static void main(String args[]) { int d
= 0;
int a = 42 / d;
[Link](a);
[Link]("End of program");
}
}
Error Message: [Link]: / by
zero at [Link]([Link])
[Link] compiles successfully
javac [Link]
2. Program starts running
java DivideByZero
3. JVM executes:
int a = 42 / d;
4. JVM detects division by zero
5. JVM automatically throws:
ArithmeticException: / by zero
6. JVM searches for a matching catch
none found
[Link] prints stack trace
[Link] terminates immediately
[Link] lines are NOT executed
Using try and catch
• Handle an exception
– First, it allows you to fix the error.
– Second, it prevents the program from
automatically terminating.
• To guard against and handle a run-time error,
simply enclose the code that you want to
monitor inside a try block.
• Immediately following the try block, include a
catch clause that specifies the exception type
that you wish to catch.
try {
11block of code to monitor for errors
}
catch (ExceptionTypel el ) {
II exception handler for Exception'J'ypel
}
catch (ExceptionType2 e2) {
II exception handler for Exception1'ype2
}
II ..•
finally {
II block of code to be executed before try block
ends
}
package examplejava;
public class Except1 {
public static void main(String args[]) {
int d, a;
try {
d = 0;
a = 42 / d;
[Link]("This will not be
printed.");
} catch (ArithmeticException e) {
[Link]("Division by zero.");
}
[Link]("After catch
statement.");
}
}
OUTPUT:
Division by zero.
After catch statement
• The call to println( ) inside the try block is never executed.
Once an exception is thrown, program control transfers out of
the try block into the catch block.
• Put differently, catch is not “called,” so execution never
“returns” to the try block from a catch.
• Thus, the line “ This will not be printed.” is not displayed.
Once the catch statement has executed, program control
continues with the next line in the program following the
entire try/catch mechanism.
• A try and its catch statement form a unit.
• The scope of the catch clause is restricted to those statements
specified by the immediately preceding try statement.
• A catch statement cannot catch an exception thrown by another
try statement
• The statements that are protected by try must be surrounded by
curly braces.
• You cannot use try on a single statement.
Displaying a Description of an Exception
➢ In Java, all exceptions inherit from Throwable.
➢ So every exception object (like ArithmeticException) is a Throwable.
➢ Throwable overrides the toString( ) method (defined by Object).
Throwable overrides toString().
That means:
It replaces Object’s version
It returns a meaningful description of the exception.
catch (ArithmeticException e) {
When to use what?
[Link](e);
}
Method Use case
When you do: [Link](e) Simple debugging
[Link](e); getMessage() User-friendly error message
printStackTrace() Developer debugging
Java internally calls:
[Link]([Link]());
Multiple catch Clauses
• In some cases, more than one exception could be raised by a single piece of code.
• To handle this type of situation, you can specify two or more catch clauses,
each catching a different type of exception.
• When an exception is thrown, each catch statement is inspected in
order, and the first one whose type matches that of the exception is
executed.
• After one catch statement executes, the others are bypassed, and execution
continues after the try/catch block.
package examplejava;
class Supersubcatch {
public static void main(String args[]) {
try {
int a = 0;
int b = 42 / a;
}
catch(Exception e) {
[Link]("Generic Exception catch.");
}
/* This catch is never reached because ArithmeticException
* is a subclass of Exception. */
catch(ArithmeticException e)
{ // ERROR - unreachable
[Link]("This is never reached.");
}
}
}
/* The above program contains an
error.
A subclass must come before its
superclass in a series of catch
statements.
If not, unreachable code will be
created and a compile-time error
will result.
*/
Nested try Statements
• The try statement can be nested. That is, a try statement can
be inside the block of another try.
• Each time a try statement is entered, the context of that
exception is pushed on the stack.
• If an inner try statement does not have a catch handler for a
particular exception, the stack is unwound and the next try
statement’s catch handlers are inspected for a match.
• This continues until one of the catch statements succeeds,
or until all of the nested try statements are exhausted.
• If no catch statement matches, then the Java run-time
system will handle the exception.
// An example of nested try statements.
class NestTry {
public static void main(String args[]) {
try {
int a = [Link];
/* If no command-line args are present */
int b = 42 / a;
[Link]("a = " + a);
try { // nested try block
/* If one command-line arg is used */
if(a==1)
a = a/(a-a); // division by zero
/* If two command-line args are used */
if(a==2) {
int c[] = { 1 };
c[42] = 99; // generate an out-of-bounds exception
}
} catch(ArrayIndexOutOfBoundsException e) {
[Link]("Array index out-of-bounds: " + e);
}
} catch(ArithmeticException e) {
[Link]("Divide by 0: " + e);
}
}}
throw
• catching exceptions that are thrown automatically by the Java run-
time system.
• However, it is possible to throw an exception explicitly, using the
throw statement.
throw ThrowableInstance;
• Here, ThrowableInstance must be an object of type Throwable or a
subclass of Throwable. Primitive types (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 in a catch clause, or
– creating one with the new operator.
• The flow of execution stops immediately after the throw
statement; any subsequent statements are not executed.
• The nearest enclosing try block is inspected to see if it has
a catch statement that matches the type of exception.
• If it does find a match, control is transferred to that
statement. If not, then the next enclosing try statement
is inspected, and so on.
• If no matching catch is found, then the default
exception handler halts the program and prints the
stack trace.
package examplejava;
//Demonstrate throw.
class Throwdemo {
static void demoproc() {
try {
throw new NullPointerException("demo");
}
catch(NullPointerException e) {
[Link]("Caught inside
demoproc.");
throw e; // rethrow the exception
}
}
public static void main(String args[]) {
try {
demoproc();
} catch(NullPointerException e) {
[Link]("Recaught: " + e);
}
}
}
This program gets two chances to deal with the same
error.
First, main( ) sets up an exception context and then calls
demoproc( ).
The demoproc( ) method then sets up another exception handling
context and immediately throws a new instance of
NullPointerException, which is caught on the next line.
The exception is then rethrown.
output:
Caught inside demoproc.
Recaught: [Link]: demo
throws
• 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 exceptions 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.
type method-name(parameter-list) throws exception-list
{
// body of method
}
• Here, exception-list is a comma-separated list of the exceptions that a method can
throw.
public static void main(String args[])throws NullPointerException,
ArithmeticException
{
try{
throw new NullPointerExcption();
[Link](“aaaaaaaa”); //unreachable code
}
catch(ArithmeticException a){ }
}
// This program contains an error and will not compile.
class ThrowsDemo {
static void throwOne() {
[Link]("Inside throwOne.");
throw new IllegalAccessException("demo");
}
public static void main(String args[]) {
throwOne();
// This is now correct.
}
class ThrowsDemo {
}
static void throwOne() throws IllegalAccessException {
[Link]("Inside throwOne.");
throw new IllegalAccessException("demo");
}
public static void main(String args[]) {
try {
throwOne();
} catch (IllegalAccessException e) {
[Link]("Caught " + e);
}
}
}
finally
• When exceptions are thrown, execution in a method
takes a rather abrupt, nonlinear path that alters the
normal flow through the method.
• Depending upon how the method is coded, it is even
possible for an exception to cause the method to
return prematurely.
• This could be a problem in some methods.
• For example, if a method opens a file upon entry and
closes it upon exit, then you will not want the code
that closes the file to be bypassed by the exception-
handling mechanism.
• The finally keyword is designed to address this
contingency.
finally
• 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 an 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 handles 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.
// Execute a try block normally. static void procC()
/// Demonstrate finally. {
class FinallyDemo { //Through an exception out of the method. try {
static void procA() { [Link]("inside procC");
try { } finally {
[Link]("inside procA"); [Link]("procC's finally");
throw new RuntimeException("demo"); }
} finally { }
[Link]("procA's finally"); public static void main(String args[]) {
} try {
} procA();
// Return from within a try block. } catch (Exception e) {
static void procB() { [Link]("Exception caught");
try { }
[Link]("inside procB"); return; procB();
} finally { procC();
[Link]("procB's finally"); }
} }
}