Module 4

Download as pdf or txt
Download as pdf or txt
You are on page 1of 62

Module-4

Packages and Exception Handling


Packages
In Java, a package is a mechanism for organizing classes and interfaces into namespaces.
Packages help in organizing large codebases by providing a way to group related classes
and interfaces together.
They also help in avoiding naming conflicts between classes and interfaces with the same
name but defined in different packages.
To create a package: simply 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.
(All the classes that were written so far were packaged into the default
package.)
While the default package is fine for short, sample programs, it is inadequate
for real applications.
Most of the time, you will define a package for your code. This is the general
form of the package statement:
package pkg;
For example, the following statement creates a package called MyPackage:
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.

Remember that case is significant, and the directory name must match the package name exactly.

More than one .class file can be included 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 multileveled package statement is shown here:

package pkg1[.pkg2[.pkg3]];
example
For example, a package declared as

package java.awt.image;

needs to be stored in java\awt\image in a Windows environment.

Be sure to choose your package names carefully.

You cannot rename a package without renaming the directory in which the classes
are stored.
Finding Packages and CLASSPATH
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?

The answer has three parts.

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

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.
Example
For example, consider the following package specification:
package MyPack
In order for a program to find MyPack, one of three things must be true. Either the
program can be executed from a directory immediately above MyPack,
or
the CLASSPATH must be set to include the path to MyPack,
or
the -classpath option must specify the path to MyPack when the program is run via
java.
C:\MyPrograms\Java\MyPack
When the second two options are used, the class path must not include MyPack,
itself. It must simply specify the path to MyPack.

For example, in a Windows environment, if the path to MyPack is

C:\MyPrograms\Java\MyPack

then the class path to MyPack is

C:\MyPrograms\Java
The easiest way to try the examples shown in this book is to simply create the
package directories below your current development directory, put the .class files
into the appropriate directories, and then execute the programs from the
development directory. This is the approach used in the all the examples.
A Short Package Example
// A simple package
package MyPack;
class Balance {
String name;
double bal;
Balance(String n, double b) {
name = n;
bal = b;
}
void show() {
if(bal<0)
System.out.print("--> ");
System.out.println(name + ": $" + bal);
}
}
class AccountBalance {
public static void main(String args[]) {
Balance current[] = new Balance[3];
current[0] = new Balance("K. J. Fielding", 123.23);
current[1] = new Balance("Will Tell", 157.02);
current[2] = new Balance("Tom Jackson", -12.33);
for(int i=0; i<3; i++) current[i].show();
}
}
Call this file AccountBalance.java and put it in a directory called MyPack. Next, compile the
file. Make sure that the resulting .class file is also in the MyPack directory. Then, try
executing the AccountBalance class, using the following command line:
java MyPack.AccountBalance
Remember, you will need to be in the directory above MyPack when you execute this
Command.
(Alternatively, you can use one of the other two options described in the preceding
section to specify the path MyPack.)
As explained, AccountBalance is now part of the package MyPack. This means that it
cannot be executed by itself. That is, you cannot use this command line:
java AccountBalance
AccountBalance must be qualified with its package name.
Access Protection
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 for data and code.
The class is Java’s smallest unit of abstraction.
Because of the interplay between classes and packages, Java addresses four
categories of visibility for class members:
● Subclasses in the same package
● Non-subclasses in the same package
● Subclasses in different packages
● Classes that are neither in the same package nor subclasses
An Access Example
This example has two packages and five classes. Shows all combinations of the
access control modifiers.
Remember that the classes for the two different packages need to be stored in
directories named after their respective packages—in this case, p1 and p2.
The source for the first package P1 defines three classes:
Protection, Derived, and SamePackage. The first class defines four int variables
in each of the legal protection modes.
The variable n is declared with the default protection, n_pri is private, n_pro is
protected, and n_pub is public.
Each subsequent class in this example will try to access the variables in an instance
of this class.

The lines that will not compile due to access restrictions are commented out.
Before each of these lines is a comment listing the places from which this level of
protection would allow access.

The second class, Derived, is a subclass of Protection in the same package, p1.

This grants Derived access to every variable in Protection except for n_pri, the
private one.

