Module - 4 - Oop With Java
Module - 4 - Oop With Java
BCS306A
Lecture Notes
Syllabus:
Packages: Packages, Packages and Member Access, Importing Packages.
Exceptions: Exception-Handling Fundamentals, Exception Types, Uncaught Exceptions, Using try and
catch, Multiple catch Clauses, nested try Statements, throw, throws, finally, Java’s Built-in Exceptions,
Creating Your Own Exception Subclasses, Chained Exceptions.
Packages
When we have more than one class in our program, usually we give unique names to classes. In a real- time
development, as the number of classes increases, giving unique meaningful name for each class will be a
problem. To avoid name-collision in such situations, Java provides a concept of packages.
A package is a collection of classes. 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. 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.
One 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]];
A package hierarchy must be reflected in the file system of your Java development system. For example, a
package declared as package [Link]; needs to be stored in java\awt\image in a Windows
environment. You cannot rename a package without renaming the directory in which the classes are stored.
Finding Packages and CLASSPATH
As we have seen, packages are reflected with directories. This will raise the question that - how does Java
run-time know where to look for the packages that we create?
• By default, Java run-time uses current working directory as a starting point. So, if our package is in
a sub-directory of current working directory, then it will be found.
• We can set directory path using CLASSPATH environment variable.
We can use –classpath option with javac and java to specify path of our classes
Assume that we have created a package MyPackage. When the second two options are used, the class path
must not include MyPackage. It must simply specify the path to MyPackage. For example, in a Windows
environment, if the path to MyPackage is
C:\MyPrograms\Java\MyPackage
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.
In a Java source file, import statements occur immediately following the package statement (if it exists)
and before any class definitions. The general form of the import statement is:
import pkg1[.pkg2].(classname|*);
For example,
import [Link];
import [Link].*;
All the standard Java classes included with Java are stored in a package called java. The basic language
functions are stored in a package inside of the java package called [Link]. Normally, you must import
every package or class that you want to use, but since Java is useless without much of the functionality in
[Link], it is implicitly imported by the compiler for all programs. This is equivalent to the following line
being at the top of all your programs:
import [Link].*;
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 must explicitly name the class specifying its package.
The import statement is optional. Any place you use a class name, you can use its fully qualified name,
which includes its full package hierarchy. For example,
import [Link].*;
class MyDate extends Date
{ ……………}
Can be written as –
class MyDate extends [Link]
{ …}
Develop a JAVA program to create a package named mypack and import & implement it in a suitable
class.
To create a Java package named mypack and import it in a suitable class, you can follow these steps in
Eclipse:
1. Open Eclipse and create a new Java project:
o Go to File > New > Java Project.
o Enter the project name, e.g., "MyPackageDemo," and click Finish.
2. Create a package named mypack:
o Right-click on the "src" folder within your project.
o Choose New > Package.
o Enter "mypack" as the package name and click Finish.
3. Create a class within the mypack package:
mypack/[Link]
package mypack; // Import the mypack package
import [Link];
public class Circle
{
public static void main(String[] args)
{
Scanner scanner = new Scanner([Link]);
[Link]("Enter the radius of the circle: ");
double radius = [Link]();
double area = calculateCircleArea(radius);
[Link]("The area of the circle is: " + area);
[Link]();
}
public static double calculateCircleArea(double radius)
{
return [Link] * radius * radius;
}
}
To use the mypack package in another class and calculate the area of a circle using the import statement,
you can follow these steps:
1. Create a new Java class in your project. Let's call it MainClass in a different package (e.g., myapp).
2. Import the mypack package in your MainClass and use it to calculate the area of a circle.
3. To run the program, right-click on the MainClass and select "Run As" > "Java Application."
myapp/[Link]
package myapp; // This is the package for MainClass
import [Link]; // Import the Circle class from mypack
public class MainClass
{
public static void main(String[] args)
{
Circle circle = new Circle(); // Create an instance of the Circle class
Sub packages: It is also possible to create sub packages for the main package like creating subfolders .
Syntax: package pack1.pack2;
Where pack1 is the main package and pack2 is the sub package.
Example:
package pack1;
public class X
{
public void show()
{
[Link](“Super”);
}
}
package pack1.pack2; // creating pack2 under the package pack1
public class Y
{
public void display()
{
[Link](“sub”);
}
}
import pack1.X ;
import pack1.pack2.Y;
class check
{
public static void main(String args[])
Even a class has accessibility feature. A class can be kept as default or can be declared as public. When a
class is declared as public, it is accessible by any other code. If a class has default access, then it can only
be accessed by other code within its same package. When a class is public, it must be theonly public
class declared in the file, and the file must have the same name as the class. Accessibility of members of the
class can be better understood using the following table.
A Java exception is an object that describes an exceptional (that is, error) condition that has occurred in a
piece of code. 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.
Exceptions thrown by Java relate to fundamental errors that violate the rules of the Java language or the
constraints of the Java execution environment. Manually generated exceptions are typically used to report
some error condition to the caller of a method.
Throwable
Exception Error
Customized Exception
(User defined class to
Runtime Exception I/O Exception
handle own)
Exceptions can be caught and handled by the program. When an exception occurs within a method, it creates
an object. This object is called the exception object. It contains information about the exception such as the
name and description of the exception and state of the program when the exception occurred.
Runtime Exception. A runtime exception happens due to a programming error. They are also known
asunchecked exceptions.
These exceptions are not checked at compile-time but run-time. Some of the common runtime exceptions
are:
IOException An IOException is also known as a checked exception. They are checked by the compiler at
the compile-time and the programmer is prompted to handle these exceptions.
Errors represent irrecoverable conditions such as Java virtual machine (JVM) running out of memory,
memory leaks, stack overflow errors, library incompatibility, infinite recursion, etc.
Errors are usually beyond the control of the programmer and we should not try to handle errors.
Any un-caught exception is handled by default handler. 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 exception generated when above example is executed:
The stack trace displays class name, method name, file name and line number causing the exception. Also,
the type of exception thrown viz. ArithmeticException which is the subclass of Exception is displayed. The
type of exception gives more information about what type of error has occurred. The stacktrace will always
show the sequence of method invocations that led up to the error.
class Exc1
{
static void subroutine()
{
int d = 0;
int a = 10 / d;
}
public static void main(String args[])
{
[Link]();
}
}
To handle run-time error, we need to enclose the suspected code within try block.
class Exc2
{
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.
class MultiCatch
{
public static void main(String args[])
{
try
{
int a = [Link];
[Link]("a = " + a);
int b = 42 / a;
int c[] = { 1 };
c[42] = 99;
}
catch(ArithmeticException e)
{
[Link]("Divide by 0: " + e);
}
catch(ArrayIndexOutOfBoundsException e)
{
[Link]("Array index : " + e);
}
[Link]("After try/catch blocks.");
}
}
Here is the output generated by running it both ways:
C:\>java MultiCatch
a=0
Divide by 0: [Link]: / by zero
After try/catch blocks.
C:\>java MultiCatch TestArg
a=1
Array index : [Link]
After try/catch blocks.
class SuperSubCatch
{
public static void main(String args[])
{
try
{
int a = 0;
int b = 42 / a;
}
catch(Exception e)
{
[Link]("Generic Exception catch.");
}
catch(ArithmeticException e) // ERROR - unreachable
{
[Link]("This is never reached.");
}
}
}
The above program generates error “Unreachable Code”, because ArithmeticException is a subclass of
Exception.
}
catch(ExceptionType1 e1)
{
// child catch block
}
}
catch (ExceptionType2 e1)
{
// parent catch block
}
Output:
In the following example, we're creating an error by dividing a value by 0 in nested try block but we're not
handling in corresponding catch block. As parent try block is handling the exception raised as generic
exception, it captures the exception raised by child catch block and prints the same.
Output:
In the following example, we're creating an error by dividing a value by 0 in nested try block but we're not
handling this kind of exception in any catch block. Now JVM will capture the exception and terminate the
program without printing the last statement.
package [Link];
public class ExcepTest
{
public static void main(String args[])
{
try
{
int a[] = new int[2];
try
{
int b = 0;
int c = 1/b;
}
catch(ArrayIndexOutOfBoundsException e)
{
[Link]("Exception thrown: " + e);
}
[Link]("Access element three :" + a[3]);
}
catch (ArrayIndexOutOfBoundsException e)
{
[Link]("Exception thrown: " + e);
}
[Link]("Out of the block");
}
}
Output:
Exception in thread "main" [Link]: / by zero at
[Link]([Link])
When the second form is used, the argument specifies a string that describes the exception.
throws
If a method can cause 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.
Output:
Number cannot be divided by e
Rest of the code..
The finally clause creates a block of code that will be executed after a try/catch block has completed and
before the next code of 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.
The finally clause is optional. However, each try statement requires at least one catch or a finally clause.
class TestFinallyBlock
{
public static void main(String args[])
{
try
{
//below code do not throw any exception
int data=25/5;
[Link](data);
}
Output:
5
Finally block is always executed
rest of the code...
Case 2: When an exception occur but not handled by the catch block
class Demo
{
static void sum(int a,int b) throws MyException
Prof KALIDASS M, Dept of AIML SSCE, Anekal
{
if(a<0)
{
throw new MyException(a); //calling constructor of user-defined exception class
}
else
{
[Link](a+b);
}
}
Although Java’s built-in exceptions handle most common errors, sometimes we may want to create our own
exception types to handle situations specific to our applications. This is achieved by defining a subclass of
Exception class. Your subclasses don’t need to actually implement anything—it is their existence in the
type system that allows you to use them as exceptions. The Exception class does not define any methods of
its own. It inherits those methods provided by Throwable. Thus, all exceptions, including those that you
create, have the methods defined by Throwable available to them.
Method Description
Throwable fillInStackTrace( ) Returns a Throwable object that contains a completedstack
trace. This object can be re-thrown.
Throwable getCause( ) Returns the exception that underlies the current [Link]
there is no underlying exception, null is returned.
String getLocalizedMessage( ) Returns a localized description of the exception.
void setStackTrace( Sets the stack trace to the elements passed in elements.
StackTraceElement This method is for specialized applications, not normal
elements[ ]) use.
We may wish to override one or more of these methods in exception classes that we create. Two of the
constructors of Exception are:
Exception( )
Exception(String msg)
Though specifying a description when an exception is created is often useful, sometimes it is better to
override toString( ). The version of toString( ) defined by Throwable (and inherited by Exception) first
displays the name of the exception followed by a colon, which is then followed by your description. By
overriding toString( ), you can prevent the exception name and colon from being displayed. This makes for
a cleaner output, which is desirable in some cases.
MyException (int m)
{
marks=m;
}
[Link]("Normal exit");
}
Example: ArithmeticException was thrown by the following program but the real cause of exception was
IOException.
import [Link];
public class ChainedException
{
public static void divide(int a, int b)
{
if(b == 0)
{
ArithmeticException ae = new ArithmeticException("top layer");
[Link](new IOException("cause"));
throw ae;
}
else
{
[Link](a/b);
}
}
Chained exceptions can be carried on to whatever depth is necessary. Thus, the cause exception can, itself,
have a cause. Be aware that overly long chains of exceptions may indicate poor design. Chained exceptions
are not something that every program will need. However, in cases in which knowledge of an underlying
cause is useful, they offer an elegant solution.
Using Exceptions
Exception handling provides a powerful mechanism for controlling complex programs that have many
dynamic run-time characteristics. It is important to think of try, throw, and catch as clean ways to handle
errors and unusual boundary conditions in your program’s logic. Unlike some other languages in which
error return codes are used to indicate failure, Java uses exceptions. Thus, when a method can fail, have it
throw an exception. This is a cleaner way to handle failure modes.
Note that Java’s exception-handling statements should not be considered a general mechanism for
nonlocal branching. If you do so, it will only confuse yo`ur code and make it hard to maintain.
import [Link];
[Link]();
if (denominator == 0)
{
throw new DivisionByZeroException("Division by zero is
not allowed.");
}
Output: