You are on page 1of 42

http://withoutbook.com/InterviewQuestionAnswer.php?tech=1&quesId=62 Batch Execution in JAVA http://www.tutorialspoint.com/jdbc/jdbc-batch-processing.

htm
Batch Processing allows you to group related SQL statements into a batch and submit them with one call to the database. When you send several SQL statements to the database at once, you reduce the amount of communication overhead, thereby improving performance.

JDBC drivers are not required to support this feature. You should use theDatabaseMetaData.supportsBatchUpdates() method to determine if the target database supports batch update processing. The method returns true if your JDBC driver supports this feature. The addBatch() method of Statement, PreparedStatement, and CallableStatement is used to add individual statements to the batch. The executeBatch() is used to start the execution of all the statements grouped together. The executeBatch() returns an array of integers, and each element of the array represents the update count for the respective update statement. Just as you can add statements to a batch for processing, you can remove them with theclearBatch() method. This method removes all the statements you added with the addBatch() method. However, you cannot selectively choose which statement to remove.

Batching with Statement Object:


Here is a typical sequence of steps to use Batch Processing with Statment Object:

1. 2. 3. 4. 5.

Create a Statement object using either createStatement() methods. Set auto-commit to false using setAutoCommit(). Add as many as SQL statements you like into batch using addBatch() method on created statement object. Execute all the SQL statements using executeBatch() method on created statement object. Finally, commit all the changes using commit() method.

Example:
The following code snippet provides an example of a batch update using Statement object:

// Create statement object Statement stmt = conn.createStatement(); // Set auto-commit to false conn.setAutoCommit(false); // Create SQL statement String SQL = "INSERT INTO Employees (id, first, last, age) " + "VALUES(200,'Zia', 'Ali', 30)"; // Add above SQL statement in the batch. stmt.addBatch(SQL); // Create one more SQL statement String SQL = "INSERT INTO Employees (id, first, last, age) " + "VALUES(201,'Raj', 'Kumar', 35)";

// Add above SQL statement in the batch. stmt.addBatch(SQL); // Create one more SQL statement String SQL = "UPDATE Employees SET age = 35 " + "WHERE id = 100"; // Add above SQL statement in the batch. stmt.addBatch(SQL); // Create an int[] to hold returned values int[] count = stmt.executeBatch(); //Explicitly commit statements to apply changes conn.commit();
For a better understanding, I would suggest to study Batching - Example Code.

Batching with PrepareStatement Object:


Here is a typical sequence of steps to use Batch Processing with PrepareStatement Object: 1. Create SQL statements with placeholders. Create PrepareStatement object using either prepareStatement() methods. Set auto-commit to false using setAutoCommit(). Add as many as SQL statements you like into batch using addBatch() method on created statement object. Execute all the SQL statements using executeBatch() method on created statement object. Finally, commit all the changes using commit() method.

2. 3. 4. 5. 6.

The following code snippet provides an example of a batch update using PrepareStatement object:

// Create SQL statement String SQL = "INSERT INTO Employees (id, first, last, age) " + "VALUES(?, ?, ?, ?)"; // Create PrepareStatement object PreparedStatemen pstmt = conn.prepareStatement(SQL); //Set auto-commit to false conn.setAutoCommit(false); // Set the variables pstmt.setInt( 1, 400 ); pstmt.setString( 2, "Pappu" ); pstmt.setString( 3, "Singh" ); pstmt.setInt( 4, 33 ); // Add it to the batch pstmt.addBatch(); // Set the variables pstmt.setInt( 1, 401 ); pstmt.setString( 2, "Pawan" ); pstmt.setString( 3, "Singh" ); pstmt.setInt( 4, 31 ); // Add it to the batch pstmt.addBatch(); //add more batches .

. . . //Create an int[] to hold returned values int[] count = stmt.executeBatch(); //Explicitly commit statements to apply changes conn.commit();

JDBC: CallableStatement
http://tutorials.jenkov.com/jdbc/callablestatement.html
A java.sql.CallableStatement is used to call stored procedures in a database. A stored procedure is like a function or method in a class, except it lives inside the database. Some database heavy operations may benefit performance-wise from being executed inside the same memory space as the database server, as a stored procedure.

Creating a CallableStatement
You create an instance of a CallableStatement by calling the prepareCall() method on a connection object. Here is an example:

CallableStatement callableStatement =

connection.prepareCall("{call calculateStatistics(?, ?)}");

If the stored procedure returns a ResultSet, and you need a non-default ResultSet (e.g. with different holdability, concurrency etc. characteristics), you will need to specify these characteristics already when creating the CallableStatement. Here is an example:

CallableStatement callableStatement =

connection.prepareCall("{call calculateStatistics(?, ?)}",

ResultSet.TYPE_FORWARD_ONLY,

ResultSet.CONCUR_READ_ONLY,

ResultSet.CLOSE_CURSORS_OVER_COMMIT

);

Setting Parameter Values


Once created, a CallableStatement is very similar to a PreparedStatement. For instance, you can set parameters into the SQL, at the places where you put a ? . Here is an example:

CallableStatement callableStatement =

connection.prepareCall("{call calculateStatistics(?, ?)}");

callableStatement.setString(1, "param1");

callableStatement.setInt

(2, 123);

Executing the CallableStatement


Once you have set the parameter values you need to set, you are ready to execute theCallableStatement. Here is how that is done:

ResultSet result = callableStatement.executeQuery();

The executeQuery() method is used if the stored procedure returns a ResultSet. If the stored procedure just updates the database, you can call the executeUpdate() method instead, like this:

callableStatement.executeUpdate();

Batch Updates
You can group multiple calls to a stored procedure into a batch update. Here is how that is done:

CallableStatement callableStatement =

connection.prepareCall("{call calculateStatistics(?, ?)}");

callableStatement.setString(1, "param1");

callableStatement.setInt

(2, 123);

callableStatement.addBatch();

callableStatement.setString(1, "param2");

callableStatement.setInt

(2, 456);

callableStatement.addBatch();

int[] updateCounts = callableStatement.executeBatch();

OUT Parameters
A stored procedure may return OUT parameters. That is, values that are returned instead of, or in addition to, a ResultSet. After executing the CallableStatement you can then access these OUTparameters from the CallableStatement object. Here is an example:

CallableStatement callableStatement =

connection.prepareCall("{call calculateStatistics(?, ?)}");

callableStatement.setString(1, "param1");

callableStatement.setInt

(2, 123);

callableStatement.registerOutParameter(1, java.sql.Types.VARCHAR);

callableStatement.registerOutParameter(2, java.sql.Types.INTEGER);

ResultSet result = callableStatement.executeQuery();

while(result.next()) { ... }

String out1 = callableStatement.getString(1);

int

out2 = callableStatement.getInt

(2);

Why Prepared Statements are important and how to use them "properly"
http://www.theserverside.com/news/1365244/Why-Prepared-Statements-are-importantand-how-to-use-them-properly
It is recommended that you first process the ResultSet before trying to access any OUTparameters. This is recommended for database compatibility reasons. Databases have a tough job. They accept SQL queries from many clients concurrently and execute the queries as efficiently as possible against the data. Processing statements can be an expensive operation but databases are now written in such a way so that this overhead is minimized. However, these optimizations need assistance from the application developers if we are to capitalize on them. This article shows you how the correct use of PreparedStatements can significantly help a database perform these optimizations.

How does a database execute a statement?


Obviously, don't expect alot of detail here; we'll only examine the aspects important to this article. When a database receives a statement, the database engine first parses the statement and looks for syntax errors. Once the statement is parsed, the database needs to figure out the most efficient way to execute the statement. This can be computationally quite expensive. The database checks what indexes, if any, can help, or whether it should do a full read of all rows in a table. Databases use statistics on the data to figure out what is the best way. Once the query plan is created then it can be executed by the database engine. It takes CPU power to do the access plan generation. Ideally, if we send the same statement to the database twice, then we'd like the database to reuse the access plan for the first statement. This uses less CPU than if it regenerated the plan a second time.