The third class, SamePackage, is not a subclass of Protection, but is in the same
package and also has access to all but n_pri.
Package-P1
//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 = " + n);
System.out.println("n_pri = " + n_pri);
System.out.println("n_pro = " + n_pro);
System.out.println("n_pub = " + n_pub);
}
}
This is file Derived.java:
package p1;
class Derived extends Protection {
Derived() {
System.out.println("derived constructor");
System.out.println("n = " + n);
// class only
// System.out.println("n_pri = "4 + n_pri);
System.out.println("n_pro = " + n_pro);
System.out.println("n_pub = " + n_pub);
}
}
//This is file SamePackage.java:
package p1;
class SamePackage {
SamePackage() {
Protection p = new Protection();
System.out.println("same package constructor");
System.out.println("n = " + p.n);
// class only
// System.out.println("n_pri = " + p.n_pri);
System.out.println("n_pro = " + p.n_pro);
System.out.println("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();
}
}
Creating these files, Compiling and executing
– Create a folder named P1
– Navigate to P1
– Create Protection.java mentioning package as P1
– Create Derived.java mentioning package as P1
– Create SamePackage.java mentioning package as P1
– Create Demo.java mentioning package as P1.
– Move the parent directory of P1 (cd ..)
– Compile all the files as javac P1/*.java
– Run the file as java -classpath /root P1.Demo
Package-P2
//This is file Protection2.java:
package P2;
class Protection2 extends P1.Protection {
Protection2() {
System.out.println("derived other package constructor");
// class or package only
// System.out.println("n = " + n);
// class only
// System.out.println("n_pri = " + n_pri);
System.out.println("n_pro = " + n_pro);
System.out.println("n_pub = " + n_pub);
}
}
//This is file OtherPackage.java:
package P2;
class OtherPackage {
OtherPackage() {
P1.Protection p = new P1.Protection();
System.out.println("other package constructor");
// class or package only
// System.out.println("n = " + p.n);
// class only
// System.out.println("n_pri = " + p.n_pri);
// class, subclass or package only
// System.out.println("n_pro = " + p.n_pro);
System.out.println("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();
}
}
Creating these files, Compiling and executing
– Create a folder named P2
– Navigate to P2
– Create Protection2.java mentioning package as P2
– Create OtherPackage.java mentioning package as P2
– Create Demo.java mentioning package as P2.
– Move the parent directory of P2(cd ..)
– Compile all the files as javac P2/*.java
– Run the file as java -classpath /root P2.Demo
Importing Packages
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.

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 a Java source file, import statements occur immediately following the package
statement (if it exists) and before any class definitions.
This is the general form of the
import statement:
import pkg1 [.pkg2].(classname | *);
Here, pkg1 is the name of a top-level package, and pkg2 is the name 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. Finally, you specify either an explicit classname or a star (*), which
indicates that the Java compiler should import the entire package.
This code fragment shows both forms in use:
import java.util.Date;
import java.io.*
Example
Exception Handling
Exceptions
– An exception is an abnormal condition that arises in a code sequence at run time.

— In other words, an exception is a runtime error.

– In computer languages that do not support exception handling, errors must be

– checked and handled manually—typically through the use of error codes, and so on.

– This approach is as cumbersome as it is troublesome.

– Java’s exception handling avoids these problems and, in the process, brings run-time
error management into the object-oriented world.
– Java exception handling is managed via five keywords: try, catch, throw, throws,
and finally.
– Briefly, here is how they work.
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 a logical/smart
manner.
System-generated exceptions are automatically thrown by the Java runtime
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.
Example
Exception Types
All exception types are subclasses of the built-in class Throwable.
Thus, Throwable is at the top of the exception class hierarchy.
Immediately below Throwable are two subclasses that partition exceptions into two
distinct branches.

One branch is headed by Exception. This class is used for exceptional conditions
that user programs should catch.
This is also the class that you will subclass to create your own custom exception types.
There is an important subclass of Exception, called RuntimeException.
Exceptions of this type are automatically defined for the programs that you write and
include things such as division by zero and invalid array indexing.
The other branch is topped by Error, which defines exceptions that are not
expected to be caught under normal circumstances by your program.

Exceptions of type Error are used by the Java run-time system to indicate errors
having to do with the run-time environment, itself.

Stack overflow is an example of such an error.

This chapter will not be dealing with exceptions of type Error, because these are
typically created in response to catastrophic failures that cannot usually be
handled by your program.
Uncaught Exceptions
This small program includes an expression that intentionally causes a divide-by-zero
error:
class Exc0 {
public static void main(String args[]) {
int d = 0;
int a = 42 / d;
}
}
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 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 haven’t supplied any exception handlers of our own, so the
exception is caught by the default handler provided by the Java run-time system.
Any exception that is not caught by your program will ultimately be processed by the
default handler
Here is the exception generated when this example is executed:
java.lang.ArithmeticException: / by zero at Exc0.main(Exc0.java:4)

Notice how the class name, Exc0; the method name, main; the filename, Exc0.java;
and the line number, 4, are all included in the simple stack trace.

Also, notice that the type of exception thrown is a subclass of Exception called
ArithmeticException, which more specifically describes what type of error
happened
Stack trace
The stack trace will always
show the sequence of
method invocations that led
up to the error .

For example, here is another


version of the preceding
program that introduces the
same error but in a method
separate from main( ):
Using try and catch
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.

Second, it prevents the program from automatically terminating.


To 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.

To illustrate how easily this can be done, the following program includes a try block
and a catch clause that processes the ArithmeticException generated by the
division-by-zero error:
class Exc2 {
public static void main(String args[]) {
int d, a;
try { // monitor a block of code.
d = 0;
a = 42 / d;
System.out.println("This will not be printed.");
} catch (ArithmeticException e) { // catch divide-by-zero error
System.out.println("Division by zero.");
}
System.out.println("After catch statement.");
}
}
This program generates the following output:
Division by zero.
After catch statement.
Notice that 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 (except in the case
of nested
try statements, described shortly).
The statements that are protected by try must be surrounded by curly braces. (That is, they must
be within a block.) You cannot use try on a single statement.
// Handle an exception and move on.
Displaying a Description of an Exception
Throwable overrides the toString( ) method (defined by Object) so that it returns a
string containing a description of the exception.

You can display this description in a println( ) statement by simply passing the
exception as an argument.

For example, the catch block in the preceding program can be rewritten like this:
Multiple catch Clauses
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.
Example-2
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.
Try statements can be implicitly nested via
calls to methods.
throw
So far, you have only been catching exceptions that are thrown by the Java run-time
system.
It is possible for your program to throw an exception 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 subclass of


Throwable. Primitive 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 in a catch clause or
creating one with the new operator.
Caught inside demoproc.
Recaught:

Example
java.lang.NullPointerExce
ption: 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 the general form of a method declaration that includes a throws clause:
type method-name(parameter-list) throws exception-list
{
// body of method
}
Example
Example [with error]
finally
When exceptions are thrown, execution in a method takes a rather abrupt,
nonlinear path that alters the normal flow through the method.

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 issue.


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.

The finally clause is optional. However, each try statement requires at least one
catch or a finally clause.
Example
Java’s Built-in Exceptions
Creating Your Own Exception Subclasses

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy