Final Exam Questions
Final Exam Questions
1. What is Java?
2. What are the differences between C++ and Java?
3. List the features of Java Programming language.
4. What do you understand about Java virtual machine?
5. What is the difference between JDK, JRE, and JVM?
6. What are the various access specifiers in Java?
7. What is the purpose of static methods and variables?
8. What are the advantages of Packages in Java?
9. What is the output of the following Java program?
class Test
{
public static void main (String args[])
{
System.out.println(10 + 20 + "Javatpoint");
System.out.println("Javatpoint" + 10 + 20);
}
}
If subclass (child class) has the same method as declared in the parent class, it is known as method
overriding in Java.
In other words, If a subclass provides the specific implementation of the method that has been declared by
one of its parent class, it is known as method overriding.
Usage of Java Method Overriding
o Method overriding is used to provide the specific implementation of a method which is already
provided by its superclass.
o Method overriding is used for runtime polymorphism
Understanding the problem without method overriding
Let's understand the problem that we may face in the program if we don't use method overriding.
1. //Java Program to demonstrate why we need method overriding
2. //Here, we are calling the method of parent class with child
3. //class object.
4. //Creating a parent class
5. class Vehicle{
6. void run(){System.out.println("Vehicle is running");}
7. }
8. //Creating a child class
9. class Bike extends Vehicle{
10. public static void main(String args[]){
11. //creating an instance of child class
12. Bike obj = new Bike();
13. //calling the method with child class instance
14. obj.run();
15. }
16. }
Test it Now
Output:
Vehicle is running
Problem is that I have to provide a specific implementation of run() method in subclass that is why we use
method overriding.
1. //Java Program to illustrate the use of Java Method Overriding
2. //Creating a parent class.
3. class Vehicle{
4. //defining a method
5. void run(){System.out.println("Vehicle is running");}
6. }
7. //Creating a child class
8. class Bike2 extends Vehicle{
9. //defining the same method as in the parent class
10. void run(){System.out.println("Bike is running safely");}
11.
12. public static void main(String args[]){
13. Bike2 obj = new Bike2();//creating object
14. obj.run();//calling method
15. }
16. }
Test it Now
Output:
1. //Java Program to demonstrate the real scenario of Java Method Overriding
2. //where three classes are overriding the method of a parent class.
3. //Creating a parent class.
4. class Bank{
5. int getRateOfInterest(){return 0;}
6. }
7. //Creating child classes.
8. class SBI extends Bank{
9. int getRateOfInterest(){return 8;}
10. }
11.
12. class ICICI extends Bank{
13. int getRateOfInterest(){return 7;}
14. }
15. class AXIS extends Bank{
16. int getRateOfInterest(){return 9;}
17. }
18. //Test class to create objects and call the methods
19. class Test2{
20. public static void main(String args[]){
21. SBI s=new SBI();
22. ICICI i=new ICICI();
23. AXIS a=new AXIS();
24. System.out.println("SBI Rate of Interest: "+s.getRateOfInterest());
25. System.out.println("ICICI Rate of Interest: "+i.getRateOfInterest());
26. System.out.println("AXIS Rate of Interest: "+a.getRateOfInterest());
27. }
28. }
Test it Now
Output:
SBI Rate of Interest: 8
ICICI Rate of Interest: 7
AXIS Rate of Interest: 9
2) Method overloading occurs Method overriding occurs in two classes that have
within the class. IS-A relationship between them.
3) In this case, the In this case, the parameters must be the same.
parameters must be different.
45. What is the output of the following Java program? Explain it.
class Base
{
void method(int a)
{
System.out.println("Base class method called with integer a = "+a);
}
void method(double d)
{
System.out.println("Base class method called with double d ="+d);
}
}
The method() is overloaded in class Base whereas it is derived in class Derived with
the double type as the parameter. In the method call, the integer is passed.
46. What is the output of the following Java program? Explain it.
class Base
{
public void baseMethod()
{
System.out.println("BaseMethod called ...");
}
}
class Derived extends Base
{
public void baseMethod()
{
System.out.println("Derived method called ...");
}
}
public class Test
{
public static void main (String args[])
{
Base b = new Derived();
b.baseMethod();
}
}
Output: Derived method called ...
Explanation:
The method of Base class, i.e., baseMethod() is overridden in Derived class. In Test
class, the reference variable b (of type Base class) refers to the instance of the Derived class.
Here, Runtime polymorphism is achieved between class Base and Derived. At compile time, the
presence of method baseMethod checked in Base class, If it presence then the program compiled
otherwise the compiler error will be shown. In this case, baseMethod is present in Base class;
therefore, it is compiled successfully. However, at runtime, It checks whether the baseMethod
has been overridden by Derived class, if so then the Derived class method is called otherwise
Base class method is called. In this case, the Derived class overrides the baseMethod; therefore,
the Derived class method is called.
47. What is the final variable?
In Java, the final variable is used to restrict the user from updating it. If we initialize the final
variable, we can't change its value. In other words, we can say that the final variable once
assigned to a value, can never be changed after that. The final variable which is not assigned to
any value can only be assigned through the class constructor.
1. class Bike9{
2. final int speedlimit=90;//final variable
3. void run(){
4. speedlimit=400;
5. }
6. public static void main(String args[]){
7. Bike9 obj=new Bike9();
8. obj.run();
9. }
10. }//end of class
1. class Bike{
2. final void run(){System.out.println("running");}
3. }
4.
5. class Honda extends Bike{
6. void run(){System.out.println("running safely with 100kmph");}
7.
8. public static void main(String args[]){
9. Honda honda= new Honda();
10. honda.run();
11. }
12. }
final class Bike{}
class Honda1 extends Bike{
void run(){System.out.println("running safely with 100kmph");}
public static void main(String args[]){
Honda1 honda= new Honda1();
honda.run();
}
}
Output
20
Explanation
Since i is the blank final variable. It can be initialized only once. We have
initialized it to 20. Therefore, 20 will be printed.
There are two major types of polymorphisms in Object Oriented Programming (OOPS)
languages. They are Static Binding (Compile time Polymorphism) and Dynamic Binding
(Runtime Polymorphism). Method overriding would be the example of Dynamic Polymorphism
and Method Overloading would be the example of Static Polymorphism.
Compile-time Polymorphism
By using the method of overloading, one can reach the state of static polymorphism in Object
Oriented Programming languages. This method would allow the programmer to implement
various methods. They might use the same names but their parameters are different. Method
overloading is an example of Static Polymorphism. There are certain conditions that are essential
for static polymorphism, they are:
All Parameters would have to be different in types.
The order of the Parameter might have to different.
The number of parameters of one method would have to be different from the other
method.
During the run time, the compiler of the language would identify various methods by identifying
signatures of these methods. The compiler would first identify the method signature and then
decide the method for a specific method call while compiling the program. The execution time
for Compile time Polymorphism is much faster but this process is not very flexible.
Runtime Polymorphism
This process is also known as Dynamic method dispatch. Under this process, a call to a single
overridden method is solved during the runtime of the program. Method overriding is the prime
example of Runtime Polymorphism. In this process, the call is not solved by the compiler. The
overriding is achieved through pointers and virtual functions. Method Overriding is the process
of declaring a single method in a sub-class that is present in a parent class. Through this process,
the child class would gain a method for implementation. This method is given by the parent class
of the child class. This process of polymorphism is slow but it is more flexible than the static
polymorphism. The main advantage of Runtime Polymorphism is the ability of the class to offer
the specification of its own to another inherited method. This transfer of implementation of one
method to another method is possible without changing or modifying the codes of the parent
class object. Thus, if a single child class needs the implementation method of the parent class
while other child class might use the overriding feature to have different implementation
methods.
Polymorphism is one of the core concepts of OOPS. This feature is applicable while
handling various classes and sub-classes. Here are some of the advantages of using
polymorphism in programming.
One of the biggest advantages of using Polymorphism is that it allows the
programming to extend itself.
This process allows the user to reuse the old classes and codes that were once tested
and already implemented successfully. These codes and classes would be applicable to
various other methods.
Through this process, the user would be able to store several variables of different
types (double, Float, Int, Long, etc) in a single variable. This would make it easier for
the user to search for and implementing these variables.
Polymorphism would also help in reducing coupling between two different functions.
Polymorphism is the core concept of the Object-Oriented Programming (OOPS) languages. This
language is used for executing various types of huge programming. This concept makes it
possible to access different classes of objects through the same interface. Through this concept,
the programming would become more efficient and quicker.
The interface in Java is a mechanism to achieve abstraction. There can be only abstract
methods in the Java interface, not method body. It is used to achieve abstraction and
multiple inheritance in Java.
In other words, you can say that interfaces can have abstract methods and variables. It cannot
have a method body.
There are mainly three reasons to use interface. They are given below.
An interface is declared by using the interface keyword. It provides total abstraction; means
all the methods in an interface are declared with the empty body, and all the fields are public,
static and final by default. A class that implements an interface must implement all the
methods declared in the interface.
A class that is declared as abstract is known as an abstract class. It needs to be extended and its
method implemented. It cannot be instantiated. It can have abstract methods, non-abstract
methods, constructors, and static methods. It can also have the final methods which will force the
subclass not to change the body of the method. Consider the following example.
1. abstract class Bike{
2. abstract void run();
3. }
4. class Honda4 extends Bike{
5. void run(){System.out.println("running safely");}
6. public static void main(String args[]){
7. Bike obj = new Honda4();
8. obj.run();
9. }
10. }
Output
running safely
S Array ArrayList
N
1 The Array is of fixed size, means ArrayList is not of the fixed size we
we cannot resize the array as per can change the size dynamically.
need.
3 Arrays can store primitive data ArrayList cannot store the primitive
types as well as objects. data types it can only store the
objects.
Java Collections can achieve all the operations that you perform on a data such as searching,
sorting, insertion, manipulation, and deletion.
Java Collection means a single unit of objects. Java Collection framework provides many
interfaces (Set, List, Queue, Deque) and classes (ArrayList,
Vector, LinkedList, PriorityQueue, HashSet, LinkedHashSet, TreeSet).
Next →← Prev
Collections in Java
1. Java Collection Framework
3. Collection interface
4. Iterator interface
Java Collection means a single unit of objects. Java Collection framework provides
many interfaces (Set, List, Queue, Deque) and classes (ArrayList,
Vector, LinkedList, PriorityQueue, HashSet, LinkedHashSet, TreeSet).
o It is optional.
2. Algorithm
Iterator interface
Iterator interface provides the facility of iterating the elements in a forward direction only.
There are only three methods in the Iterator interface. They are:
No Method Description
.
2 public Object next() It returns the element and moves the cursor pointer to
the next element.
3 public void remove() It removes the last elements returned by the iterator. It
is less used.
Iterable Interface
The Iterable interface is the root interface for all the collection classes. The Collection
interface extends the Iterable interface and therefore all the subclasses of Collection
interface also implement the Iterable interface.
1. Iterator<T> iterator()
Collection Interface
The Collection interface is the interface which is implemented by all the classes in the
collection framework. It declares the methods that every collection will have. In other
words, we can say that the Collection interface builds the foundation on which the
collection framework depends.
Some of the methods of Collection interface are Boolean add ( Object obj), Boolean
addAll ( Collection c), void clear(), etc. which are implemented by all the subclasses of
Collection interface.
List Interface
List interface is the child interface of Collection interface. It inhibits a list type data
structure in which we can store the ordered collection of objects. It can have duplicate
values.
List interface is implemented by the classes ArrayList, LinkedList, Vector, and Stack.
1. List <data-type> list1= new ArrayList();
2. List <data-type> list2 = new LinkedList();
3. List <data-type> list3 = new Vector();
4. List <data-type> list4 = new Stack();
There are various methods in List interface that can be used to insert, delete, and
access the elements from the list.
The classes that implement the List interface are given below.
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. Consider the following example.
1. import java.util.*;
2. class TestJavaCollection1{
3. public static void main(String args[]){
4. ArrayList<String> list=new ArrayList<String>();//Creating arraylist
5. list.add("Ravi");//Adding object in arraylist
6. list.add("Vijay");
7. list.add("Ravi");
8. list.add("Ajay");
9. //Traversing list through Iterator
10.Iterator itr=list.iterator();
11.while(itr.hasNext()){
12.System.out.println(itr.next());
13.}
14.}
15.}
Output:
Ravi
Vijay
Ravi
Ajay
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. In LinkedList, the manipulation is fast because no shifting is
required.
1. import java.util.*;
2. public class TestJavaCollection2{
3. public static void main(String args[]){
4. LinkedList<String> al=new LinkedList<String>();
5. al.add("Ravi");
6. al.add("Vijay");
7. al.add("Ravi");
8. al.add("Ajay");
9. Iterator<String> itr=al.iterator();
10.while(itr.hasNext()){
11.System.out.println(itr.next());
12.}
13.}
14.}
Output:
Ravi
Vijay
Ravi
Ajay
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.
1. import java.util.*;
2. public class TestJavaCollection3{
3. public static void main(String args[]){
4. Vector<String> v=new Vector<String>();
5. v.add("Ayush");
6. v.add("Amit");
7. v.add("Ashish");
8. v.add("Garima");
9. Iterator<String> itr=v.iterator();
10.while(itr.hasNext()){
11.System.out.println(itr.next());
12.}
13.}
14.}
Output:
Ayush
Amit
Ashish
Garima
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.
1. import java.util.*;
2. public class TestJavaCollection4{
3. public static void main(String args[]){
4. Stack<String> stack = new Stack<String>();
5. stack.push("Ayush");
6. stack.push("Garvit");
7. stack.push("Amit");
8. stack.push("Ashish");
9. stack.push("Garima");
10.stack.pop();
11.Iterator<String> itr=stack.iterator();
12.while(itr.hasNext()){
13.System.out.println(itr.next());
14.}
15.}
16.}
Output:
Ayush
Garvit
Amit
Ashish
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.
1. Queue<String> q1 = new PriorityQueue();
2. Queue<String> q2 = new ArrayDeque();
There are various classes that implement the Queue interface, some of them are given
below.
PriorityQueue
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.
1. import java.util.*;
2. public class TestJavaCollection5{
3. public static void main(String args[]){
4. PriorityQueue<String> queue=new PriorityQueue<String>();
5. queue.add("Amit Sharma");
6. queue.add("Vijay Raj");
7. queue.add("JaiShankar");
8. queue.add("Raj");
9. System.out.println("head:"+queue.element());
10.System.out.println("head:"+queue.peek());
11.System.out.println("iterating the queue elements:");
12.Iterator itr=queue.iterator();
13.while(itr.hasNext()){
14.System.out.println(itr.next());
15.}
16.queue.remove();
17.queue.poll();
18.System.out.println("after removing two elements:");
19.Iterator<String> itr2=queue.iterator();
20.while(itr2.hasNext()){
21.System.out.println(itr2.next());
22.}
23.}
24.}
Output:
head:Amit Sharma
head:Amit Sharma
iterating the queue elements:
Amit Sharma
Raj
JaiShankar
Vijay Raj
after removing two elements:
Raj
Vijay Raj
Deque Interface
Deque interface extends the Queue interface. In Deque, we can remove and add the
elements from both the side. Deque stands for a double-ended queue which enables us
to perform the operations at both the ends.
1. Deque d = new ArrayDeque();
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.
1. import java.util.*;
2. public class TestJavaCollection6{
3. public static void main(String[] args) {
4. //Creating Deque and adding elements
5. Deque<String> deque = new ArrayDeque<String>();
6. deque.add("Gautam");
7. deque.add("Karan");
8. deque.add("Ajay");
9. //Traversing elements
10.for (String str : deque) {
11.System.out.println(str);
12.}
13.}
14.}
Output:
Gautam
Karan
Ajay
Set Interface
Set Interface in Java is present in java.util package. It extends the Collection interface.
It represents the unordered set of elements which doesn't allow us to store the
duplicate items. We can store at most one null value in Set. Set is implemented by
HashSet, LinkedHashSet, and TreeSet.
1. Set<data-type> s1 = new HashSet<data-type>();
2. Set<data-type> s2 = new LinkedHashSet<data-type>();
3. Set<data-type> s3 = new TreeSet<data-type>();
HashSet
HashSet class implements Set Interface. It represents the collection that uses a hash
table for storage. Hashing is used to store the elements in the HashSet. It contains
unique items.
1. import java.util.*;
2. public class TestJavaCollection7{
3. public static void main(String args[]){
4. //Creating HashSet and adding elements
5. HashSet<String> set=new HashSet<String>();
6. set.add("Ravi");
7. set.add("Vijay");
8. set.add("Ravi");
9. set.add("Ajay");
10.//Traversing elements
11.Iterator<String> itr=set.iterator();
12.while(itr.hasNext()){
13.System.out.println(itr.next());
14.}
15.}
16.}
Output:
Vijay
Ravi
Ajay
LinkedHashSet
LinkedHashSet class represents the LinkedList implementation of Set Interface. It
extends the HashSet class and implements Set interface. Like HashSet, It also contains
unique elements. It maintains the insertion order and permits null elements.
Consider the following example.
1. import java.util.*;
2. public class TestJavaCollection8{
3. public static void main(String args[]){
4. LinkedHashSet<String> set=new LinkedHashSet<String>();
5. set.add("Ravi");
6. set.add("Vijay");
7. set.add("Ravi");
8. set.add("Ajay");
9. Iterator<String> itr=set.iterator();
10.while(itr.hasNext()){
11.System.out.println(itr.next());
12.}
13.}
14.}
Output:
Ravi
Vijay
Ajay
SortedSet Interface
SortedSet is the alternate of Set interface that provides a total ordering on its
elements. The elements of the SortedSet are arranged in the increasing (ascending)
order. The SortedSet provides the additional methods that inhibit the natural ordering
of the elements.
1. SortedSet<data-type> set = new TreeSet();
TreeSet
Java TreeSet class implements the Set interface that uses a tree for storage. Like
HashSet, TreeSet also contains unique elements. However, the access and retrieval
time of TreeSet is quite fast. The elements in TreeSet stored in ascending order.
Output:
Ajay
Ravi
Vijay
When an error occurs within a method, the method creates an object and hands it off to the runtime system.
The object, called an exception object, contains information about the error, including its type and the state of
the program when the error occurred. Creating an exception object and handing it to the runtime system is
called throwing an exception.
After a method throws an exception, the runtime system attempts to find something to handle it. The set of
possible "somethings" to handle the exception is the ordered list of methods that had been called to get to the
method where the error occurred. The list of methods is known as the call stack (see the next figure).
The call stack.
The runtime system searches the call stack for a method that contains a block of code that can handle the
exception. This block of code is called an exception handler. The search begins with the method in which the
error occurred and proceeds through the call stack in the reverse order in which the methods were called.
When an appropriate handler is found, the runtime system passes the exception to the handler. An exception
handler is considered appropriate if the type of the exception object thrown matches the type that can be
handled by the handler.
The exception handler chosen is said to catch the exception. If the runtime system exhaustively searches all
the methods on the call stack without finding an appropriate exception handler, as shown in the next figure,
the runtime system (and, consequently, the program) terminates.
Built-in exceptions are the exceptions which are available in Java libraries.
These exceptions are suitable to explain certain error situations. Below is the
list of important built-in exceptions in Java.
1. ArithmeticException
It is thrown when an exceptional condition has occurred in an arithmetic
operation.
2. ArrayIndexOutOfBoundsException
It is thrown to indicate that an array has been accessed with an illegal index.
The index is either negative or greater than or equal to the size of the array.
3. ClassNotFoundException
This Exception is raised when we try to access a class whose definition is
not found
4. FileNotFoundException
This Exception is raised when a file is not accessible or does not open.
5. IOException
It is thrown when an input-output operation failed or interrupted
6. InterruptedException
It is thrown when a thread is waiting , sleeping , or doing some processing ,
and it is interrupted.
7. NoSuchFieldException
It is thrown when a class does not contain the field (or variable) specified
8. NoSuchMethodException
It is thrown when accessing a method which is not found.
9. NullPointerException
This exception is raised when referring to the members of a null object. Null
represents nothing
10. NumberFormatException
This exception is raised when a method could not convert a string into a
numeric format.
11. RuntimeException
This represents any exception which occurs during runtime.
12. StringIndexOutOfBoundsException
It is thrown by String class methods to indicate that an index is either
negative or greater than the size of the string
Examples of Built-in Exception:
Arithmetic exception
Java
class ArithmeticException_Demo
{
try {
int a = 30, b = 0;
catch(ArithmeticException e) {
}
}
Output:
Can't divide a number by 0
NullPointer Exception
Java
class NullPointer_Demo
{
try {
System.out.println(a.charAt(0));
} catch(NullPointerException e) {
System.out.println("NullPointerException..");
}
}
Output:
NullPointerException..
StringIndexOutOfBound Exception
Java
class StringIndexOutOfBound_Demo
{
try {
System.out.println(c);
}
catch(StringIndexOutOfBoundsException e) {
System.out.println("StringIndexOutOfBoundsException");
}
}
Output:
StringIndexOutOfBoundsException
FileNotFound Exception
Java
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
class File_notFound_Demo {
try {
// Following file does not exist
}
}
Output:
File does not exist
NumberFormat Exception
Java
class NumberFormat_Demo
{
try {
// "akki" is not a number
System.out.println(num);
} catch(NumberFormatException e) {
}
}
Output:
Number format exception
ArrayIndexOutOfBounds Exception
Java
class ArrayIndexOutOfBound_Demo
{
try{
int a[] = new int[5];
// size 5
}
catch(ArrayIndexOutOfBoundsException e){
}
}
Output:
Array Index is Out Of Bounds
User-Defined Exceptions
Sometimes, the built-in exceptions in Java are not able to describe a certain
situation. In such cases, user can also create exceptions which are called ‘user-
defined Exceptions’.
Following steps are followed for the creation of user-defined Exception.
The user should create an exception class as a subclass of Exception class.
Since all the exceptions are subclasses of Exception class, the user should
also make his class a subclass of it. This is done as:
class MyException extends Exception
We can write a default constructor in his own exception class.
MyException(){}
We can also create a parameterized constructor with a string as a
parameter.
We can use this to store exception details. We can call super
class(Exception) constructor from this and send the string there.
MyException(String str)
{
super(str);
}
To raise exception of user-defined type, we need to create an object to his
exception class and throw it using throw clause, as:
MyException me = new MyException(“Exception details”);
throw me;
The following program illustrates how to create own exception class
MyException.
Details of account numbers, customer names, and balance amounts are
taken in the form of three arrays.
In main() method, the details are displayed using a for-loop. At this time,
check is done if in any account the balance amount is less than the minimum
balance amount to be apt in the account.
If it is so, then MyException is raised and a message is displayed “Balance
amount is less”.
Java
MyException() { }
{
try {
"\t" + "BALANCE");
{
"\t" + bal[i]);
{
MyException me =
throw me;
}
}
catch (MyException e) {
e.printStackTrace();
}
}
RunTime Error
MyException: Balance is less than 1000
at MyException.main(fileProperty.java:36)
Output:
ACCNO CUSTOMER BALANCE
1001 Nish 10000.0
1002 Shubh 12000.0
1003 Sush 5600.0
1004 Abhi 999.0
1
public void doNotCloseResourceInTry() {
2
FileInputStream inputStream = null;
3
try {
4
File file = new File("./tmp.txt");
5
inputStream = new FileInputStream(file);
6
7
// use the inputStream to read a file
8
9
// do NOT do this
10
inputStream.close();
11
} catch (FileNotFoundException e) {
12
log.error(e);
13
} catch (IOException e) {
14
log.error(e);
15
}
16
}
The problem is that this approach seems to work perfectly fine as long as no exception gets thrown.
All statements within the try block will get executed, and the resource gets closed.
But you added the try block for a reason. You call one or more methods which might throw an
exception, or maybe you throw the exception yourself. That means you might not reach the end of
the try block. And as a result, you will not close the resources.
You should, therefore, put all your clean up code into the finally block or use a try-with-resource
statement.
Use a Finally Block
In contrast to the last few lines of your try block, the finally block gets always executed. That
happens either after the successful execution of the try block or after you handled an exception in a
catch block. Due to this, you can be sure that you clean up all the opened resources.
1
public void closeResourceInFinally() {
2
FileInputStream inputStream = null;
3
try {
4
File file = new File("./tmp.txt");
5
inputStream = new FileInputStream(file);
6
7
// use the inputStream to read a file
8
9
} catch (FileNotFoundException e) {
10
log.error(e);
11
} finally {
12
if (inputStream != null) {
13
try {
14
inputStream.close();
15
} catch (IOException e) {
16
log.error(e);
17
}
18
}
19
}
20
}
Java 7’s Try-With-Resource Statement
Another option is the try-with-resource statement which I explained in more detail in my introduction
to Java exception handling.
You can use it if your resource implements the AutoCloseable interface. That’s what most Java
standard resources do. When you open the resource in the try clause, it will get automatically closed
after the try block got executed, or an exception handled.
1
public void automaticallyCloseResource() {
2
File file = new File("./tmp.txt");
3
try (FileInputStream inputStream = new FileInputStream(file);) {
4
// use the inputStream to read a file
5
6
} catch (FileNotFoundException e) {
7
log.error(e);
8
} catch (IOException e) {
9
log.error(e);
10
}
11
}
Therefore make sure to provide them as many information as possible. That makes your API easier
to understand. And as a result, the caller of your method will be able to handle the exception better
or avoid it with an additional check.
So, always try to find the class that fits best to your exceptional event, e.g. throw
a NumberFormatException instead of an IllegalArgumentException. And avoid throwing an
unspecific Exception.
1
public void doNotDoThis() throws Exception {
2
...
3
}
4
5
public void doThis() throws NumberFormatException {
6
...
7
}
So, make sure to add a @throws declaration to your Javadoc and to describe the situations that can
cause the exception.
1
/**
2
* This method does something extremely useful ...
3
*
4
* @param input
5
* @throws MyBusinessException if ... happens
6
*/
7
public void doSomething(String input) throws MyBusinessException {
8
...
9
}
Don’t get me wrong; you shouldn’t write a paragraph of text. But you should explain the reason for
the exception in 1-2 short sentences. That helps your operations team to understand the severity of
the problem, and it also makes it easier for you to analyze any service incidents.
If you throw a specific exception, its class name will most likely already describe the kind of error.
So, you don’t need to provide a lot of additional information. A good example for that is
the NumberFormatException. It gets thrown by the constructor of the class java.lang.Long when you
provide a String in a wrong format.
1
try {
2
new Long("xyz");
3
} catch (NumberFormatException e) {
4
log.error(e);
5
}
The name of the NumberFormatException class already tells you the kind of problem. Its message
only needs to provide the input string that caused the problem. If the name of the exception class
isn’t that expressive, you need to provide the required information in the message.
1
17:17:26,386 ERROR TestExceptionHandling:52 - java.lang.NumberFormatException:
For input string: "xyz"
The problem is that only the first catch block that matches the exception gets executed. So, if you
catch an IllegalArgumentException first, you will never reach the catch block that should handle the
more specific NumberFormatException because it’s a subclass of the IllegalArgumentException.
Always catch the most specific exception class first and add the less specific catch blocks to the end
of your list.
You can see an example of such a try-catch statement in the following code snippet. The first catch
block handles all NumberFormatExceptions and the second one all IllegalArgumentExceptions
which are not a NumberFormatException.
1
public void catchMostSpecificExceptionFirst() {
2
try {
3
doSomething("A message");
4
} catch (NumberFormatException e) {
5
log.error(e);
6
} catch (IllegalArgumentException e) {
7
log.error(e)
8
}
9
}
If you use Throwable in a catch clause, it will not only catch all exceptions; it will also catch all errors.
Errors are thrown by the JVM to indicate serious problems that are not intended to be handled by an
application. Typical examples for that are the OutOfMemoryError or the StackOverflowError. Both
are caused by situations that are outside of the control of the application and can’t be handled.
So, better don’t catch a Throwable unless you’re absolutely sure that you’re in an exceptional
situation in which you’re able or required to handle an error.
1
public void doNotCatchThrowable() {
2
try {
3
// do something
4
} catch (Throwable t) {
5
// don't do this!
6
}
7
}
1
public void doNotIgnoreExceptions() {
2
try {
3
// do something
4
} catch (NumberFormatException e) {
5
// this will never happen
6
}
7
}
So, please, never ignore an exception. You don’t know how the code will change in the future.
Someone might remove the validation that prevented the exceptional event without recognizing that
this creates a problem. Or the code that throws the exception gets changed and now throws multiple
exceptions of the same class, and the calling code doesn’t prevent all of them.
You should at least write a log message telling everyone that the unthinkable just had happened and
that someone needs to check it.
1
public void logAnException() {
2
try {
3
// do something
4
} catch (NumberFormatException e) {
5
log.error("This should never happen: " + e);
6
}
7
}
It might feel intuitive to log an exception when it occurred and then rethrow it so that the caller can
handle it appropriately. But it will write multiple error messages for the same exception.
1
17:44:28,945 ERROR TestExceptionHandling:65 - java.lang.NumberFormatException:
For input string: "xyz"
2
Exception in thread "main" java.lang.NumberFormatException: For input string:
"xyz"
3
at
java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
4
at java.lang.Long.parseLong(Long.java:589)
5
at java.lang.Long.(Long.java:965)
6
at
com.stackify.example.TestExceptionHandling.logAndThrowException(TestExceptionH
andling.java:63)
7
at
com.stackify.example.TestExceptionHandling.main(TestExceptionHandling.java:58)
The additional messages also don’t add any information. As explained in best practice #4, the
exception message should describe the exceptional event. And the stack trace tells you in which
class, method, and line the exception was thrown.
If you need to add additional information, you should catch the exception and wrap it in a custom
one. But make sure to follow best practice number 9.
1
public void wrapException(String input) throws MyBusinessException {
2
try {
3
// do something
4
} catch (NumberFormatException e) {
5
throw new MyBusinessException("A message that describes the error.",
e);
6
}
7
}
So, only catch an exception if you want to handle it. Otherwise, specify it in the method signature
and let the caller take care of it.
When you do that, make sure to set the original exception as the cause. The Exception class
provides specific constructor methods that accept a Throwable as a parameter. Otherwise, you lose
the stack trace and message of the original exception which will make it difficult to analyze the
exceptional event that caused your exception.
1
public void wrapException(String input) throws MyBusinessException {
2
try {
3
// do something
4
} catch (NumberFormatException e) {
5
throw new MyBusinessException("A message that describes the error.",
e);
6
}
7
}
Summary
As you’ve seen, there are lots of different things you should consider when you throw or catch an
exception. Most of them have the goal to improve the readability of your code or the usability of your
API.
Exceptions are most often an error handling mechanism and a communication medium at the same
time. You should, therefore, make sure to discuss the best practices and rules you want to apply
with your coworkers so that everyone understands the general concepts and uses them in the same
way.
Exceptions provide the means to separate the details of what to do when something out of the ordinary
happens from the main logic of a program. In traditional programming, error detection, reporting, and handling
often lead to confusing spaghetti code. For example, consider the pseudocode method here that reads an
entire file into memory.
readFile {
open the file;
determine its size;
allocate that much memory;
read the file into memory;
close the file;
}
At first glance, this function seems simple enough, but it ignores all the following potential errors.
To handle such cases, the readFile function must have more code to do error detection, reporting, and
handling. Here is an example of what the function might look like.
errorCodeType readFile {
initialize errorCode = 0;
There's so much error detection, reporting, and returning here that the original seven lines of code are lost in
the clutter. Worse yet, the logical flow of the code has also been lost, thus making it difficult to tell whether the
code is doing the right thing: Is the file really being closed if the function fails to allocate enough memory? It's
even more difficult to ensure that the code continues to do the right thing when you modify the method three
months after writing it. Many programmers solve this problem by simply ignoring it — errors are reported when
their programs crash.
Exceptions enable you to write the main flow of your code and to deal with the exceptional cases elsewhere. If
the readFile function used exceptions instead of traditional error-management techniques, it would look more
like the following.
readFile {
try {
open the file;
determine its size;
allocate that much memory;
read the file into memory;
close the file;
} catch (fileOpenFailed) {
doSomething;
} catch (sizeDeterminationFailed) {
doSomething;
} catch (memoryAllocationFailed) {
doSomething;
} catch (readFailed) {
doSomething;
} catch (fileCloseFailed) {
doSomething;
}
}
Note that exceptions don't spare you the effort of doing the work of detecting, reporting, and handling errors,
but they do help you organize the work more effectively.
A second advantage of exceptions is the ability to propagate error reporting up the call stack of methods.
Suppose that the readFile method is the fourth method in a series of nested method calls made by the main
program: method1 calls method2, which calls method3, which finally calls readFile.
method1 {
call method2;
}
method2 {
call method3;
}
method3 {
call readFile;
}
Suppose also that method1 is the only method interested in the errors that might occur within readFile.
Traditional error-notification techniques force method2 and method3 to propagate the error codes returned
by readFile up the call stack until the error codes finally reach method1—the only method that is interested in
them.
method1 {
errorCodeType error;
error = call method2;
if (error)
doErrorProcessing;
else
proceed;
}
errorCodeType method2 {
errorCodeType error;
error = call method3;
if (error)
return error;
else
proceed;
}
errorCodeType method3 {
errorCodeType error;
error = call readFile;
if (error)
return error;
else
proceed;
}
Recall that the Java runtime environment searches backward through the call stack to find any methods that
are interested in handling a particular exception. A method can duck any exceptions thrown within it, thereby
allowing a method farther up the call stack to catch it. Hence, only the methods that care about errors have to
worry about detecting errors.
method1 {
try {
call method2;
} catch (exception e) {
doErrorProcessing;
}
}
method2 throws exception {
call method3;
}
However, as the pseudocode shows, ducking an exception requires some effort on the part of the middleman
methods. Any checked exceptions that can be thrown within a method must be specified in its throws clause.
Because all exceptions thrown within a program are objects, the grouping or categorizing of exceptions is a
natural outcome of the class hierarchy. An example of a group of related exception classes in the Java platform
are those defined in java.io — IOException and its descendants. IOException is the most general and
represents any type of error that can occur when performing I/O. Its descendants represent more specific
errors. For example, FileNotFoundException means that a file could not be located on disk.
A method can write specific handlers that can handle a very specific exception.
The FileNotFoundException class has no descendants, so the following handler can handle only one type of
exception.
catch (FileNotFoundException e) {
...
}
A method can catch an exception based on its group or general type by specifying any of the exception's
superclasses in the catch statement. For example, to catch all I/O exceptions, regardless of their specific type,
an exception handler specifies an IOException argument.
catch (IOException e) {
...
}
This handler will be able to catch all I/O exceptions, including FileNotFoundException, EOFException, and so
on. You can find details about what occurred by querying the argument passed to the exception handler. For
example, use the following to print the stack trace.
catch (IOException e) {
// Output goes to System.err.
e.printStackTrace();
// Send trace to stdout.
e.printStackTrace(System.out);
}
You could even set up an exception handler that handles any Exception with the handler here.
In most situations, however, you want exception handlers to be as specific as possible. The reason is that the
first thing a handler must do is determine what type of exception occurred before it can decide on the best
recovery strategy. In effect, by not catching specific errors, the handler must accommodate any possibility.
Exception handlers that are too general can make code more error-prone by catching and handling exceptions
that weren't anticipated by the programmer and for which the handler was not intended.
instanceof is a binary operator used to test if an object is of a given type. The
result of the operation is either true or false. It's also known as type comparison
operator because it compares the instance with type.
Before casting an unknown object, the instanceof check should always be used. Doing
this helps in avoiding ClassCastException at runtime.
The instanceof operator's basic syntax is:
(object) instanceof (type)
Let's see a basic example for the instanceof operator. First, let's create a class Round:
public class Round {
// implementation details
}
Next, let's create a class Ring that extends Round:
public class Ring extends Round {
// implementation details
}
We can use instanceof to check if an instance of Ring is of Round type:
@Test
public void givenWhenInstanceIsCorrect_thenReturnTrue() {
Ring ring = new Ring();
Assert.assertTrue(ring instanceof Round);
}
6. instanceof and Generics
Instance tests and casts depend on inspecting the type information at runtime.
Therefore, we can't use instanceof along with erased generic types.
For instance, if we try to compile the following snippet:
public static <T> void sort(List<T> collection) {
if (collection instanceof List<String>) {
// sort strings differently
}
// omitted
}
Then we get this compilation error:
error: illegal generic type for instanceof
if (collection instanceof List<String>) {
^
Technically speaking, we are only allowed to use instanceof along with
reified types in Java. A type is reified if its type information is present at runtime.
The reified types in Java are as follows:
Because generic type parameters aren't reified, we can't use them either:
public static <T> boolean isOfType(Object input) {
return input instanceof T; // won't compile
}
However, it's possible to test against something like List<?>:
if (collection instanceof List<?>) {
// do something
}
{
return geekAge;
}
{
return geekName;
}
{
return geekRoll;
}
{
geekAge = newAge;
}
{
geekName = newName;
}
{
geekRoll = newRoll;
}
class TestEncapsulation {
{
obj.setName("Harsh");
obj.setAge(19);
obj.setRoll(51);
}
Output:
String color;
{
this.color = color;
}
{
return color;
}
double radius;
{
super(color);
this.radius = radius;
}
@Override
double area()
{
@Override
{
+ super.color
+ area();
}
double length;
double width;
double length,
double width)
{
super(color);
this.length = length;
this.width = width;
}
@Override
double area()
{
}
@Override
{
return "Rectangle color is "
+ super.color
+ area();
}
{
System.out.println(s1.toString());
System.out.println(s2.toString());
}
Output:
Shape constructor called
Circle constructor called
Shape constructor called
Rectangle constructor called
Circle color is Redand area is : 15.205308443374602
Rectangle color is Yellowand area is : 8.0
We can make a class read-only by making all of the data members private.
Please note:
If we make a class read-only, then we can’t modify the properties or data members
value of the class.
If we make a class read-only, then we can only read the properties or data members
value of the class.
The read-only class will contain only getter methods which return the value of the
private properties to the main() function.
The read-only class can contain setter methods if we want to modify the value of the
private properties after reading because there is our choice to keep setter method in
the class but as per based on the concepts we should not contain.
Now, we will see the objective of the getter method, why it is required?
Few points need to remember about getter methods are given below:
As we know that "private" data member of the class is accessible in the same class
only.
Let suppose we want to access "private" data member of the class in outside class.
So, in that case, we need to declare public "getter" methods.
The objective of the getter method is used to view the private variable values.
Syntax:
In the Getter method, it is not mandatory the same data member name after get, but it is
convenient for our understanding that we should consider the same name as the data
member after get.
Example:
}
}
Output:Days in a Week: 7 days
We can make a class write-only by making all of the data members private.
Please note:
If we made a class write-only then we can modify the properties or data member
value of the class.
If we made a class write-only then we can only write the properties or data members
value of the class.
The write-only class will contain setter methods which write the value of the private
properties because there is a setter method available in the class.
The write-only class can contain getter method if we want to read the value of the
private properties after writing.
Now, we will see the objective of the setter method, why it is required?
Few points need to remember about setter methods are given below:
As we know that "private" data member of the class is accessible in the same class
only.
Let suppose we want to access "private" data member of the class in outside class.
So, in that case, we need to declare public "setter" methods.
The objective of the set method is used to update or set the private variable values.
Syntax:
In the setter method, it is not mandatory the same data member name after set, but it is
convenient for our understanding that we should consider the same name as the data
member after set.
Example:
}
}
Output
The java.lang.Throwable class is the root class of Java Exception hierarchy which is
inherited by two subclasses: Exception and Error. A hierarchy of Java Exception classes
are given below:
Basically, there are two types of exceptions in java API. They are:
1. Predefined Exceptions (Built-in-Exceptions)
2. Custom Exceptions
Predefined Exceptions:
Predefined exceptions are those exceptions that are already defined by Java
system. These exceptions are also called built-in-exceptions.
Java API supports exception handling by providing the number of predefined
exceptions. These predefined exceptions are represented by classes in java.
When a predefined exception occurs, JVM (Java runtime system) creates an
object of predefined exception class. All exceptions are derived from
java.lang.Throwable class but not all exception classes are defined in the same
package.
All the predefined exceptions supported by java are organized as subclasses in a
hierarchy under the Throwable class.
The Throwable class is the root of exception hierarchy and is an immediate
subclass of Object class. Let’s take a look at the java exception hierarchy, as
shown in the below figure.
Throwable class is the superclass of all exceptions in java. This class has two
subclasses: Error and Exception. Errors or exceptions occurring in java programs
are objects of these classes. Using Throwable class, you can also create your
own custom exceptions.
2. Error: Error class is the subclass of Throwable class and a superclass of all
the runtime error classes. It terminates the program if there is problem-related to
a system or resources (JVM).
An error generally represents an unusual problem or situation from which it is
difficult to recover. It does not occur by programmer mistakes. It generally occurs
if the system is not working properly or resource is not allocated properly.
VirtualMachineError, StackOverFlowError, AssertionError, LinkageError,
OutOfMmeoryError, etc are examples of error. We will learn more detail in further
tutorials.
3. Exception: It is represented by an Exception class that represents errors
caused by the program and by external factors. Exception class is a subclass of
Throwable class and a superclass of all the exception classes. All the exception
classes are derived directly or indirectly from the Exception class. They generally
originate from within the application.
The exception class provides two constructors:
public Exception() (Default constructor)
public Exception(String message) (It takes a message string as argument)
Each of the exception classes provides two constructors: one with no argument
and another with a String type argument. Exception class does not provide its
own method. It inherits all methods provided by Throwable class.
The hierarchy of exception class in Java has been shown in the below figure that
is very important for an interview purpose.
Custom Exceptions:
Custom exceptions are those exceptions that are created by users or
programmers according to their own needs. The custom exceptions are also
called user-defined exceptions that are created by extending the exception class.
So, Java provides the liberty to programmers to throw and handle exceptions
while dealing with functional requirements of problems they are solving. We will
discuss in more detail about custom exceptions in further tutorials.
Let’s see the brief description of each subclass of the Exception class.
import java.io.*;
class Example {
public static void main(String args[])
{
FileInputStream fis = null;
/*This constructor FileInputStream(File filename)
* throws FileNotFoundException which is a checked
* exception
*/
fis = new FileInputStream("B:/myfile.txt");
int k;
import java.io.*;
class Example {
public static void main(String args[]) throws IOException
{
FileInputStream fis = null;
fis = new FileInputStream("B:/myfile.txt");
int k;
import java.io.*;
class Example {
public static void main(String args[])
{
FileInputStream fis = null;
try{
fis = new FileInputStream("B:/myfile.txt");
}catch(FileNotFoundException fnfe){
System.out.println("The specified file is not " +
"present at the given path");
}
int k;
try{
while(( k = fis.read() ) != -1)
{
System.out.print((char)k);
}
fis.close();
}catch(IOException ioe){
System.out.println("I/O error occurred: "+ioe);
}
}
}
This code will run fine and will display the file content.
SQLException
IOException
ClassNotFoundException
InvocationTargetException
class Example {
public static void main(String args[])
{
int arr[] ={1,2,3,4,5};
/* My array has only 5 elements but we are trying to
* display the value of 8th element. It should throw
* ArrayIndexOutOfBoundsException
*/
System.out.println(arr[7]);
}
}
This code would also compile successfully since ArrayIndexOutOfBoundsException is
also an unchecked exception.
Note: It doesn’t mean that compiler is not checking these exceptions so we
shouldn’t handle them. In fact we should handle them more carefully. For e.g. In
the above example there should be a exception message to user that they are
trying to display a value which doesn’t exist in array so that user would be able to
correct the issue.
class Example {
public static void main(String args[]) {
try{
int arr[] ={1,2,3,4,5};
System.out.println(arr[7]);
}
catch(ArrayIndexOutOfBoundsException e){
System.out.println("The specified index does not exist " +
"in array. Please correct the error.");
}
}
}
Output:
The specified index does not exist in array. Please correct the error.
68. In Java, How many ways you know to take input from the console?
In Java, there are three ways by using which, we can take input from the console.
o Using BufferedReader class: we can take input from the console by wrapping
System.in into an InputStreamReader and passing it into the BufferedReader. It
provides an efficient reading as the input gets buffered. Consider the following
example.
1. import java.io.BufferedReader;
2. import java.io.IOException;
3. import java.io.InputStreamReader;
4. public class Person
5. {
6. public static void main(String[] args) throws IOException
7. {
8. System.out.println("Enter the name of the person");
9. BufferedReader reader = new BufferedReader(new InputStreamReader(Sy
stem.in));
10. String name = reader.readLine();
11. System.out.println(name);
12. }
13.}
o Using Scanner class: The Java Scanner class breaks the input into tokens
using a delimiter that is whitespace by default. It provides many methods to
read and parse various primitive values. Java Scanner class is widely used to
parse text for string and primitive types using a regular expression. Java
Scanner class extends Object class and implements Iterator and Closeable
interfaces. Consider the following example.
1. import java.util.*;
2. public class ScannerClassExample2 {
3. public static void main(String args[]){
4. String str = "Hello/This is JavaTpoint/My name is Abhishek.";
5. //Create scanner with the specified String Object
6. Scanner scanner = new Scanner(str);
7. System.out.println("Boolean Result: "+scanner.hasNextBoolean());
8. //Change the delimiter of this scanner
9. scanner.useDelimiter("/");
10. //Printing the tokenized Strings
11. System.out.println("---Tokenizes String---");
12. while(scanner.hasNext()){
13. System.out.println(scanner.next());
14. }
15. //Display the new delimiter
16. System.out.println("Delimiter used: " +scanner.delimiter());
17. scanner.close();
18. }
19.}
20.
o Using Console class: The Java Console class is used to get input from the
console. It provides methods to read texts and passwords. If you read the
password using the Console class, it will not be displayed to the user. The
java.io.Console class is attached to the system console internally. The Console
class is introduced since 1.5. Consider the following example.
1. import java.io.Console;
2. class ReadStringTest{
3. public static void main(String args[]){
4. Console c=System.console();
5. System.out.println("Enter your name: ");
6. String n=c.readLine();
7. System.out.println("Welcome "+n);
8. }
9. }
The current version of JDBC is 4.3. It is the stable release since 21st September, 2017.
It is based on the X/Open SQL Call Level Interface. The java.sql package contains
classes and interfaces for JDBC API. A list of popular interfaces of JDBC API are given
below:
o Driver interface
o Connection interface
o Statement interface
o PreparedStatement interface
o CallableStatement interface
o ResultSet interface
o ResultSetMetaData interface
o DatabaseMetaData interface
o RowSet interface
o DriverManager class
o Blob class
o Clob class
o Types class
Why Should We Use JDBC
Before JDBC, ODBC API was the database API to connect and execute the query with
the database. But, ODBC API uses ODBC driver which is written in C language (i.e.
platform dependent and unsecured). That is why Java has defined its own API (JDBC
API) that uses JDBC drivers (written in Java language).
We can use JDBC API to handle database using Java program and can perform the
following activities:
What is API
API (Application programming interface) is a document that contains a description of all
the features of a product or software. It represents classes and interfaces that software
programs can follow to communicate with each other. An API can be created for
applications, libraries, operating systems, etc
o Create connection
o Create statement
o Execute queries
o Close connection
1) Register the driver class
The forName() method of Class class is used to register the driver class. This method is used to d
Note: Since JDBC 4.0, explicitly registering the driver is optional. We just need to put
vender's Jar in the classpath, and then JDBC driver manager can detect and load the
driver automatically.
1. Class.forName("oracle.jdbc.driver.OracleDriver");
2) Create the connection object
The getConnection() method of DriverManager class is used to establish connection with the data
First, you must get a reference to the appropriate Class object. One way to
do this, is to use a string and the Class.forName( ) method. This is
convenient because you don’t need an object of that type in order to get the
Class reference. However, if you do already have an object of the type
you’re interested in, you can fetch the Class reference by calling a method
that’s part of the Object root class: getClass( ). This returns the Class
reference representing the actual type of the object.
The Class.getInterfaces( ) method returns an array of Class objects representing the
interfaces that are contained in the Class object of interest.
If you have a Class object, you can also ask it for its direct base class
using getSuperclass( ). This, of course, returns a Class reference that you can
further query. This means that at run time, you can discover an object’s entire class
hierarchy.
The final method in the listing is printInfo( ), which takes a Class reference and gets
its name with getName( ), and finds out whether it’s an interface with isInterface( ).
Thus, with the Class object you can find out just about everything you want to know
about an object.
Generics are a facility of generic programming that were added to the Java
programming language in 2004 within version J2SE 5.0. They were
designed to extend Java's type system to allow "a type or method to
operate on objects of various types while providing compile-time type
safety".[1] The aspect compile-time type safety was not fully achieved,
since it was shown in 2016 that it is not guaranteed in all cases.[2]
In 1998, Gilad Bracha, Martin Odersky, David Stoutamire and Philip Wadler
created Generic Java, an extension to the Java language to support
generic types.[3] Generic Java was incorporated in Java with the addition
of wildcards.
77. Class diagrams: give and example, how to read it.
A class represent a concept which encapsulates state (attributes) and behavior
(operations). Each attribute has a type. Each operation has a signature. The
class name is the only mandatory information.
Class Name:
The name of the class appears in the first partition.
Class Attributes:
Attributes are shown in the second partition.
The attribute type is shown after the colon.
Attributes map onto member variables (data members) in code.
Class Visibility
Parameter Directionality
The perspective affects the amount of detail to be supplied and the kinds of
relationships worth presenting. As we mentioned above, the class name is the
only mandatory information.
The figure below shows an inheritance example with two styles. Although the
connectors are drawn differently, they are semantically equivalent.
Association
Simple Association
A structural link between two peer classes.
There is an association between Class1 and Class2
Aggregation
Dependency
An object of one class might use an object of another class in the code of a
method. If the object is not stored in any field, then this is modeled as a
dependency relationship.
A special type of association.
Exists between two classes if changes to the definition of one may cause
changes to the other (but not the other way around).
Class1 depends on Class2
The figure below shows another example of dependency. The Person class might
have a hasRead method with a Book parameter that returns true if the person
has read the book (perhaps by checking some database).
Realization
#include <iostream>
#include <string.h>
class TempClass {
T value;
public:
TempClass(T item)
{
value = item;
}
T getValue()
{
return value;
}
};
int main()
<< "\n";
class TempClass<int>* integer = new TempClass<int>(9);
Output:
Output Values: Generics vs Templates
Output Values: 9
Generics in Java
1. One of the major features of Java Generics is that It handles type checking
during instantiation and generates byte-code equivalent to non-generic code.
The compiler of Java checks type before instantiation, that in turn makes the
implementation of Generic type-safe. Meanwhile, in C++, templates know
nothing about types.
2. If Generics is applied in a class, then it gets Applied to classes and methods
within classes.
3. Another major factor that leads to the use of generics in Java is because it
allows you to eliminate downcasts.
4. Instantiating a generic class has no runtime overhead over using an
equivalent class that uses as specific object rather than a generic type of T.
// Generics
private T value;
this.value = value;
}
{
System.out.println("Type:" +
value.getClass().getSimpleName());
}
{
GenericClass<String> Str =
GenericClass<Integer> integer =
new GenericClass<Integer>(9);
Str.showType();
integer.showType();
}
Output:
Type:String
Value: Generics vs Templates
Type:Integer
Value: 9
C++ Templates vs Generics in Java
Though both of the methods to create a generic type is similar, but they vary at
some places, while the implementation property that they possess is the same.
1. Type erasure : Type erasure ensures tighter type check during compile
time. Java generics simply offer compile-time safety and eliminate the need
for casts. This is directly implemented in the Java compiler front-end and
make sure type erasure is done.
2. In C++ when you use a template the compiler will emit the template code
again after replacing the generic parameter in it with the type you used. This
is more powerful in several ways but can lead to bloated executables.
3. Wrapper class : In Java, Even if we have to specifically specify the datatype
within which the function call using any object, we don’t need to cast it
similar to that of C++ with actual data types, rather we use wrapper classes
to do the required.
4. Type Checking : Java Generics handles type checking during instantiation
and generates byte-code equivalent to non-generic code C++ has “latent
typing” and template metaprogramming and generates a new class for each
instantiation
85. What is your teacher’s name OOP (firstname, last name, patronymic
name), position :)
Beibut Amirgaliev, Associate Professor of the Information and
Communication Technologies Program, Director of the Department of
Science and Innovation of Astana IT University, is the best teacher of
the university in 2019.