Statement Caches
Databases are tuned to do statement caches. They usually include some kind of statement cache. This cache uses the statement itself as a key and the access plan is stored in the cache with the corresponding statement. This allows the database engine to reuse the plans for statements that have been executed previously. For example, if we sent the database a statement such as "select a,b from t where c = 2", then the computed access plan is cached. If we send the same statement later, the database can reuse the previous access plan, thus saving us CPU power.

Note however, that the entire statement is the key. For example, if we later sent the statement "select a,b from t where c = 3", it would not find an access plan. This is because the "c=3" is different from the cached plan "c=2". So, for example: For(int I = 0; I < 1000; ++I) { PreparedStatement ps = conn.prepareStatement("select a,b from t where c = " + I); ResultSet rs = Ps.executeQuery(); Rs.close(); Ps.close(); } Here the cache won't be used. Each iteration of the loop sends a different SQL statement to the database. A new access plan is computed for each iteration and we're basically throwing CPU cycles away using this approach. However, look at the next snippet: PreparedStatement ps = conn.prepareStatement("select a,b from t where c = ?"); For(int I = 0; I < 1000; ++I) { ps.setInt(1, I); ResultSet rs = ps.executeQuery(); Rs.close(); } ps.close(); Here it will be much more efficient. The statement sent to the database is parameterized using the '?' marker in the sql. This means every iteration is sending the same statement to the database with different parameters for the "c=?" part. This allows the database to reuse the access plans for the statement and makes the program execute more efficiently inside the database. This basically let's your application run faster or makes more CPU available to users of the database.

PreparedStatements and J2EE servers


Things can get more complicated when we use a J2EE server. Normally, a prepared statement is associated with a single database connection. When the connection is closed, the preparedstatement is discarded. Normally, a fat client application would get a database connection and then hold it for its lifetime. It would also create all prepared statements eagerly or lazily. Eagerly means that they are all created at once when the application starts. Lazily means that they are created as they are used. An eager approach gives a delay when the application starts but once it starts then it performs optimally. A lazy approach gives a fast start but as the application runs, the prepared statements are created when they are first used by the application. This gives an uneven performance until all statements are prepared but the application eventually settles and runs as fast as the eager application. Which is best depends on whether you need a fast start or even performance. The problem with a J2EE application is that it can't work like this. It only keeps a connection for the duration of the request. This means that it must create the prepared statements every time the request is executed. This is not as efficient as the fat client approach where the prepared statements are created once, rather than on every request. J2EE vendors have noticed this and designed connection pooling to avoid this performance disadvantage. When the J2EE server gives your application a connection, it isn't giving you the actual connection; you're getting a wrapper. You can verify this by looking at the name of the class for the connection you are given. It won't be a database JDBC connection, it'll be a class created by your application server. Normally, if you called close on a connection then the jdbc driver closes the connection. We want the connection to be returned to the pool when close is called by a J2EE application. We do this by making a proxy jdbc connection class that looks like a real connection. It has a reference to the actual connection. When we invoke any method on the connection then the proxy forwards the call to the real connection. But, when we call methods such as close instead of calling close on the real connection, it simply returns the connection to the connection pool and then marks the proxy connection as invalid so that if it is used again by the application we'll get an exception.

Wrapping is very useful as it also helps J2EE application server implementers to add support for prepared statements in a sensible way. When an application calls Connection.prepareStatement, it is returned a PreparedStatement object by the driver. The application then keeps the handle while it has the connection and closes it before it closes the connection when the request finishes. However, after the connection is returned to the pool and later reused by the same, or another application, , then ideally, we want the same PreparedStatement to be returned to the application.

J2EE PreparedStatement Cache


J2EE PreparedStatement Cache is implemented using a cache inside the J2EE server connection pool manager. The J2EE server keeps a list of prepared statements for each database connection in the pool. When an application calls prepareStatement on a connection, the application server checks if that statement was previously prepared. If it was, the PreparedStatement object will be in the cache and this will be returned to the application. If not, the call is passed to the jdbc driver and the query/preparedstatement object is added in that connections cache. We need a cache per connection because that's the way jdbc drivers work. Any preparedstatements returned are specific to that connection. If we want to take advantage of this cache, the same rules apply as before. We need to use parameterized queries so that they will match ones already prepared in the cache. Most application servers will allow you to tune the size of this prepared statement cache.

Summary
In conclusion, we should use parameterized queries with prepared statements. This reduces the load on the database by allowing it to reuse access plans that were already prepared. This cache is databasewide so if you can arrange for all your applications to use similar parameterized SQL, you will improve the efficiency of this caching scheme as an application can take advantage of prepared statements used by another application. This is an advantage of an application server because logic that accesses the database should be centralized in a data access layer (either an OR-mapper, entity beans or straight JDBC). Finally, the correct use of prepared statements also lets you take advantage of the prepared statement cache in the application server. This improves the performance of your application as the application can reduce the number of calls to the JDBC driver by reusing a previous prepared statement call. This makes it competitive with fat clients efficiency-wise and removes the disadvantage of not being able to keep a dedicated connection. If you use parameterized prepared statements, you improve the efficiency of the database and your application server hosted code. Both of these improvements will allow your application to improve its performance.

What is an Object's Hash Code?


http://www.devx.com/tips/Tip/5839 Objects in Java have hash codes associated with them. An object's hash code is a signed number that identifies the object (for example, an instance of the parent class). An object's hash code may be obtained by using the object's hashCode() method as follows:
int hashCode = SomeObject.hashCode();

The method hashCode() is defined in the Object class and is inherited by all Java objects. The following code snippet shows how the hash codes of two objects relate to the corresponding equals() method:
1. 2. 3. 4. // Compare objects and then compare their hash codes if (object1.equals(object2) System.out.println("hash code 1 = " + object1.hashCode() + ", hashcode 2 = " + object2.hashCode());

5. 6. 7. 8. 9. 10. 11. 12. 13.

// Compare hash codes and then compare objects if (object1.hashCode() == object2.hashCode()) { if (object1.equals(object2)) System.out.println"object1 equals object2"); else System.out.println"object1 does not equal object2"); }

In lines 3-4, the value of the two hash codes will always be the same. However, the program may go through line 10 or line 12 in the code. Just because an object's reference equals another object's reference (remember that the equals() method compares object references by default), it does not necessarily mean that the hash codes also match. The hashCode() method may be overridden by subclasses. Overriding the hash code will allow you to associate your own hash key with the object.

Java Serialization
http://www.tutorialspoint.com/java/java_serialization.htm
Java provides a mechanism, called object serialization where an object can be represented as a sequence of bytes that includes the object's data as well as information about the object's type and the types of data stored in the object. After a serialized object has been written into a file, it can be read from the file and deserialized that is, the type information and bytes that represent the object and its data can be used to recreate the object in memory. Most impressive is that the entire process is JVM independent, meaning an object can be serialized on one platform and deserialized on an entirely different platform. Classes ObjectInputStream and ObjectOutputStream are high-level streams that contain the methods for serializing and deserializing an object. The ObjectOutputStream class contains many write methods for writing various data types, but one method in particular stands out:

public final void writeObject(Object x) throws IOException


The above method serializes an Object and sends it to the output stream. Similarly, the ObjectInputStream class contains the following method for deserializing an object:

public final Object readObject() throws IOException, ClassNotFoundException


This method retrieves the next Object out of the stream and deserializes it. The return value is Object, so you will need to cast it to its appropriate data type. To demonstrate how serialization works in Java, I am going to use the Employee class that we discussed early on in the book. Suppose that we have the following Employee class, which implements the Serializable interface:

public class Employee implements java.io.Serializable {

public String name; public String address; public int transient SSN; public int number; public void mailCheck() { System.out.println("Mailing a check to " + name + " " + address); } }
Notice that for a class to be serialized successfully, two conditions must be met:

The class must implement the java.io.Serializable interface. All of the fields in the class must be serializable. If a field is not serializable, it must be marked transient.

