What can prevent the execution of the code in finally block ? and what are the rules for catching multiple exceptions?
The death of thread
– Use of system.exit()
– Turning off the power to CPU
– An exception arising in the finally block itself
Rules for catching multiple exceptions
– A more specific catch block must precede a more general one in the source, else it
gives compilation error
– Only one catch block, that is first applicable one, will be executed
What is an observer design pattern
The Observer pattern is a behavioral design pattern that allows an object (an Observer) to watch another object (a Subject). The subject and observer to have a publish/subscribe relationship. Observers can register to receive events from the Subject.
Some of the practical uses of observer pattern are:
- When a change to one object requires changing of others, and you don’t know how many objects need to be changed.
- When an object should be able to notify other objects without making assumptions about who these objects are and not tightly coupling them.
- When a report is received or an event occurs, a message needs to be sent to the subscribed handlers.
Examples:
- Programming Swing based GUI applications where the listeners register them with events like button click, property change, etc.
- Programming a stock market application to know when the price of a stock changes.
- Programming a order placement or trading application to know the status changes like pending, filled, shipped, rejected, etc.
So, whenever you want to have the state change or other information, instead of polling every few second, register the observers with a subject.
Here is some pseudo code of this third scenario
STEP 1: Define the Subject and Observer interfaces
This is the subject interface
package com;
public interface ReportExecutor {
public void addHandler(ReportHandler rh);
public void removeHandler(ReportHandler rh);
public void processReport(String message);
}
This is the observer interface
package com;
public interface ReportHandler {
//handles report
public void handleMessage(String message);
}
STEP 2: Define the concrete subject and observers
The concrete subject
package com;
import java.util.ArrayList;
import java.util.List;
public class SalesReportExecutor implements ReportExecutor {
//list of observers that register their interest in SalesReport
private List<reporthandler> reportHandlers = new ArrayList<reporthandler>();
@Override
public void addHandler(ReportHandler rh) {
reportHandlers.add(rh);
}
@Override
public void processReport(String message) {
for (ReportHandler reportHandler : reportHandlers) {
reportHandler.handleMessage(message);
}
}
@Override
public void removeHandler(ReportHandler rh) {
reportHandlers.remove(rh);
}
}
The concrete observers
package com;
public class LoggingReportHandler implements ReportHandler {
@Override
public void handleMessage(String message) {
//handles report by formatting and printing
System.out.println(“Logging report ” + message);
}
}
package com;
public class EmailReportHandler implements ReportHandler {
@Override
public void handleMessage(String message) {
//handles the report by formatting it differently and emailing.
System.out.println(“Emailing report ” + message);
//logic to email report.
}
}
STEP 3: Finally, the JMS listener class that uses the subject. The JMS Listener class listens on a queue for presence of a report.
package com.mgl.mts.fix;
import javax.jms.Message;
import javax.jms.TextMessage;
public class MyAppListener {
public void onMessage(Message message) {
if (message instanceof TextMessage) {
ReportExecutor executor = new SalesReportExecutor();
executor.addHandler(new LoggingReportHandler());
executor.addHandler(new EmailReportHandler());
executor.processReport(message.toString());
} else {
throw new IllegalArgumentException(“Message must be of type TextMessage”);
}
}
}
How will you go about creating a memory leak in Java
In Java, memory leaks are possible under a number of scenarios. Here is a typical example where hashCode( ) and equals( ) methods are not implemented for the Key class that is used to store key/value pairs in a HashMap.
This will end up creating a large number of duplicate objects. All memory leaks in Java end up with java.lang.OutOfMemoryError, and it is a matter of time. The following code agressively creates the OutOfMemoryError via an endless loop for demonstration purpose.
If you are not familiar with the significance of equals( ) and hashCode ( ) methods in Java, then learn with this example how to define proper key class in Java.
import java.util.HashMap;
import java.util.Map;
public class MemoryLeak {
public static void main(String[] args) {
Map<Key, String> map = new HashMap<Key, String>(1000);
int counter = 0;
while (true) { // creates duplicate objects due to bad Key class
map.put(new Key(“dummyKey”), “value”);
counter++;
if (counter % 1000 == 0) {
System.out.println(“map size: ” + map.size());
System.out.println(“Free memory after count ” + counter + ” is ” + getFreeMemory() + “MB”);
sleep(1000);
}
}
}
// inner class key without hashcode() or equals() — bad implementation
static class Key {
private String key;
public Key(String key) {
this.key = key;
}
}
//delay for a given period in milli seconds
public static void sleep(long sleepFor) {
try {
Thread.sleep(sleepFor);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//get available memory in MB
public static long getFreeMemory() {
return Runtime.getRuntime().freeMemory() / (1024 * 1024);
}
}
If you run the above code, you will get the ouput as shown below
map size: 1000
Free memory after count 1000 is 4MB
map size: 2000
Free memory after count 2000 is 4MB
map size: 1396000
Free memory after count 1396000 is 2MB
map size: 1397000
Free memory after count 1397000 is 2MB
map size: 1398000
Free memory after count 1398000 is 2MB
map size: 1399000
Free memory after count 1399000 is 1MB
map size: 1400000
Free memory after count 1400000 is 1MB
map size: 1401000
Free memory after count 1401000 is 1MB
…..
…..
map size: 1452000
Free memory after count 1452000 is 0MB
map size: 1453000
Free memory after count 1453000 is 0MB
Exception in thread “main” java.lang.OutOfMemoryError: Java heap space
at java.util.HashMap.addEntry(HashMap.java:753)
at java.util.HashMap.put(HashMap.java:385)
at MemoryLeak.main(MemoryLeak.java:10)
As you could see, the size of the map keeps growing with the same objects and the available memory keeps coming down from 4MB to 0MB. At the end, the program dies with an OutOfMemoryError.
How to do database connection using JDBC thin driver
This is one of the most commonly asked questions from JDBC fundamentals, and knowing all the steps of JDBC connection is important.
import java.sql.*;
class JDBCTest {
public static void main (String args []) throws Exception
{
//Load driver class
Class.forName (“oracle.jdbc.driver.OracleDriver”);
//Create connection
Connection conn = DriverManager.getConnection
(“jdbc:oracle:thin:@hostname:1526:testdb”, “scott”, “tiger”);
// @machineName:port:SID, userid, password
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(“select ‘Hi’ from dual”);
while (rs.next())
System.out.println (rs.getString(1)); // Print col 1 => Hi
stmt.close();
}
}
What are transient variables? What role do they play in Serialization process
The transient keyword in Java is used to indicate that a field should not be serialized. Once the process of de-serialization is carried out, the transient variables do not undergo a change and retain their default value. Marking unwanted fields as transient can help you boost the serialization performance. Below is a simple example where you can see the use of transient keyword.
class MyVideo implements Serializable {
private Video video;
private transient Image thumbnailVideo;
private void generateThumbnail()
{
// Generate thumbnail.
}
private void readObject(ObjectInputStream inputStream)
throws IOException, ClassNotFoundException
{
inputStream.defaultReadObject();
generateThumbnail();
}
}
What is the base class from which all exceptions are subclasses
All exceptions are subclasses of a class called java.lang.Throwable
What does Class.forName() method do
Method forName() is a static method of java.lang.Class. This can be used to dynamically load a class at run-time. Class.forName() loads the class if its not already loaded. It also executes the static block of loaded class. Then this method returns an instance of the loaded class. So a call to Class.forName(‘MyClass’) is going to do following:
- Load the class MyClass.
- Execute any static block code of MyClass.
- Return an instance of MyClass.
JDBC Driver loading using Class.forName is a good example of best use of this method. The driver loading is done like this
Class.forName(“org.mysql.Driver”);
All JDBC Drivers have a static block that registers itself with DriverManager and DriverManager has static initializer method registerDriver() which can be called in a static blocks of Driver class. A MySQL JDBC Driver has a static initializer which looks like this:
static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException(“Can’t register driver!”);
}
}
Class.forName() loads driver class and executes the static block and the Driver registers itself with the DriverManager.
What does throws statement declaration in a method indicate
This indicates that the method throws some exception and the caller method
should take care of handling it
What is the difference between NoClassDefFoundError and ClassNotFoundException? When NoClassDefFoundError and ClassNotFoundException are thrown
NoClassDefFoundError and ClassNotFoundException are very closely related and often confused with each other by many developers. Below is the description of each from the Java API Specifications
ClassNotFoundException
Thrown when an application tries to load in a class through its string name using:
- The forName method in class Class.
- The findSystemClass method in class ClassLoader.
- The loadClass method in class ClassLoader.
but the definition of the class with the specified name could not be found due to following reasons
- The specified name class does not exist.
- The specified name class is not in the classpath
- The specified name class is not visible to the classloader.
NoClassDefFoundError
Thrown if the Java Virtual Machine or a ClassLoader instance tries to load in the definition of a class (as part of a normal method call or as part of creating a new instance using the new expression) and no definition of the class could be found.
The searched-for class definition existed when the currently executing class was compiled, but the definition can no longer be found.
Key Differences
- The NoClassDefFoundError is thrown when the source was successfully compiled, but during runtime, the required class files were not found. This may be a case when some dependency jar files were not included or not in classpath.
- A ClassNotFoundException is thrown when the reported class is not found by the ClassLoader or not visible to the Classloader.
- Another important distinction between these two is, NoClassDefFoundError is a sub class of java.lang.Error and the ClassNotFoundException is a subclass of java.lang.Exception.
- NoClassDefFoundError is a critical error for JVM since its having problems finding a class it expected to find.
On the other hand, the ClassNotFoundException is an Exception. Use of reflection api can be error-prone and there is no compile-time check to validate reflection call is loading right classes, so there can be situations when some classes may not be found.
Some scenario when ClassNotFoundException may occur:
Scenario 1 (Use of reflection) – You will see ClassNotFoundException when you are using reflection to load classes at runtime, and the class you are trying to load does not exist or not in classpath.
Scenario 2 (Multiple Classloaders being used) – You will see ClassNotFoundException when a class is being loaded from another class which was already loaded in a parent classloader and the class from the child classloader is not visible.
What is fail-fast property
At high level – Fail-fast is a property of a system or software with respect to its response to failures. A fail-fast system is designed to immediately report any failure or condition that is likely to lead to failure. Fail-fast systems are usually designed to stop normal operation rather than attempt to continue a possibly-flawed process. When a problem occurs, a fail-fast system fails immediately and visibly. Failing fast is a non-intuitive technique: “failing immediately and visibly” sounds like it would make your software more fragile, but it actually makes it more robust. Bugs are easier to find and fix, so fewer go into production. In Java, Fail-fast term can be related to context of iterators. If an iterator has been created on a collection object and some other thread tries to modify the collection object “structurally”, a concurrent modification exception will be thrown. It is possible for other threads though to invoke “set” method since it doesn’t modify the collection “structurally”. However, if prior to calling “set”, the collection has been modified structurally, “IllegalArgumentException” will be thrown.