Advanced Java
Advanced Java
Programming paradigms are different ways or styles in which a given program or programming
language can be organized. Each paradigm consists of certain structures, features, and opinions
about how common programming problems should be tackled.
Different types of programming paradigms are needed due to certain paradigms better suited for
certain types of problems. Moreover, having advancements in hardware and software, it is
required to update the paradigms over time.
It is necessary to know that programming paradigms are not the same to programming languages
or tools. It is more of a set of ideals or guidelines that many people have agreed on, followed,
and expanded upon. That means you cannot build anything with a paradigm. Programming
languages aren't always tied to a specific paradigm. There are languages that have been built with
a certain paradigm in mind and have features that facilitate that kind of programming more than
others (functional programming is a good example).
But there are also multi-paradigm languages, meaning you can adapt your code to fit a certain
paradigm or another (JavaScript and Python are good examples).At the same time, programming
paradigms aren't mutually exclusive, in the sense that you could use practices from different
paradigms at the same time with no problem at all.
Example:
a. Say you want to bake a cake, your imperative program to do this might look like this:
Pour flour in a bowl
Pour a couple eggs in the same bowl
Pour some milk in the same bowl
Mix the ingredients
Pour the mix in a mold
Cook for 35 minutes
Let chill
b. Assume we want to filter an array of numbers to only keep the elements larger than 5, the
following is an imperative code:
function pourIngredients() {
- Pour flour in a bowl
- Pour a couple eggs in the same bowl
- Pour some milk in the same bowl
}
function mixAndTransferToMold() {
- Mix the ingredients
- Pour the mix in a mold
}
function cookAndLetChill() {
- Cook for 35 minutes
- Let chill
}
pourIngredients()
mixAndTransferToMold()
cookAndLetChill()
Here, the user is encouraged to subdivide the program execution into functions, as a way of
improving modularity and organization.
You can note that, we could just read the three function calls at the end of the file and get a good
idea of what our program does. That simplification and abstraction is one of the benefits of
procedural programming. But within the functions, we still got same old imperative code.
3. Functional Programming
Functional programming takes the concept of functions a little bit further. In functional
programming, functions are treated as first-class citizens, meaning that they can be assigned to
variables, passed as arguments, and returned from other functions.
Going back to the array filtering example above, we can transform that imperative programming
into functional programming as follows:
4. Declarative Programming
Declarative programming is all about hiding away complexity and bringing programming
languages closer to human language and thinking. It’s the direct opposite of imperative
programming in the sense that the programmer doesn't give instructions about how the
computer should execute the task, but rather on what result is needed.
For example, taking the array filtering example above, it can be changed to a declarative
programming as follows:
5. Structured programming
Structured programming paradigms are based on the top-down methodology in which a system is
further divided into compositional subsystem. It is not only limited to the top down approach.
It employs methods using: -
Top-down analysis for problem solving: It focuses on dividing the problem into sub parts
and hence simplifies the problem solving.
Modularization for program structure and organization: It organizes large instructions by
breaking them into separate and smaller section of modules, sub routines and
subprograms.
Structured code for the individual modules: Control structures are used to determine the
exact order in which the set of instructions are to be executed. Therefore, a structured
code does not involve GOTO statement as it represents no certain order of execution.
Structured programming caught favor with programming languages for its iconic opposition to
the keyword goto, aiming to reduce the prevalence of spaghetti code. Some other controversial
features that most languages have not adopted are avoiding early exit and opposition to
exceptions for control flow.
Block: It is a command or a set of commands that the program executes linearly. The
sequence has a single point of entry (first line) and exit (last line).
Selection: It is the branching of the flow of control based on the outcome of a condition.
Two sequences are specified: the 'if' block when the condition is true and the 'else' block
when it is false. The 'else' block is optional and can be a no-op.
Iteration: It is the repetition of a block as long as it meets a specific condition. The
evaluation of the condition happens at the start or the end of the block. When the
condition results in false, the loop terminates and moves on to the next block.
Nesting: The above building blocks can be nested because conditions and iterations,
when encapsulated, have singular entry-exit points and behave just like any other block.
Subroutines: Since entire programs now have singular entry-exit points, encapsulating
them into subroutines allows us to invoke blocks by one identifier.
Opposed to imperative programming, all units of work are broken into smaller tractable parts -
that is when functions came into existence and programming became a hierarchy of functions
and many at lower level could be re-used.
OOP makes heavy usage of classes (which are a way of creating new objects starting out from a
blueprint or boilerplate that the programmer sets). Objects that are created from a class are called
instances.
Following our pseudo-code cooking example, now let's say in our bakery we have a main cook
(called Frank) and an assistant cook (called Anthony) and each of them will have certain
responsibilities in the baking process. If we used OOP, our program might look like this.
class Cook {
constructor constructor (name) {
this.name = name
}
mixAndBake() {
- Mix the ingredients
- Pour the mix in a mold
- Cook for 35 minutes
}
}
class AssistantCook {
constructor (name) {
this.name = name
}
pourIngredients() {
- Pour flour in a bowl
- Pour a couple eggs in the same bowl
- Pour some milk in the same bowl
}
chillTheCake() {
- Let chill
}
}
// Instantiate an object from each class
const Frank = new Cook('Frank')
const Anthony = new AssistantCook('Anthony')
// Call the corresponding methods from each instance
Anthony.pourIngredients()
Frank.mixAndBake()
Anthony.chillTheCake()
Assume you want to create a video game, you need something that will hold details of the
player/s such as name, health-status, and skill. you can easily store this information if the number
of players is too limited. The problem starts when this number starts to grow. One of these
problems is that you may make a mistake when you create a player, as there is no common
standard telling what makes up a player. You may even misspell a property of a player, which is
very difficult to catch. The other problem is that assume you want to add or remove another
property, you have to search the players that you have created in your code and add/ remove this
property one by one. This doesn’t seem a good idea.
Better idea would be to have a player “factory”. Some function or something where you can just
input some data and receive a player object as an output. This means you don’t have to duplicate
so much code and you will minimize spelling mistakes. Moreover, if you want to add another
property, you don’t have to edit it everywhere, rather you have to just update the player factory.
That means, updating the players factory will let you update all the players. This scenario in
object-oriented programming is the concept of classes.
Classes allow us to create factories for objects that have the same properties but different data.
They allow us to define a shape or a blue print of how our player object should look like.For
example, using a class the above scenario would have the following code:
Class Player{
public void Player(String name, int health, String skill){
this.name = name;
this.health = health;
this.skill = skill;
}}
Player chala = new Player(“Chala”, 85, “Programmer”);
Player fikadu = new Player(“Fikadu”, 95, “Investor”);
Player moges = new Player(“Moges”, 80, “Merchant”);
System.out.println(fikadu.skill);
Note that this keyword is used to refer to the properties and methods inside the class.
1. Encapsulation
OOP helps you to combine a group related variables and functions into a unit. This unit is called
Object. These variables are called Properties, and the functions are called Methods. This is what
is called Encapsulation.
Encapsulation is achieved when each object keeps its state private, inside a class. Other objects
don’t have direct access to this state. Instead, they can only call a list of public functions —
called methods.
So, the object manages its own state via methods — and no other class can touch it unless
explicitly allowed. If you want to communicate with the object, you should use the methods
provided. But (by default), you can’t change the state.
Let us think of a DVD player as an object. This DVD player has a complex logic board on the
inside and a few buttons on the outside that you interact with. You simply press the play button
and you don’t care what happens on the inside. All that complexity is hidden from you. This is
what we call abstraction. That means, we can hide some of the properties and methods from the
outside and this gives us a couple of benefits. First, it will make the interface of those object
simpler. Using and understanding an object with a few properties and methods is easier than an
object with several properties and methods. The second benefit is that it reduces the impact of
change. Let’s say you want to change these inner or private methods. None of these changes will
leak to the outside. This is because we don’t have any code that touches these methods outside of
their containing object. We may delete a method or change its parameters, but none of these
changes will impact the rest of the applications code.
3. Inheritance
Objects are often very similar. They share common logic. But they’re not entirely the same. So
how do we reuse the common logic and extract the unique logic into a separate class? One
way to achieve this is inheritance. It means that you create a (child) class by deriving from
another (parent) class. This way, we form a hierarchy. The child class reuses all fields and
methods of the parent class (common part) and can implement its own (unique part).
Inheritance is a mechanism that allows you to eliminate redundant code. Instead of redefining
methods and properties, we can define it in a generic object and have other objects inherit these
properties and methods.
Polymorphism is a technique that allows you to get rid of long if and else or switch and case
statements.
Benefits of OOP
The benefits of OOP reside over its four pillars.
Encapsulation: lets you group related variables and functions together. This way we can reduce
complexity.And now, we can re-use this object in different part of a program or in different
programs. (Reduce Complexity + Increase Re-usability)
Abstraction: will let you hide the details and the complexity and show only the essentials.
(Reduce Complexity + Isolate impact of changes)
1. abstract: Java abstract keyword is used to declare an abstract class. An abstract class can
provide the implementation of the interface. It can have abstract and non-abstract methods.
But note that abstract method belongs to an abstract class, and it has NO BODY/
implementation. The body is provided by the subclass.
Note that:
a. the abstract keyword is a non-access modifier, used for classes and methods
b. If a class is abstract, it cannot be instantiated. It is a restricted class.
c. Abstract methods only belong to abstract class
d. If a class has to inherit abstract class, it has to either be an abstract or implement all
member abstract methods.
e. An abstract keyword cannot be used with variables and constructors
f. An abstract class can contain constructors and static methods
g. We cannot use the abstract keyword with the final.
h. We can declare the abstract method with a throw clause.
i. We cannot declare abstract methods as private.
j. We cannot declare abstract methods as static.
k. An abstract method can't be synchronized.
Example:
abstract class Main {
public String fname = "Bizuneh";
public int id=3204;
public int age = 24;
public abstract void study(); // abstract method
}
// Subclass (inherit from Main)
class Student extends Main {
public int graduationYear = 2018;
public void study() { // implementation of abstract method
System.out.println("Studying all day long");
}
}
class Second {
public static void main(String[] args) {
// create an object of the Student class (which inherits attributes and methods from Main)
Student myObj = new Student();
System.out.println("Name: " + myObj.fname);
System.out.println("Age: " + myObj.age);
System.out.println("Graduation Year: " + myObj.graduationYear);
myObj.study(); // calling the abstract method
}
}
2. Final: is a non-access modifier used for classes, attributes and methods, which makes them non-
changeable. It stops value change, method overriding, and inheritance. The final keyword is
useful when you want a variable to always store the same value, like PI (3.14159...).
a. Variable
If you make any variable as final, you cannot change the value of final variable(It will be
constant).
Example:
class Car{
final int speedlimit=30;//final variable
void run(){
speedlimit=80; //this will raise a compile time error
}
public static void main(String args[]){
Car obj=new Car();
obj.run();
}
}
b. Method
If you make any method as final, you cannot override it.
class Car{
final void run(){
System.out.println("running");
}
}
class Vitz extends Car{
void run(){//This will raise a compile time error
System.out.println("running with 100km/h");
}
public static void main(String args[]){
Vitz vit= new Vitz();
vit.run();
}
}
c. Class
If you make any class as final, you cannot extend it.
final class Car{
}
class Vitz extends Car{//This will raise a compile time error
void run(){
System.out.println("running with 100kmph");}
public static void main(String args[]){
Vitz vit= new Vitz();
vit.run();
}
}
Note that:
a. Final method can be inherited but it can not be overridden.
System.out.println("running..."); System.out.println("running...");}
}} }
public static void main(String args[]){ public static void main(String args[]){
} new Vitz().run();
{ }
}}
b. If you want to create a variable that is initialized at the time of creating object and once
initialized may not be changed, you can use what we call blank or uninitialized final
variable. Then, it can only be initialized in a constructor.
class Car{
final int carPlate;//blank final variable
Car(){
carPlate=70456;
System.out.println(carPlate);
}
public static void main(String args[]){
new Car();
}
}
c. We cannot declare a constructor as final, since constructor is never inherited it is
overloaded.
3. Static: It belongs to the class than an instance of the class.Static methods/attributes can be
accessed without creating an object of a class. Java static property is shared to all objects.
Example:
class Student{
int id;//instance variable
String name;
static String department ="IT";//static variable
//constructor
Student(int i, String n){
id = i;
name = n;
}
void display (){
System.out.println(id+" "+name+" "+department);}
}
public class TestStaticMembers{
public static void main(String args[]){
Student s1 = new Student(01125,"Eyob");
Student s2 = new Student(02243,"Iman");
s1.display();
s2.display();
}
}
b. Method (also known as a class method)
A static method belongs to the class rather than the object of a class. It can be invoked without
the need for creating an instance of a class. It can also access static data member and can change
the value of it.
Example:
class Student{
int id;//instance variable
String name;
static String department ="IT";//static variable
//constructor
Student(int i, String n){
id = i;
name = n;
}
static void change(){
department = “IS”;
}
void display (){
System.out.println(id+" "+name+" "+department);}
}
public class TestStaticMembers{
public static void main(String args[]){
Student.change();// No instance is needed
Student s1 = new Student(01125,"Eyob");
Student s2 = new Student(02243,"Iman");
s1.display();
s2.display();
}
}
Remember that:
Static method cannot use non static data member or call non static method directly
this and super keyword cannot be used in static context
c. Block
Static block is used to initialize the static data member.It is executed before the main method at
the time of classloading.
Example:
class StaticBlock{
static{System.out.println("static block is invoked");}
public static void main(String args[]){
System.out.println("main method is invoked");
}
}
4. super: used to refer to immediate superclass (parent) objects. It is used to call superclass
methods, and to access the superclass constructor. Whenever you create the instance of subclass,
an instance of parent class is created implicitly which is referred by super reference variable.
The most common use of the super keyword is to eliminate the confusion between super
classes and subclasses that have methods with the same name.
Example:
class Animal{
String color="white";
}
class Dog extends Animal{
String color="black";
void printColor(){
System.out.println(color);//prints color of Dog class
System.out.println(super.color);//prints color of Animal class
}
}
class TestSuper1{
public static void main(String args[]){
Dog d=new Dog(); // here, object of Animal class is also created
d.printColor();
}}
Note that super keyword is used to:
Referimmediate parent class instance variable.
Invokeimmediate parent class method.
Invokeimmediate parent class constructor.
5. this: refers to the current object in a method or constructor. The most common use of this
keyword is to eliminate the confusion between class attributes and parameters with the same
name (because a class attribute is shadowed by a method or constructor parameter).
Example:
class Student{
int id;//instance variable
String name;
static String department ="IT";//static variable
//constructor
Student(int id, String name){
this.id = id;
this.name = name;
}
void display (){
System.out.println(id+" "+name+" "+department);}
}
public class TestStaticMembers{
public static void main(String args[]){
Student s1 = new Student(01125,"Eyob");
Student s2 = new Student(02243,"Iman");
s1.display();
s2.display();
}
}
1. Syntax Errors
Syntax Errors are those errors detected during the compilation phase by the compiler when your
code does not follow the syntactical rules of the programming language you are using. e.g,
missing semi-colon(s), or missing parenthesis.
2. Runtime Errors
Runtime Errors occur during the execution of a program, due to lack of system resources, or due
to irrelevant input by the user. The compiler has no idea whatsoever how to detect these kinds of
errors. For example, dividing a number by 0, accessing an element from an array that is out of
range, trying to convert an invalid string to an integer, out of memory error, etc
3. Logical Errors
Logical Errors are those errors where the program returned incorrect results when you were
expecting the desired result. These occur due to some mistake in the code logic made by the
programmer. The compiler cannot detect these errors. The user can just understand them after
seeing the output. These are also known as Semantic Errors.
For example, When the programmer writes mistakenly, if( i = 1) instead of, if(i == 1): This will
change the program's narrative.
Exceptions
During code execution, different errors can occur. When an error occurs, Java will normally stop
and generate an error message. That means java will throw an exception (it will throw an
error).
Exception is unexpected event, which occurs during the execution of a program, i.e., at run time,
that disrupts the normal flow of the program’s instructions. 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 the state of the program when the exception occurred.
The key differences between Error and Exception is that an error indicates a serious problem that
a reasonable application should not try to catch, while exception indicates that a reasonable
application might try to catch.
The following is comparison between an error and an exception.
Error Exception
An error cannot be handled at runtime. An exception can be handled at runtime
An error can occur both at compile time Although all the Exceptions occur at
and during runtime. runtime. But checked Exceptions can
be detected at compile time.
There are 3 types of Errors: Syntax There are 2 types of Exceptions:
Error, Runtime Error and Logical Error Checked Exceptions and Unchecked
Exceptions
An error has the capacity to terminate An exception has the capacity to
your program and maybe your system distract the normal flow of the program
as well. and change its direction to somewhere
else when an exceptional case has
occurred.
An Error is such an event that no one An Exception can be guessed, handled,
can control or guess when it is going to and utilized in order to change the
happen. original flow of the program.
An Error can be thought of as an An Exception can be thought of as a
explosion that happens when there is no last line of defense to prevent errors.
defense or checks against a particular
failure condition.
Types of Exceptions
1. Checked Exception
Checked exceptions are called compile-time exceptions because these exceptions are checked at
compile-time by the compiler. Example: IOException, SQLException, etc.
2. Unchecked Exception
The compiler will not check these exceptions at compile time. In simple words, if a program
throws an unchecked exception, and even if we didn’t handle or declare it, the program would
not give a compilation error. Example, ArithmeticException, NullPointerException,
ArrayOutOfBoundsException, etc. These exceptions are checked at runtime.
Exception Handling
Java exception handling is managed using 5 keywords (try, catch, throw, throws and finally).
Program statements that you think can raise 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 block) and handle it in some rational manner.
System-generated exceptions are automatically thrown by the Java run-time system (JVM). 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.
The try statement allows you to define a block of code to be tested for errors while it is
being executed.
The catch statement allows you to define a block of code to be executed, if an error
occurs in the try block.
The finally statement lets you execute code, after try...catch, regardless of the result
The throw statement allows you to create a custom error.
Example:
Priority: Priority of each thread lies between 1 to 10. If a thread has a higher priority, it means
that thread has got a better chance of getting picked up by the thread scheduler.
Time of Arrival: Suppose two threads of the same priority enter the runnable state, then priority
cannot be the factor to pick a thread from these two threads. In such a case, arrival time of thread
is considered by the thread scheduler. A thread that arrived first gets the preference over the
other threads.
First Come First Served (FCFS): the scheduler picks the threads that arrive first in the
runnable queue
Time-slicing Scheduling: FCFS is non-preemptive, which can lead to infinite block. To
avoid this, some time-slices are provided to the threads so that after some time, the
running thread has to give up a CPU. Thus, the other waiting threads also get time to run
their job.
Preemptive-Priority Scheduling: Suppose there are multiple threads available in the
runnable state. The thread scheduler picks that thread that has the highest priority. Since
the algorithm is also preemptive, therefore, time slices are also provided to the threads to
avoid starvation. Thus, after some time, even if the highest priority thread has not
completed its job, it has to release the CPU because of preemption.
The thread scheduler selects the thread that has the highest priority, and the thread begins the
execution of the job. If a thread is already in runnable state and another thread (that has higher
priority) reaches in the runnable state, then the current thread is pre-empted from the
processor, and the arrived thread with higher priority gets the CPU time.
When there are two threads having the same priorities and arrival time, the scheduling will be
decided on the basis of FCFS algorithm. Thus, the thread that arrives first gets the opportunity to
execute first.
Note:
You cannot start a thread twice. If you do so, an IllegalThreadStateException is thrown.
In such case, thread will run once but for second time, it will throw exception.
Daemon Thread
Daemon thread in Java is a service provider thread that provides services to the user thread. Its
life depends on the mercy of user threads i.e., when all user threads die, JVM terminates this
thread automatically. There are many java daemon threads running automatically e.g. gc,
finalizer etc. It is a low priority thread.
Collections in Java
The Collection in Java is a framework that provides an architecture to store and manipulate the
group of objects. That means, it represents a single unit of objects, as a group.
Java Collections can achieve all the operations that you perform on a data such as searching,
sorting, insertion, manipulation, and deletion.
ArrayList
The ArrayList class implements the List interface. It uses a dynamic array to store the
duplicate element of different data types. The ArrayList class maintains the insertion order and
is non-synchronized. The elements stored in the ArrayList class can be randomly accessed.
LinkedList
LinkedList implements the Collection interface. It uses a doubly linked list internally to store the
elements. It can store the duplicate elements. It maintains the insertion order and is not
synchronized.
Vector
Vector uses a dynamic array to store the data elements. It is similar to ArrayList. However, it is
synchronized and contains many methods that are not the part of Collection framework.
Stack
The stack is the subclass of Vector. It implements the last-in-first-out data structure, i.e., Stack.
The stack contains all of the methods of Vector class and also provides its methods like boolean
push(), boolean peek(), boolean push(object o), which defines its properties. It uses push() not
add() to add elemets to the stack. The pop() method removes and returns the top element of the
stack. An ‘EmptyStackException’ will be thrown if you attempt to pop from empty stack
Queue Interface
Queue interface maintains the first-in-first-out order. It can be defined as an ordered list that is
used to hold the elements which are about to be processed. There are various classes like
PriorityQueue, Deque, and ArrayDeque which implements the Queue interface.
The PriorityQueue class implements the Queue interface. It holds the elements or objects which
are to be processed by their priorities. PriorityQueue doesn't allow null values to be stored in
the queue.
Methods:
add(): In order to add an element in a priority queue. The insertion order is not retained.
remove(): In order to remove an element from a priority queue
poll(): In order to remove an element from a priority queue and return it
peek(): In order to access the head of the queue
Deque Interface
Deque interface extends the Queue interface. In Deque, we can remove and add the elements
from both sides. Deque stands for a double-ended queue which enables us to perform the
operations at both ends.
ArrayDeque
ArrayDeque class implements the Deque interface. It facilitates us to use the Deque. Unlike
queue, we can add or delete the elements from both the ends. ArrayDeque is faster than
ArrayList and Stack and has no capacity restrictions.
Methods:
MCQs
1. . Which feature of OOP indicates code reusability?
a. Abstraction
b. Polymorphism
c. Encapsulation
d. Inheritance
2. Which among the following doesn’t come under OOP concept?
a. Data hiding
b. Message passing
c. Platform independency
d. Data binding
3. Which feature of OOP is indicated by the following code?
Class Student{
int marks;
}
class Topper extends Student{
private int age;
public topper(int age){
this.age=age;
}
}
a. Encapsulation and Inheritance
b. Inheritance and polymorphism
c. Polymorphism
d. Inheritance
4. Which among the following, for a pure OOP language, is true?
a. The language should follow at least 1 feature of OOP
b. The language must follow only 3 features of OOP
c. The language must follow all the rules of OOP
d. The language should follow 3 or more features of OOP
5. In multilevel inheritance, which is the most significant feature of OOP used?
a. Code efficiency
b. Code readability
c. Flexibility
d. Code reusability
6. What is encapsulation in OOP?
a. It is a way of combining various data members and member functions into a
single unit which can operate on any data
b. It is a way of combining various data members into a single unit
c. It is a way of combining various member functions into a single unit
d. It is a way of combining various data members and member functions that operate
on those data members into a single unit
7. Which of the following is a type of polymorphism in Java?
a. Compile time polymorphism
b. Execution time polymorphism
c. Multiple polymorphism
d. Multilevel polymorphism
8. When does method overloading is determined?
a. At run time
b. At compile time
c. At coding time
d. At execution time
9. When Overloading does not occur?
a. More than one method with same name but different method signature and
different number or type of parameters
b. More than one method with same name, same signature but different number of
signature
c. More than one method with same name, same signature, same number of
parameters but different type
d. More than one method with same name, same number of parameters and type but
different signature
10. Which concept of Java is a way of converting real world objects in terms of class?
a. Polymorphism
b. Encapsulation
c. Abstraction
d. Inheritance
11. Which concept of Java is achieved by combining methods and attribute into a class?
a. Encapsulation
b. Inheritance
c. Polymorphism
d. Abstraction
12. Method overriding is combination of inheritance and polymorphism?
a. True
b. False
13. When does Exceptions in Java arises in code sequence?
a. Run Time
b. Compilation Time
c. Can Occur Any Time
d. None of the mentioned
14. Which of these keywords is used to deal with an exception manually?
a. try
b. finally
c. throw
d. catch
15. What will be the output of the following Java program?
class exception_handling
{
public static void main(String args[]) {
try {
System.out.print("Hello" + " " + 1 / 0);
} catch(ArithmeticException e) {
System.out.print("World");
} } }
a. Hello Exception Statement
b. Exception Statement World
c. World
d. Hello World
16. What will be the output of the following Java program?
public class exception_handling {
public static void main(String args[]) {
try {
int a, b;
b = 0;
System.out.print("A");
a = 5 / b; }
catch(ArithmeticException e) {
System.out.print("B"); } }}
a. A
b. Compilation Error
c. AB
d. Runtime Error