If you are curious to know if a Java Satandard Class is serializable or not, check the documentation for the class. The test is simple: If the class implements java.io.Serializable, then it is serializable; otherwise, it's not.

Serializing an Object:
The ObjectOutputStream class is used to serialize an Object. The following SerializeDemo program instantiates an Employee object and serializes it to a file. When the program is done executing, a file named employee.ser is created. The program does not generate any output, but study the code and try to determine what the program is doing. Note: When serializing an object to a file, the standard convention in Java is to give the file a.ser extension.

import java.io.*; public class SerializeDemo { public static void main(String [] args) { Employee e = new Employee(); e.name = "Reyan Ali"; e.address = "Phokka Kuan, Ambehta Peer"; e.SSN = 11122333; e.number = 101; try { FileOutputStream fileOut = new FileOutputStream("employee.ser"); ObjectOutputStream out = new ObjectOutputStream(fileOut); out.writeObject(e); out.close(); fileOut.close(); }catch(IOException i) { i.printStackTrace(); } } }

Deserializing an Object:

The following DeserializeDemo program deserializes the Employee object created in the SerializeDemo program. Study the program and try to determine its output:

import java.io.*; public class DeserializeDemo { public static void main(String [] args) { Employee e = null; try { FileInputStream fileIn = new FileInputStream("employee.ser"); ObjectInputStream in = new ObjectInputStream(fileIn); e = (Employee) in.readObject(); in.close(); fileIn.close(); }catch(IOException i) { i.printStackTrace(); return; }catch(ClassNotFoundException c) { System.out.println(.Employee class not found.); c.printStackTrace(); return; } System.out.println("Deserialized Employee..."); System.out.println("Name: " + e.name); System.out.println("Address: " + e.address); System.out.println("SSN: " + e.SSN); System.out.println("Number: " + e.number); } }
This would produce following result:

Deserialized Employee... Name: Reyan Ali Address:Phokka Kuan, Ambehta Peer SSN: 0 Number:101
Here are following important points to be noted:

The try/catch block tries to catch a ClassNotFoundException, which is declared by the readObject() method. For a JVM to be able to deserialize an object, it must be able to find the bytecode for the class. If the JVM can't find a class during the deserialization of an object, it throws a ClassNotFoundException. Notice that the return value of readObject() is cast to an Employee reference. The value of the SSN field was 11122333 when the object was serialized, but because the field is transient, this value was not sent to the output stream. The SSN field of the deserialized Employee object is 0.

Serialization in Java
http://www.jusfortechies.com/java/core-java/serialization.php
Serialization is the process of converting an object's state (including its references) to a sequence of bytes, as well as the process of rebuilding those bytes into a live object at some future time. Simple......Coverting an object to bytes and bytes back to object. So when is serialization used? Serialization is used when you want to persist the object. It is also used by RMI to pass objects between JVMs, either as arguments in a method invocation from a client to a server or as return values from a method invocation. In general, serialization is used when we want the object to exist beyond the lifetime of the JVM. Lets see couple of different scenarios (examples) where we use serialization.

1. Banking example: When the account holder tries to withdraw money from
the server through ATM, the account holder information along with the withdrawl details will be serialized (marshalled/flattened to bytes) and sent to server where the details are deserialized (unmarshalled/rebuilt the bytes)and used to perform operations. This will reduce the network calls as we are serializing the whole object and sending to server and further request for information from client is not needed by the server.

2. Stock example: Lets say an user wants the stock updates immediately
when he request for it. To achieve this, everytime we have an update, we can serialize it and save it in a file. When user requests the information, deserialize it from file and provide the information. This way we dont need to make the user wait for the information until we hit the database, perform computations and get the result. Here are some uses of serialization

To persist data for future use. To send data to a remote computer using such client/server Java technologies To "flatten" an object into array of bytes in memory. To exchange data between applets and servlets. To store user session in Web applications. To activate/passivate enterprise java beans. To send objects between the servers in a cluster.

as RMI or socket programming.

So far we saw what and when serialization is used. Lets see now how serialization is performed in java. Java provides Serialization API, a standard mechanism to handle object serialization. To persist an object in java, the first step is to flatten the object. For that the respective class should implement "java.io.Serializable" interface. Thats it. We dont need to implement any methods as this interface do not have any methods. This is a marker

interface/tag interface. Marking a class as Serializable indicates the underlying API that this object can be flattened.

public class SerialClass implements Serializable { private Date currentTime;

public SerialClass() { currentTime = Calendar.getInstance().getTime(); }

public Date getCurrentTime() { return currentTime; } }

Now you marked the object for flattening. Next step is to actually persist the object. To persist an object you need to use node stream to write to file systems or transfer a flattened object across a network wire and have it be rebuilt on the other side. You can use java.io.ObjectOutputStream class, a filter stream which is a wrapper around a lower-level byte stream. So to write an object you use "writeObject(<<instance>>)" method of "java.io.ObjectOutputStream" class and to read an object you use "readObject()" method of "java.io.ObjectOutputStream" class. "readObject()" can read only serialized object, that means if the class does not implement "java.io.Serializable" interface, "readObject()" cannot read that object.

//Class to persist the time in a flat file time.ser public class PersistSerialClass {

public static void main(String [] args) { String filename = "time.ser";

if(args.length > 0){ filename = args[0];

PersistSerialClass time = new PersistSerialClass(); FileOutputStream fos = null; ObjectOutputStream out = null;

try{ fos = new FileOutputStream(filename); out = new ObjectOutputStream(fos); out.writeObject(time); out.close(); }catch(IOException ex){ ex.printStackTrace(); } } }

//Class to read the time from a flat file time.ser public class ReadSerialClass {

public static void main(String [] args) { String filename = "time.ser";

if(args.length > 0){ filename = args[0]; }

PersistSerialClass time = null; FileInputStream fis = null; ObjectInputStream in = null;

try{ fis = new FileInputStream(filename);

in = new ObjectInputStream(fis); time = (PersistSerialClass)in.readObject(); in.close(); }catch(IOException ex){ ex.printStackTrace(); }catch(ClassNotFoundException cnfe){ cnfe.printStackTrace(); }

// print out restored time System.out.println("Restored time: " + time.getTime());

// print out the current time System.out.println("Current time: " + Calendar.getInstance().getTime());

} } When you serialize an object, only the object's state will be saved, not the object's class file or methods. When you serialize the above example class, the serialized class will look like below. Surprising.. isn't it? Yes, when you serialized a 2 byte object, you see 51 bytes serialized file. How did it convert to 51 bytes file? To know this, Let's see step by step on how the object is serialized and de-serialized. So when an object is serailized

First it writes out the serialization stream magic data - What is serialization

stream magic data? This is nothing but the STREAM_MAGIC and STREAM_VERSION data (static data) so that JVM can deserialize it when it has to. The STRAM_MAGIC will be "AC ED" and the STREAM_VERSION will be the version of the JVM.

Then it writes out the metadata (description) of the class associated with an

instance. So in the below example after writing out the magic data, it writes out the description of "SerialClass" class. What does this description include? It includes the length of the class, the name of the class, serialVersionUID (or serial version), various flags and the number of fields in this class.

Then it recursively writes out the metadata of the superclass until it finds

java.lang.object. Again in the below example, it writes out the description of "SerialParent" and "SerialParentParent" classes.

Once it finishes writing the metadata information, it then starts with the actual

data associated with the instance. But this time, it starts from the top most superclass. So it starts from "SerialParentParent", then writes out "SerialParent".

Finally it writes the data of objects associated with the instance starting from

metadata to actual content. So here it starts writing the metadata for the class Contain and then the contents of it as usual recursively.

class SerialParentParent implements Serializable { int parentParentVersion = 10; }

class SerialParent implements Serializable { int parentVersion = 11; }

class Contain implements Serializable{ int containVersion = 20; }

public class SerialClass extends SerialParent implements Serializable { int version = 12; Contain con = new Contain();

public int getVersion() { return version; }

public static void main(String args[]) throws IOException { FileOutputStream fos = new FileOutputStream("temp.ser"); ObjectOutputStream oos = new ObjectOutputStream(fos); SerialClass st = new SerialClass(); oos.writeObject(st); oos.flush(); oos.close();

} }

How to customize the default protocol? MMmmmm.. Now its getting more interesting. Lets say, you need to perform some specific operations in the constructor when you are instantiating the class but you cant perform those operations when you deserialize the object because constructor wont be called when an object is de-serialized. Here we are restoring an object but not reconstructing an object. Then how will you call or perform those operations when you desrialize the object? Well, you have a way here and its simple too. You can enhance the normal process by providing two methods inside your serializable class. Those methods are: private void writeObject(ObjectOutputStream out) throws IOException; private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException; Notice that both methods are declared private and ofcourse they must be declared private, proving that neither method is inherited and overridden or overloaded. The trick here is that the virtual machine will automatically check to see if either method is declared during the corresponding method call. The virtual machine can call private methods of your class whenever it wants but no other objects can. Thus, the integrity of the class is maintained and the serialization protocol can continue to work as normal.

public class SerialClass implements Serializable { private Date currentTime;

public SerialClass() { calculateCurrentTime(); }

public Date getCurrentTime() { return currentTime; }

private Date calculateCurrentTime(){ currentTime = Calendar.getInstance().getTime();

private void writeObject(ObjectOutputStream out) throws IOException { out.defaultWriteObject(); }

private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException{

// our "pseudo-constructor" in.defaultReadObject(); // now perfrom same operation you need to do in constructor calculateCurrentTime(); } }

Ooops. I mentioned earlier that for a class to be serializable either the class should implement "Serializable" interface or one of its super class should implement "Serializable" interface. Now what if you dont want to serialize one of the sub class of a serializable class? You have a way here tooo. To stop the automatic serialization, you can once again use the private methods to just throw the NotSerializableException in your class.

private void writeObject(ObjectOutputStream out) throws IOException{

throw new NotSerializableException("Dont Serialize"); }

private void readObject(ObjectInputStream in) throws IOException{

throw new NotSerializableException("Dont Serialize"); }

Well... One more way to serialize the object - the Externalizable Interface Again there is one more way to serialize the object - create your own protocol with the Externalizable interface. Instead of implementing the Serializable interface, you can implement Externalizable, which contains two methods: public void writeExternal(ObjectOutput out) throws IOException; public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException; The Externalization is discussed as separate topic. Check it out here or check the menu. How not to serialize some fields in a serializble object? Sometimes you dont want to serialize/store all the fields in the object. Say some fields you want to hide to preserve the privacy or some fields you may want to read only from master data, then you dont seriaalize them. To do this, you just need to declare a field as transient field. transient private int checkPoint; Also the static fields are not serialized. Actually there is no point in serializing static fields as static fields do not represent object state but represent class state and it can be modified by any other object. Lets assume that you have serialized a static field and its value and before deserialization of the object, the static field value is changed by some other object. Now the static field value that is serialized/stored is no more valid. Hence it make no point in serializing the static field.

Apart from declaring the field as transient, there is another tricky way of controlling what fields can be serialized and what fields cannot be. This is by overriding the writeObject() method while serialization and inside this method you are responsible for writing out the appropriate fields. When you do this, you may have to override readObject() method as well. This sound similar to using Externalizable where you will write writeExternal() and readExternal() methods but anyways lets not take this route as this is not a neat route. Note that serialization does not care about access modifiers. It serializes all private, public and protected fields. Nonserializable objects Earlier we discussed about not serializing certain fields in a serializable object and why it may be needed sometimes. But now lets see why certain objects should not be serialized? As you know, the Object class does not implement Serializable interface and hence any object by default is not serializable. To make an object serializable, the respective class should explicitly implement Serializable interface. However certain system classes defined by java like "Thread", "OutputStream", "Socket" are not serializable. Why so? Lets take a step back - now what is the use of serializing the Thread running in System1 JVM using System1 memory and then deserializing it in System2 and trying to run in System2 JVM. Makes no sense right! Hence these classes are not serializable.

Ok. So far so good. Now what if you want to serialize an object containing an instance of Thread? Simple. Declare the Thread instance as transient.

public class SerialClass implements Serializable, Runnable { transient private Thread myThread;

public PersistentAnimation(int animationSpeed) { ... ... } }

Versioning issues One very important item to look at is the versioning issue. Sometimes you wil get "java.io.InvalidClassException" but when you check the class (it will be Serializable class), you will find nothing wrong with it. Then what is causing this exception to be thrown? Ok. Here it is. You create a Serializable class, instantiate it, and write it out to an object stream. That flattened object sits in the file system for some time. Meanwhile, you update the class file by adding a new field. Then try to read the flattened object. InvalidClassException is thrown because all persistent-capable classes are automatically given a unique identifier. If the identifier of the class does not equal the identifier of the flattened object, the exception will be thrown and when you update the class with a new field, a new identifier will be generated. To fix this issue, manually add the identifier to the class. The identifier that is part of all classes is maintained in a field called serialVersionUID. If you wish to control versioning, you simply have to provide the serialVersionUID field manually and ensure it is always the same, no matter what changes you make to the classfile. More about it is discussed in separate topic. Check it here. Performance Issues/Improvement with Serialization The default way of implementing the serialization (by implementing the Serializable interface) has performance glitches. Say you have to write an object 10000 times in a flat file through serialization, this will take much more (alomost double) the time than it takes to write the same object 10000 times to console. To overcome this issue, its always better to write your custom protocol instead of going for default option.

Also always note to close the streams (object output and input streams). The object references are cached in the output stream and if the stream is not closed, the system may not garbage collect the objects written to a stream and this will result in poor performance.

Using Serialization always have performance issues? Nope... Let me give you a situation where it is used for performance improvement. Lets assume you have an application that should display a map and pointing to different areas in the map should highlight those areas in different color. Since all these are images, when you point to each location, loading an image each time will slow the application heavily. To resolve this issue, serialization can be used. So here since the images wont change, you can serialize the image object and the respective points on the map (x and y co-ordinates) and deserialize it as and when necessary. This improves the performance greatly. What happens to inner classes? We forgot all about it. Yes, you can serialize inner classes by implementing the Serializable interface but it has some problems. Inner classes (declared in a non-static context) will always contain implicit references to their enclosing classes and these references are always nontransient. So, while object serialization process of inner classes, the enclosing classes will also be serialized. Now the problem is that the synthetic fields generated by Java compilers to implement inner classes are pretty much implementation dependent and hence we may face compatibility issues while deserialization on a different platform having a .class file generated by a different Java compiler. The default serialVerionUID may also be different in such cases. Not only this, the names assigned to the local and anonymous inner classes are also implementation dependent. Thus, we see that object serialization of inner classes may pose some unavoidable compatibility issues and hence the serialization of inner classes is strongly discouraged.

Comparable and Comparator Interface http://onjava.com/onjava/2003/03/12/java_comp.html

In real life, objects are often comparable. For example, Dad's car is more expensive than Mom's, this dictionary is thicker than those books, Granny is older than Auntie Mollie (well, yeah, living objects, too, are comparable), and so forth. In writing object-oriented programs, there are often needs to compare instances of the same class. And once instances are comparable, they can be sorted. As an example, given two Employees, you may want to know which one has stayed in the organization longer. Or, in a search method for Person instances with a first name of Larry, you may want to display search results sorted by age. This article teaches you how to design your class to make its instances comparable by using the java.lang.Comparable and java.util.Comparator interfaces and presents three examples that illustrate both interfaces. Most Java programmers know how to sort the elements of a String array by using the sort method of java.util.Arrays. For String instances in an ArrayList, you can sort them with the sort method of thejava.util.Collections class. The code in Listing 1 shows how to use Arrays.sort to order String instances.

Listing 1: Sorting String Instances Using Arrays.sort


import java.util.Arrays; . . . String animals[] = new String[4]; animals[0] = "snake"; animals[1] = "kangaroo"; animals[2] = "wombat"; animals[3] = "bird"; for (int i=0; i<4; i++) { System.out.println("animal " + i + " : " + animals[i]); } Arrays.sort(animals); for (int i=0; i<4; i++) { System.out.println("animal " + i + " : " + animals[i]); }

If you run the program, the first for loop gives you the name of animals as follows:
animal animal animal animal 0 1 2 3 : : : : snake kangaroo wombat bird

And, the second for loop prints the animals sorted alphabetically.
animal animal animal animal 0 1 2 3 : : : : bird kangaroo snake wombat

With the java.util.Collections class's sort method, you can sort String instances in an ArrayList, as shown in Listing 2.

Listing 2: Sorting String Instances Using Collections.sort


import java.util.ArrayList; import java.util.Collections; . . . ArrayList insects = new ArrayList(); insects.add("mosquito"); insects.add("butterfly"); insects.add("dragonfly"); insects.add("fly"); int size = insects.size();

for (int i=0; i<size; i++) { System.out.println("insect " + i + " : " + (String) insects.get(i)); } Collections.sort(insects); for (int i=0; i<size; i++) { System.out.println("insect " + i + " : " + (String) insects.get(i)); }

The first for loop in Listing 2 produces the following output:


insect insect insect insect 0 1 2 3 : : : : mosquito butterfly dragonfly fly

The second for loop prints the following:


insect insect insect insect 0 1 2 3 : : : : butterfly dragonfly fly mosquito

However, suppose we have a Person class, as in Listing 3.

Listing 3: The Person Class


class Person { private String firstName; private String lastName; private int age; public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }

In another part of the program, we construct four instances of the Person class and populate them with names and ages:
Person[] persons = new Person[4]; persons[0] = new Person(); persons[0].setFirstName("Elvis"); persons[0].setLastName("Goodyear"); persons[0].setAge(56); persons[1] = new Person(); persons[1].setFirstName("Stanley"); persons[1].setLastName("Clark"); persons[1].setAge(8); persons[2] = new Person(); persons[2].setFirstName("Jane"); persons[2].setLastName("Graff"); persons[2].setAge(16); persons[3] = new Person(); persons[3].setFirstName("Nancy"); persons[3].setLastName("Goodyear"); persons[3].setAge(69);

How do we sort these Person instances by age or by name? Using the java.util.Arrays class' sort method, as in:
Arrays.sort(persons);

will throw a ClassCastException. You can, of course, write your own code to sort them using an algorithm such as quick sort, bubble sort, or others, but that's impractical. The easy solution is to implement the java.lang.Comparable interface.
Using the java.lang.Comparable Interface

Implement the Comparable interface to make class instances comparable. This interface has one method, compareTo, which determines how to compare two instances of the class. The signature of this method is:
public int compareTo(Object o)

The compareTo method accepts Object, so you can pass it an instance of any type. However, chances are that you want to make sure to compare two instances of the same type. It does not make sense to compare an elephant with an ant, for example. Therefore, you can throw a java.lang.ClassCastException if the argument of this method is not the same type as your class.

The compareTo method returns zero if the object passed is equal to this instance. It returns a positive integer or a negative integer if this object is greater or smaller than the passed object, respectively. Let's have a look at the examples in Listing 4 and Listing 5. Listing 4 presents a Person class that implements the Comparable interface. Notice that a Person object is older if its age value is greater than the object compared. Listing 5 shows the Testing class that constructs four instances of the Person class and sorts them by age. Both classes in Listings 4 and 5 reside in the comparable.ex01 package.

Listing 4: The Person Class That Implements the Comparable Interface


package comparable.ex01; class Person implements Comparable { private String firstName; private String lastName; private int age; public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public int compareTo(Object anotherPerson) throws ClassCastException { if (!(anotherPerson instanceof Person)) throw new ClassCastException("A Person object expected."); int anotherPersonAge = ((Person) anotherPerson).getAge(); return this.age - anotherPersonAge; } }

Listing 5: The comparable.ex01.Testing Class


package comparable.ex01; import java.util.Arrays;

import java.util.ArrayList; public class Testing { public static void main(String[] args) { Person[] persons = new Person[4]; persons[0] = new Person(); persons[0].setFirstName("Elvis"); persons[0].setLastName("Goodyear"); persons[0].setAge(56); persons[1] = new Person(); persons[1].setFirstName("Stanley"); persons[1].setLastName("Clark"); persons[1].setAge(8); persons[2] = new Person(); persons[2].setFirstName("Jane"); persons[2].setLastName("Graff"); persons[2].setAge(16); persons[3] = new Person(); persons[3].setFirstName("Nancy"); persons[3].setLastName("Goodyear"); persons[3].setAge(69); System.out.println("Natural Order"); for (int i=0; i<4; i++) { Person person = persons[i]; String lastName = person.getLastName(); String firstName = person.getFirstName(); int age = person.getAge(); System.out.println(lastName + ", " + firstName + ". Age:" + age); } Arrays.sort(persons); System.out.println(); System.out.println("Sorted by age"); for (int i=0; i<4; i++) { Person person = persons[i]; String lastName = person.getLastName(); String firstName = person.getFirstName(); int age = person.getAge(); System.out.println(lastName + ", " + firstName + ". Age:" + age); } } }

The result of the code in Listing 5 is as follows:


Natural Order Goodyear, Elvis. Age:56 Clark, Stanley. Age:8 Graff, Jane. Age:16 Goodyear, Nancy. Age:69

Sorted by age Clark, Stanley. Age:8 Graff, Jane. Age:16 Goodyear, Elvis. Age:56 Goodyear, Nancy. Age:69

Using the java.util.Comparator Class

Implementing the Comparable interface enables you to define one way to compare instances of your class. However, objects are sometimes comparable in many ways. For example, two Person objects may need to be compared by age or by last/first name. In cases like this, create a Comparator that defines how to compare two objects. To make objects comparable in two ways, then you need two comparators. To create a comparator, write a class that implements the java.util.Comparator interface--the compare method. This method has the following signature:
public int compare(Object o1, Object o2)

The compare method returns zero if o1 and o2 are equal, a negative integer if o1 is less than o2, and a positive integer if o1 is greater than o2. Just as in the compareTo method of Comparable, you define what makes an object equal or less/greater than another object. As an example, let's write two comparators for the Person class. This example consists of four classes, all of which reside in the comparable.ex02 package. The Person class is similar to the one in the previous example, and is reprinted in Listing 6 for reading convenience. Listings 7 and 8 present two comparators of Person objects (by last name and by first name), and Listing 9 offers the class that instantiates the Person class and the two comparators.

Listing 6: The comparable.ex02.Person Class


package comparable.ex02; class Person implements Comparable { private String firstName; private String lastName; private int age; public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName;

} public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public int compareTo(Object anotherPerson) throws ClassCastException { if (!(anotherPerson instanceof Person)) throw new ClassCastException("A Person object expected."); int anotherPersonAge = ((Person) anotherPerson).getAge(); return this.age - anotherPersonAge; } }

Listing 7: The comparable.ex02.LastNameComparator Class


package comparable.ex02; import java.util.Comparator; public class LastNameComparator implements Comparator { public int compare(Object person, Object anotherPerson) { String lastName1 = ((Person) person).getLastName().toUpperCase(); String firstName1 = ((Person) person).getFirstName().toUpperCase(); String lastName2 = ((Person) anotherPerson).getLastName().toUpperCase(); String firstName2 = ((Person) anotherPerson).getFirstName().toUpperCase(); if (!(lastName1.equals(lastName2))) return lastName1.compareTo(lastName2); else return firstName1.compareTo(firstName2); } }

Listing 8: The comparable.ex02.FirstNameComparator Class


package comparable.ex02; import java.util.Comparator; public class FirstNameComparator implements Comparator { public int compare(Object person, Object anotherPerson) { String lastName1 = ((Person) person).getLastName().toUpperCase(); String firstName1 = ((Person) person).getFirstName().toUpperCase();

String lastName2 = ((Person) anotherPerson).getLastName().toUpperCase(); String firstName2 = ((Person) anotherPerson).getFirstName().toUpperCase(); if (!(firstName1.equals(firstName2))) return firstName1.compareTo(firstName2); else return lastName1.compareTo(lastName2); } }

Listing 9: The comparable.ex02.Testing Class


package comparable.ex02; import java.util.Arrays; import java.util.ArrayList; public class Testing { public static void main(String[] args) { Person[] persons = new Person[4]; persons[0] = new Person(); persons[0].setFirstName("Elvis"); persons[0].setLastName("Goodyear"); persons[0].setAge(56); persons[1] = new Person(); persons[1].setFirstName("Stanley"); persons[1].setLastName("Clark"); persons[1].setAge(8); persons[2] = new Person(); persons[2].setFirstName("Jane"); persons[2].setLastName("Graff"); persons[2].setAge(16); persons[3] = new Person(); persons[3].setFirstName("Nancy"); persons[3].setLastName("Goodyear"); persons[3].setAge(69); System.out.println("Natural Order"); for (int i=0; i<4; i++) { Person person = persons[i]; String lastName = person.getLastName(); String firstName = person.getFirstName(); int age = person.getAge(); System.out.println(lastName + ", " + firstName + ". Age:" + age); } Arrays.sort(persons, new LastNameComparator()); System.out.println(); System.out.println("Sorted by last name"); for (int i=0; i<4; i++) { Person person = persons[i]; String lastName = person.getLastName(); String firstName = person.getFirstName(); int age = person.getAge();

age); }

System.out.println(lastName + ", " + firstName + ". Age:" +

Arrays.sort(persons, new FirstNameComparator()); System.out.println(); System.out.println("Sorted by first name"); for (int i=0; i<4; i++) { Person person = persons[i]; String lastName = person.getLastName(); String firstName = person.getFirstName(); int age = person.getAge(); System.out.println(lastName + ", " + firstName + ". Age:" + age); } Arrays.sort(persons); System.out.println(); System.out.println("Sorted by age"); for (int i=0; i<4; i++) { Person person = persons[i]; String lastName = person.getLastName(); String firstName = person.getFirstName(); int age = person.getAge(); System.out.println(lastName + ", " + firstName + ". Age:" + age); } } }

If you run the comparable.ex02.Testing class, you can see the following result:
Natural Order Goodyear, Elvis. Age:56 Clark, Stanley. Age:8 Graff, Jane. Age:16 Goodyear, Nancy. Age:69 Sorted by last name Clark, Stanley. Age:8 Goodyear, Elvis. Age:56 Goodyear, Nancy. Age:69 Graff, Jane. Age:16 Sorted by first name Goodyear, Elvis. Age:56 Graff, Jane. Age:16 Goodyear, Nancy. Age:69 Clark, Stanley. Age:8 Sorted by age Clark, Stanley. Age:8 Graff, Jane. Age:16 Goodyear, Elvis. Age:56 Goodyear, Nancy. Age:69

Integrating Comparators in Comparable Classes

The previous example with the Comparator interface works fine. However, the drawback is that it requires multiple classes. This means more maintenance work for the users of your comparable class. The next example shows how to integrate the comparators inside of the comparable class by making the comparators anonymous classes. This example has two classes: comparable.ex03.Person (Listing 10) and comparable.ex03.Testing (Listing 11). Note the two anonymous inner classes at the end of the Person class, and notice also in theTesting class how comparison is conducted.

Listing 10: The comparable.ex03.Person Class


package comparable.ex03; import java.util.Comparator; public class Person implements Comparable { private String firstName; private String lastName; private int age; public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public int compareTo(Object anotherPerson) throws ClassCastException { if (!(anotherPerson instanceof Person)) throw new ClassCastException("A Person object expected."); int anotherPersonAge = ((Person) anotherPerson).getAge(); return this.age - anotherPersonAge; } public static Comparator LastNameComparator = new Comparator() {

public int compare(Object person, Object anotherPerson) { String lastName1 = ((Person) person).getLastName().toUpperCase(); String firstName1 = ((Person) person).getFirstName().toUpperCase(); String lastName2 = ((Person) anotherPerson).getLastName().toUpperCase(); String firstName2 = ((Person) anotherPerson).getFirstName().toUpperCase(); if (!(lastName1.equals(lastName2))) return lastName1.compareTo(lastName2); else return firstName1.compareTo(firstName2); }; }

public static Comparator FirstNameComparator = new Comparator() { public int compare(Object person, Object anotherPerson) { String lastName1 = ((Person) person).getLastName().toUpperCase(); String firstName1 = ((Person) person).getFirstName().toUpperCase(); String lastName2 = ((Person) anotherPerson).getLastName().toUpperCase(); String firstName2 = ((Person) anotherPerson).getFirstName().toUpperCase(); if (!(firstName1.equals(firstName2))) return firstName1.compareTo(firstName2); else return lastName1.compareTo(lastName2); }; } }

Listing 11: The comparable.ex03.Testing Class


package comparable.ex03; import java.util.Arrays; import java.util.ArrayList; public class Testing { public static void main(String[] args) { Person[] persons = new Person[4]; persons[0] = new Person(); persons[0].setFirstName("Elvis"); persons[0].setLastName("Goodyear"); persons[0].setAge(56); persons[1] = new Person(); persons[1].setFirstName("Stanley"); persons[1].setLastName("Clark"); persons[1].setAge(8); persons[2] = new Person(); persons[2].setFirstName("Jane"); persons[2].setLastName("Graff"); persons[2].setAge(16);

persons[3] = new Person(); persons[3].setFirstName("Nancy"); persons[3].setLastName("Goodyear"); persons[3].setAge(69); System.out.println("Natural Order"); for (int i=0; i<4; i++) { Person person = persons[i]; String lastName = person.getLastName(); String firstName = person.getFirstName(); int age = person.getAge(); System.out.println(lastName + ", " + firstName + ". Age:" + age); } Arrays.sort(persons, Person.LastNameComparator); System.out.println(); System.out.println("Sorted by last name"); for (int i=0; i<4; i++) { Person person = persons[i]; String lastName = person.getLastName(); String firstName = person.getFirstName(); int age = person.getAge(); System.out.println(lastName + ", " + firstName + ". Age:" + age); } Arrays.sort(persons, Person.FirstNameComparator); System.out.println(); System.out.println("Sorted by first name"); for (int i=0; i<4; i++) { Person person = persons[i]; String lastName = person.getLastName(); String firstName = person.getFirstName(); int age = person.getAge(); System.out.println(lastName + ", " + firstName + ". Age:" + age); } Arrays.sort(persons); System.out.println(); System.out.println("Sorted by age"); for (int i=0; i<4; i++) { Person person = persons[i]; String lastName = person.getLastName(); String firstName = person.getFirstName(); int age = person.getAge(); System.out.println(lastName + ", " + firstName + ". Age:" + age); } } }

The result of the Testing class is the same as the previous example. However, note that the comparators are inside of the Person class. To sort instances of the Person class by last name, you just need to use:
Arrays.sort(persons, Person.LastNameComparator);

To sort them by first name:


Arrays.sort(persons, Person.LastNameComparator);

Summary

This article has demonstrated how to make class instances comparable and sortable. Example 1 shows that implementing the compareTo method of the java.lang.Comparable interface is the easiest solution. To compare instances in multiple ways, create comparators by implementing the java.util.Comparator class, as demonstrated in Example 2. For better maintenance, you can embed the comparators as anonymous classes in your comparable class, as shown in Example 3. Exception Handling works
1.It separates the working/functional code from the error-handling code by way of trycatch clauses. 2.It allows a clean path for error propagation. If the called method encounters a situation it can't manage, it can throw an exception and let the calling method deal with it. 3.By enlisting the compiler to ensure that "exceptional" situations are anticipated and accounted for, it enforces powerful coding. 4.Exceptions are of two types: Compiler-enforced exceptions, or checked exceptions. Runtime exceptions, or unchecked exceptions. Compiler-enforced (checked) exceptions are instances of the Exception class or one of its subclasses '?? excluding the RuntimeException branch. The compiler expects all checked exceptions to be appropriately handled. Checked exceptions must be declared in the throws clause of the method throwing them '?? assuming, of course, they're not being caught within that same method. The calling method must take care of these exceptions by either catching or declaring them in its throws clause. Thus, making an exception checked forces the us to pay heed to the possibility of it being thrown. An example of a checked exception is java.io.IOException. As the name suggests, it throws whenever an input/output operation is abnormally terminated.

What synchronization constructs does Java provide? How do they work?


Ans. The two common features that are used are: 1. Synchronized keyword - Used to synchronize a method or a block of code. When you synchronize a method, you are in effect synchronizing the code within the method using the monitor of the current object for the lock. The following have the same effect. synchronized void foo() { } and void foo() {

synchronized(this) { } If you synchronize a static method, then you are synchronizing across all objects of the same class, i.e. the monitor you are using for the lock is one per class, not one per object. 2. wait/notify. wait() needs to be called from within a synchronized block. It will first release the lock acquired from the synchronization and then wait for a signal. In Posix C, this part is equivalent to the pthread_cond_wait method, which waits for an OS signal to continue. When somebody calls notify() on the object, this will signal the code which has been waiting, and the code will continue from that point. If there are several sections of code that are in the wait state, you can call notifyAll() which will notify all threads that are waiting on the monitor for the current object. Remember that both wait() and notify() have to be called from blocks of code that are synchronized on the monitor for the current object.

Ques. What is RMI?


Ans. RMI stands for Remote Method Invocation. Traditional approaches to executing code on other machines across a network have been confusing as well as tedious and errorprone to implement. The nicest way to think about this problem is that some object happens to live on another machine, and that you can send a message to the remote object and get a result as if the object lived on your local machine. This simplification is exactly what Java Remote Method Invocation (RMI) allows you to do. Above excerpt is from "Thinking in java". For more information refer to any book on Java.

Ques. What are java beans?


Ans. JavaBeans is a portable, platform-independent component model written in the Java programming language, developed in collaboration with industry leaders. It enables developers to write reusable components once and run them anywhere ' benefiting from the platform-independent power of Java technology. JavaBeans acts as a Bridge between proprietary component models and provides a seamless and powerful means for developers to build components that run in ActiveX container applications. JavaBeans are usual Java classes which adhere to certain coding conventions: 1. Implements java.io.Serializable interface 2. Provides no argument constructor 3. Provides getter and setter methods for accessing it'??s properties

Ques. What is the difference between a Vector and an Array. Discuss the advantages and disadvantages of both?
Ans. Vector can contain objects of different types whereas array can contain objects only of a single type. - Vector can expand at run-time, while array length is fixed. - Vector methods are synchronized while Array methods are not

Ques. What is the difference between StringBuffer and String class?


Ans. A string buffer implements a mutable sequence of characters. A string buffer is like a String, but can be modified. At any point in time it contains some particular sequence of characters, but the length and content of the sequence can be changed through certain method calls. The String class represents character strings. All string literals in Java programs, such as

"abc" are constant and implemented as instances of this class; their values cannot be changed after they are created. Strings in Java are known to be immutable. Explanation: What it means is that every time you need to make a change to a String variable, behind the scene, a "new" String is actually being created by the JVM. For an example: if you change your String variable 2 times, then you end up with 3 Strings: one current and 2 that are ready for garbage collection. The garbage collection cycle is quite unpredictable and these additional unwanted Strings will take up memory until that cycle occurs. For better performance, use StringBuffers for string-type data that will be reused or changed frequently. There is more overhead per class than using String, but you will end up with less overall classes and consequently consume less memory. Describe, in general, how java's garbage collector works? The Java runtime environment deletes objects when it determines that they are no longer being used. This process is known as garbage collection. The Java runtime environment supports a garbage collector that periodically frees the memory used by objects that are no longer needed. The Java garbage collector is a mark-sweep garbage collector that scans Java's dynamic memory areas for objects, marking those that are referenced. After all possible paths to objects are investigated, those objects that are not marked (i.e. are not referenced) are known to be garbage and are collected. (A more complete description of our garbage collection algorithm might be "A compacting, mark-sweep collector with some conservative scanning".) The garbage collector runs synchronously when the system runs out of memory, or in response to a request from a Java program. Your Java program can ask the garbage collector to run at any time by calling System.gc(). The garbage collector requires about 20 milliseconds to complete its task so, your program should only run the garbage collector when there will be no performance impact and the program anticipates an idle period long enough for the garbage collector to finish its job. Note: Asking the garbage collection to run does not guarantee that your objects will be garbage collected. The Java garbage collector runs asynchronously when the system is idle on systems that allow the Java runtime to note when a thread has begun and to interrupt another thread (such as Windows 95). As soon as another thread becomes active, the garbage collector is asked to get to a consistent state and then terminate.

Ques. What is the advantage of OOP?


Ans. You will get varying answers to this question depending on whom you ask. Major advantages of OOP are: 1. Simplicity: software objects model real world objects, so the complexity is reduced and the program structure is very clear; 2. Modularity: each object forms a separate entity whose internal workings are decoupled from other parts of the system; 3. Modifiability: it is easy to make minor changes in the data representation or the procedures in an OO program. Changes inside a class do not affect any other part of a program, since the only public interface that the external world has to a class is through the use of methods; 4. Extensibility: adding new features or responding to changing operating environments can be solved by introducing a few new objects and modifying some existing ones; 5. Maintainability: objects can be maintained separately, making locating and fixing problems easier; 6. Re-usability: objects can be reused in different programs

Ques. Describe what happens when an object is created in Java?


Ans. Several things happen in a particular order to ensure the object is constructed properly: 1. Memory is allocated from heap to hold all instance variables and implementation-specific data of the object and its superclasses. Implementation-specific data includes pointers to class and method data. 2. The instance variables of the objects are initialized to their default values. 3. The constructor for the most derived class is invoked. The first thing a constructor does

is call the constructor for its uppercase. This process continues until the constructor for java.lang.Object is called, as java.lang.Object is the base class for all objects in java. 4. Before the body of the constructor is executed, all instance variable initializers and initialization blocks are executed. Then the body of the constructor is executed. Thus, the constructor for the base class completes first and constructor for the most derived class completes last.

Ques. How can you minimize the need of garbage collection and make the memory use more effective?
Ans. Use object pooling and weak object references. Pooling basically means utilizing the resources efficiently, by limiting access of the objects to only the period the client requires it. Increasing utilization through pooling usually increases system performance. Object pooling is a way to manage access to a finite set of objects among competing clients. in other words, object pooling is nothing but sharing of objects between different clients. Since object pooling allows sharing of objects ,the other clients/processes need to reinstantiate the object(which decreases the load time), instead they can use an existing object. After the usage , the objects are returned to the pool.

Ques. How would you make a copy of an entire Java object with its state?
Ans. Have this class implement Cloneable interface and call its method clone().

Ques. What comes to mind when someone mentions a shallow copy and deep copy in Java?
Ans. Object cloning. Java provides a mechanism for creating copies of objects called cloning. There are two ways to make a copy of an object called shallow copy and deep copy. Shallow copy is a bit-wise copy of an object. A new object is created that has an exact copy of the values in the original object. If any of the fields of the object are references to other objects, just the references are copied. Thus, if the object you are copying contains references to yet other objects, a shallow copy refers to the same subobjects. Deep copy is a complete duplicate copy of an object. If an object has references to other objects, complete new copies of those objects are also made. A deep copy generates a copy not only of the primitive values of the original object, but copies of all subobjects as well, all the way to the bottom. If you need a true, complete copy of the original object, then you will need to implement a full deep copy for the object. Java supports shallow and deep copy with the Cloneable interface to create copies of objects. To make a clone of a Java object, you declare that an object implements Cloneable, and then provide an override of the clone method of the standard Java Object base class. Implementing Cloneable tells the java compiler that your object is Cloneable. The cloning is actually done by the clone method.

Ques. What comes to mind when you hear about a young generation in Java?
Ans. Garbage collection.

In the J2SE platform version 1.4.1 two new garbage collectors were introduced to make a total of four garbage collectors from which to choose. Beginning with the J2SE platform, version 1.2, the virtual machine incorporated a number of different garbage collection algorithms that are combined using generational collection. While naive garbage collection examines every live object in the heap, generational collection exploits several empirically observed properties of most applications to avoid extra work. The default collector in HotSpot has two generations: the young generation and the tenured generation. Most allocations are done in the young generation. The young generation is optimized for objects that have a short lifetime relative to the interval between collections. Objects that survive several collections in the young generation are moved to the tenured generation. The young generation is typically smaller and is collected more often. The tenured generation is typically larger and collected less often. The young generation collector is a copying collector. The young generation is divided into 3 spaces: eden-space, to-space, and from-space. Allocations are done from eden-space and from-space. When those are full a young generation is collection is done. The expectation is that most of the objects are garbage and any surviving objects can be copied to to-space. If there are more surviving objects than can fit into to-space, the remaining objects are copied into the tenured generation. There is an option to collect the young generation in parallel. The tenured generation is collected with a mark-sweep-compact collection. There is an option to collect the tenured generation concurrently.

Ques. What's the difference between a queue and a stack?


Ans. Stacks works by last-in-first-out rule (LIFO), while queues use the FIFO rule. You can think of a queue like a line at the bank. The first person to get there will get to the teller first. If a bunch of people come while all the tellers are busy, they stand in line in the order in which they arrived. That is to say, new people (items) are added to the end of the line and the first person in line is the only one who is called to a teller. In real life this is known as "first come, first served." In programming terms it's known as first-in-first-out, or FIFO. You can think of a stack like a deck of cards. You can put down cards into a pile on your table one at a time, but if you want to draw cards, you can only draw them from the top of the deck one at a time. Unlike a queue, the first card to be put down is the last card to be used. This is known as first-in-last-out, or FILO (also called LIFO for last-in-first-out). A queue is a first-in-first-out data structure. When you add an element to the queue you are adding it to the end, and when you remove an element you are removing it from the beginning. A stack is a first-in-last-out data structure. When you add an element to a stack you are adding it to the end, and when you remove an element you are removing it from the end.

Ques. What's the main difference between a Vector and an ArrayList?


Ans. Sometimes Vector is better; sometimes ArrayList is better; sometimes you don't want to use either. I hope you weren't looking for an easy answer because the answer depends upon what you are doing. There are four factors to consider: API Synchronization Data growth

Usage patterns API: In The Java Programming Language Ken Arnold, James Gosling, and David Holmes describe the Vector as an analog to the ArrayList. So, from an API perspective, the two classes are very similar. However, there are still some major differences between the two classes. Synchronization: Vectors are synchronized. Any method that touches the Vector's contents is thread safe. ArrayList, on the other hand, is unsynchronized, making them, therefore, not thread safe. With that difference in mind, using synchronization will incur a performance hit. So if you don't need a thread-safe collection, use the ArrayList. Why pay the price of synchronization unnecessarily? Data growth: Internally, both the ArrayList and Vector hold onto their contents using an Array. You need to keep this fact in mind while using either in your programs. When you insert an element into an ArrayList or a Vector, the object will need to expand its internal array if it runs out of room. A Vector defaults to doubling the size of its array, while the ArrayList increases its array size by 50 percent. Depending on how you use these classes, you could end up taking a large performance hit while adding new elements. It's always best to set the object's initial capacity to the largest capacity that your program will need. By carefully setting the capacity, you can avoid paying the penalty needed to resize the internal array later. If you don't know how much data you'll have, but you do know the rate at which it grows, Vector does possess a slight advantage since you can set the increment value. Usage patterns: Both the ArrayList and Vector are good for retrieving elements from a specific position in the container or for adding and removing elements from the end of the container. All of these operations can be performed in constant time -- O(1). However, adding and removing elements from any other position proves more expensive -- linear to be exact: O(n-i), where n is the number of elements and i is the index of the element added or removed. These operations are more expensive because you have to shift all elements at index i and higher over by one element. So what does this all mean? It means that if you want to index elements or add and remove elements at the end of the array, use either a Vector or an ArrayList. If you want to do anything else to the contents, go find yourself another container class. For example, the LinkedList can add or remove an element at any position in constant time -- O(1). However, indexing an element is a bit slower -- O(i) where i is the index of the element. Traversing an ArrayList is also easier since you can simply use an index instead of having to create an iterator. The LinkedList also creates an internal object for each element inserted. So you have to be aware of the extra garbage being created.

If a class is located in a package, what do you need to change in the OS environment to be able to use it?
Ans. You need to add a directory or a jar file that contains the package directories to the CLASSPATH environment variable. Lets say a class Employee belongs to a package com.xyz.hr; and is located in the file c:/dev/com.xyz.hr.Employee.java. In this case, you'd need to add c:/dev to the variable CLASSPATH. If this class contains the method main(), you could test it from a command prompt window as follows: c:\>java com.xyz.hr.Employee

Ques. Explain the usage of Java packages.


Ans. This is a way to organize files when a project consists of multiple modules. It also helps resolve naming conflicts when different packages have classes with the same names. Packages access level also allows you to protect data from being used by the nonauthorized classes. e.g.

java.lang basic language functionality and fundamental types java.util collection data structure classes java.io file operations java.math multiprecision arithmetics java.nio the New I/O framework for Java java.net networking operations, sockets, DNS lookups, ... java.security key generation, encryption and decryption java.sql Java Database Connectivity (JDBC) to access databases java.awt basic hierarchy of packages for native GUI components javax.swing hierarchy of packages for platform-independent rich GUI components java.applet classes for creating an applet

Ques. Explain the usage of the keyword transient?


Ans. This keyword indicates that the value of this member variable does not have to be serialized with the object. When the class will be de-serialized, this variable will be initialized with a default value of its data type (i.e. zero for integers). For example: class T { transient int a; // will not persist int b; // will persist } Example: import import import import import import java.io.FileInputStream; java.io.FileOutputStream; java.io.ObjectInputStream; java.io.ObjectOutputStream; java.io.Serializable; java.util.Date;

public class Logon implements Serializable { private Date date = new Date(); private String username; private transient String password; public Logon(String name, String pwd) { username = name; password = pwd; } public String toString() { String pwd = (password == null) ? "(n/a)" : password; return "logon info: \n username: " + username + "\n date: " + date + "\n password: " + pwd; } public static void main(String[] args) throws Exception { Logon a = new Logon("Hulk", "myLittlePony"); System.out.println("logon a = " + a); ObjectOutputStream o = new ObjectOutputStream(new FileOutputStream( "Logon.out")); o.writeObject(a); o.close();

Thread.sleep(1000); // Delay for 1 second // Now get them back: ObjectInputStream in = new ObjectInputStream(new FileInputStream( "Logon.out")); System.out.println("Recovering object at " + new Date()); a = (Logon) in.readObject(); System.out.println("logon a = " + a); } }

Ques. Why would you use a synchronized block vs. synchronized method?
Ans. Synchronized blocks place locks for shorter periods than synchronized methods. if you go for synchronized block it will lock a specific object. if you go for synchronized method it will lock all the objects. in other way Both the synchronized method and block are used to acquires the lock for an object. But the context may vary. Suppose if we want to invoke a critical method which is in a class whose access is not available then synchronized block is used. Otherwise synchronized method can be used. Synchronized methods are used when we are sure all instance will work on the same set of data through the same function Synchronized block is used when we use code which we cannot modify ourselves like third party jars etc For a detail clarification see the below code for example: //Synchronized block class A { public void method1() {...} } class B { public static void main(String s[]) { A objecta=new A(); A objectb=new A(); synchronized(objecta){objecta.method1();} objectb.method1(); //not synchronized } } //synchronized method class A { public synchronized void method1() { ...} } class B { public static void main(String s[]) { A objecta=new A(); A objectb =new A(); objecta.method1(); objectb.method2(); } }

You might also like