Monday, September 19, 2005

Object Serialization and DeSerialization

This class writes an int primitive data type, a String and a Date Object which are predefined java class files that implements serializable interface into persistance storage.

import java.io.*;

import java.util.*;

class ObjectSeril {

public static void main(String[] args) {

int t =50000;

try {

FileOutputStream out = new FileOutputStream("theTime.tmp");

ObjectOutputStream s = new ObjectOutputStream(out);

s.writeObject("Today");

// s.writeObject(t); Only Objects

s.writeInt(t);

s.writeObject(new Date());

s.flush();

} catch(IOException e) {

System.out.println(e);

}

try {

FileInputStream out = new FileInputStream("theTime.tmp");

ObjectInputStream s = new ObjectInputStream(out);

String str = (String) s.readObject();

System.out.println(str);

// s.writeObject(t); Only Objects

int in = s.readInt();

System.out.println(in);

Date d = (Date) s.readObject();

System.out.println(d);

s.close();

} catch(IOException e1) {

System.out.println(e1);

}catch(ClassNotFoundException e2) {

System.out.println(e2);

}

}

}

How to Write to an ObjectOutputStream

Writing objects to a stream is a straightforward process.

ObjectOutputStream must be constructed on another stream. This code constructs an ObjectOutputStream on a FileOutputStream.

An ObjectOutputStream can be used to write primitive data types along with Java objects to an OutputStream. An object is serializable(that is its state[ instance variables] can be stored in persistance storage) only if its class implements the Serializable interface. The objects can be read (reconstituted) using an ObjectInputStream. Persistent storage of objects can be accomplished by using a file for the stream.Only objects that support the java.io.Serializable interface can be written to streams. Both String class of java.lang package and Date class of java.util package implements Serializable interface. So only we are able to write both the Objects into persistance storage using Serialization in the above code.

Next, the string Today, an int and a Date object are written to the stream with the writeInt and writeObject method of ObjectOutputStream.

Thus, the writeObject method serializes the specified object, traverses its references to other objects recursively, and writes them all. In this way, relationships between objects are maintained.

ObjectOutputStream implements the DataOutput interface that defines many methods for writing primitive data types, such as writeInt, writeFloat, or writeUTF. You can use these methods to write primitive data types to an ObjectOutputStream.

The writeObject method throws a NotSerializableException if it's given an object that is not serializable. An object is serializable only if its class implements the Serializable interface.


How to Read from an ObjectInputStream

Once you've written objects and primitive data types to a stream, you'll likely want to read them out again and reconstruct the objects. This is also straightforward. Here's code that reads in the String, int and the Date objects that were written to the file named theTime in the previous example:

Like ObjectOutputStream, ObjectInputStream must be constructed on another stream. In this example, the objects were archived in a file, so the code constructs an ObjectInputStream on a FileInputStream. Next, the code uses ObjectInputStream's readObject method to read the String and the Date objects from the file. The objects must be read from the stream in the same order in which they were written. Note that the return value from readObject is an object that is cast to and assigned to a specific type.

The readObject method deserializes the next object in the stream and traverses its references to other objects recursively to deserialize all objects that are reachable from it. In this way, it maintains the relationships between the objects.

ObjectInputStream stream implements the DataInput interface that defines methods for reading primitive data types. The methods in DataInput parallel those defined in DataOutput for writing primitive data types. They include methods such as readInt, readFloat, and readUTF. Use these methods to read primitive data types from an ObjectInputStream.

The following example creates an user-defined class that implements serializable interface, and its Object is Serialized (or) written to persistance storage.

import java.io.*;

import java.util.*;

public class ObjectSeril {

public static void main(String[] args) {

int t =50000;

try {

MyClass mclass = new MyClass(10, 20.5, "vishnu");

System.out.println("MyClass Object:");

System.out.println("~~~~~~~~~~~~~");

System.out.println("Before Serialization:");

System.out.println(mclass + "\n");


FileOutputStream out = new FileOutputStream("theTime");

ObjectOutputStream s = new ObjectOutputStream(out);

s.writeObject(mclass);

s.flush();

} catch(IOException e) {

System.out.println(e);

}

try {

MyClass myclass;

FileInputStream in = new FileInputStream("theTime");

ObjectInputStream s = new ObjectInputStream(in);

myclass = (MyClass) s.readObject();

System.out.println("After Serialization:");

System.out.println(myclass);


s.close();

} catch(IOException e1) {

System.out.println(e1);

}catch(ClassNotFoundException e2) {

System.out.println(e2);

}

}

}

class MyClass implements Serializable {

int in;

transient double d;

String str;

public MyClass(int in, double d, String str) {

this.in = in;

this.d = d;

this.str = str;

}

public String toString() {

return "int value: " + in + " double value: " + d + " string value: " + str;

}

}

Note the primitive type double thats marked with the keyword transient is not written to the persistance storage.

Output


MyClass Object:

~~~~~~~~~~~~~

Before Serialization:

int value: 10 double value: 20.5 string value: vishnu

After Serialization:

int value: 10 double value: 0.0 string value: vishnu

method local inner classes - final variables

The method local inner classes can only access the final variables of the method enclosing.

Why is it so? what is the special treatment to final variables?

Ans:

You see, the access that inner classes have to local (method) variables and parameters is an illusion. You don't have any access to local variables. What happens behind the scenes is that the Java compiler creates instance variables in your inner class which contain copies of the local variables you "access".

The problem is, if either the method or the inner class were allowed to change its copy of the variable, the different copies would get out of sync and the illusion would be shattered. This is why the compiler forces you to declare the variable final: so that it can freely generate multiple copies and create the illusion that your inner class has access to them.

The inner class implementation is full of such trickery. It had to be, because Sun added them to the Java language without changing the JVM spec. For example, the special access that inner (and nested) classes have to private variables of their enclosing class is... you guessed it... an illusion. Access is granted through special accessor methods generated by the compiler.

If you don't believe me, use javap to disassemble some class files that have inner classes


What u get when u print null?

Compile time error

Example:

class Hello{

public static void main(String[] args) {

System.out.println(null);

}

}


Hello.java:3: reference to println is ambiguous, both method println(char[]) in

java.io.PrintStream and method println(java.lang.String) in java.io.PrintStream

match

System.out.println(null);

^

1 error

volatile feilds

The volatile keyword tells the compiler to make sure that all threads use the same copy of the variable. If there is no volatile then each thread will use their own copy of the same variable. The reason threads may make their own copies of variables is due to optimization.


Java - Platform Independent Language.

"Platform independant" means that you compile it once, and that same executable file can be run on any system (that has a JRE).

It does NOT mean that you write the code, and then compile it on 27 different machines to make 27 different binaries that each can only be run on a specific machine, even if they're all built from the same source code file.


Floating point accuracy

public class MaxValueComparisonTest {

static double d;

static float f;

public static void main(String args[]) {

compare(Long.MAX_VALUE, Long.MAX_VALUE );

compare(Integer.MAX_VALUE, Integer.MAX_VALUE ); //1

compare(Character.MAX_VALUE, Character.MAX_VALUE); //2

compare(Short.MAX_VALUE, Short.MAX_VALUE ); //3

compare(Byte.MAX_VALUE, Byte.MAX_VALUE ); //4

}

static void compare(double d, float f) {

if (f == d) System.out.print(" equal" );

else System.out.print(" unequal");

}

}

o/p ==> equal unequal equal equal equal


Question: Please explain the output

To understand this result you have to understand the concept of floating point precision. The primitive type float can represent 23 bits of precision. Now, Integer.MAX_VALUE needs 32 bits of precision to represent its exact value. so Integer.MAX_VALUE is unable to fit into 23 bits precision of float. So it is truncated to 23 bits in the case of Float and not truncated in double. That’s why the result is false. The conversion to float rounds, the conversion to double does not.

The only question is why Long.MAX_VALUE doesn't have the same behavior ?

When it comes to Long.MAX_VALUE, primitive type long needs 64 bits of precision to represent its exact value. The primitive type double can represent 52 bits of precision and float can represent only 23 bits of precision. Hence Long.MAX_VALUE rounds in both cases.

In the above code, you're comparing a float and a double, so the compiler promotes the float to a double in order to do the comparison, because the compiler needs the two values to be the same type before comparing them.

Example to prove the above theory:

public class FloatNDouble{
public static void main(String args[]) {
System.out.println(Long.toBinaryString(Double.doubleToLongBits((double)(float)Integer.MAX_VALUE)));
System.out.println(Long.toBinaryString(Double.doubleToLongBits((double)Integer.MAX_VALUE)));
System.out.println(Long.toBinaryString(Double.doubleToLongBits((double)(float)Long.MAX_VALUE)));
System.out.println(Long.toBinaryString(Double.doubleToLongBits((double)Long.MAX_VALUE)));
}
}


Notice that to compare the two numbers the float will have to be converted to a double. That's why I did (double)(float)Integer.MAX_VALUE and (double)(float)Long.MAX_VALUE.


Output:

 100000111100000000000000000000000000000000000000000000000000000
100000111011111111111111111111111111111110000000000000000000000
100001111100000000000000000000000000000000000000000000000000000
100001111100000000000000000000000000000000000000000000000000000

NOTE:

Do not confuse the precision of a floating point number with its range. Both float and double can represent an int (or) long within their respective ranges. That's why we get widening conversions from int (or) long to float or double.

Saturday, September 17, 2005

Garbage Collection

public class Runner {

public static void main(String[] args) {

MyType myType = new MyType();

myType=null; // Line 1

java.util.ArrayList arrayList = new java.util.ArrayList(); //line 5

while(true) {

arrayList.add(new String("waste"));

}

}

}


class MyType{

protected void finalize() {

System.out.println("bye");

}

}

output:

bye

Exception in thread "main" java.lang.OutOfMemoryError


Why this program is printing bye?

Why this program is printing bye followed by OutOfMemoryError?

java.lang.OutOfMemoryError:

Thrown when the Java Virtual Machine cannot allocate an object because it is out of memory, and no more memory could be made available by the garbage collector.

This Program demonstrates how JVM runs Garbage Collecter atleast once before giving error(OutOfMemoryError). Garbage Collector calls "finalize()" method before trying to delete Objects. Since no Objects can be deleted we get runtime error.

This program also demostrates how a strong reference stops an Object from being Garbage Collected.

Example "Line 1" if it is commented then that means there is a strong reference to MyType instance meaning it cannot be garbage collected. You will not see "bye" in the output.

output:

Exception in thread "main" java.lang.OutOfMemoryError

Exception Handling

public class Ex {

public int getX(int y) {

int k=27;

try{

k=k/y;

return k;

} catch(Exception e) {

System.out.println("exception caught");

k=k/y;

// throw new ArithmeticException(); // Line 1

return k;

} finally {

System.out.println("finally");

// k=k/y; // Line 2

return 5; // Line 3

}

}

public static void main(String args[]) {

Ex eh=new Ex();

System.out.println( eh.getX(0));

}

}

output:

exception caught

finally

5


Since the finally clause should execute no matter whether a new exception is thrown inside a catch block (or)Not the o/p "finally" is printed and

The "return " statement in finally clause actually nullifies the exception so only you are not getting the exception stack trace printed during runtime.

try commenting the return statement in finally block.

When ever there is a return statement inside a finally block then it will result in a warning while compiling like

Ex.java:21: warning: finally clause cannot complete normally

}

^

1 warning

Note: If you check line 1 there is a new checked exception being thrown explicitly and if thats the case then the immediate next line will be unreacheable statement complained by the compiler. Hence no statement goes after an explicitly thrown exception(either Checked (or) UnChecked).

To stop the compiler from complaining about explicitly thrown checked exceptions either you should declare it in the throws clause (or) have a corresponding catch statement. But there is such no restriction for an unchecked exception.

Regarding Line 2

If line 2 and line 3 are commented

If a finally block contains a throw(Programatically (or) explicit throw statement) or return, these cause any previously-thrown exception to be discarded. However if the finally block does not throw an exception or return, then any uncaught exception from the try block (or) catch block will still be thrown after the finally completes.

Regarding Line 3

If line 3 is uncommented

There are differences between throwing a exception [ either explicitly (or) programatically ] and return statement in a finally block

The return statement nullifies any previous exception and makes sure the programs flow continues normally. Regarding a exception thrown inside a finally block even though it discards any previous exceptions( either is try block (or) catch block) still it generates a new exception and you will see a stack trace print during runtime.

Final class methods are not implicitly final


All methods declared in a final class are implicitly final ?

Implicitly.

That's a good word, one which the JLS uses fairly often when it's actually called for. However I don't think you'll be able to find any statement in the JLS which implies that methods of a final class are implicitly final. That's probably because the JLS authors felt it was really irrelevant whether the methods of a final class were technically final or not - as long as you can't extend the class itself, there's no possible way to override one of its methods. Regardless of whether the methods themselves are "final" or not. The important point is that a final class cannot ever be extended, which means that a method of a final class cannot ever be overridden. As long as you understand that, the above statement is really irrelevant.

import java.lang.reflect.Method;

import java.lang.reflect.Modifier;

public final class Test1 {

public static void main(String[] args) throws Exception {

Class [] c = new Class[3];

c[0] = args.getClass();

c[1] = int.class;

c[2] = double.class;

Method mainMethod = Test1.class.getMethod("call", c);

System.out.println("Modifiers: " + mainMethod.getModifiers());

boolean isFinal = Modifier.isFinal(mainMethod.getModifiers());

System.out.println("main method is final: " + isFinal);


Class[] cc = mainMethod.getParameterTypes();

System.out.println("parameters of the method: " + mainMethod.getName() );

for( int i=0;i

System.out.println("parameter " + i + ": " + cc[i]);

}

}

public void call(String[] args, int i,double d) {

}

}

Output:

main method is final: false

parameters of the method: call

parameter 0: class [Ljava.lang.String;

parameter 1: int

parameter 2: double

Exception Bug


The Exception class itself is a checked exception (as anything not in the RuntimeException hierarchy should be). That's fine, but if I create a subclass of Exception, call it NewException, and then I use it with an empty try block:


code:

try {

} catch(NewException e) {

...

}

compilation fails with "exception NewException is never thrown in body of corresponding try statement". But if I use Exception itself:

code:

try {

} catch(Exception e) {

...

}

it compiles fine. Why is the behavior different between these two checked exceptions?

Ans: 1

The Java compiler warns about catch blocks that couldn't possibly be entered. Note that RuntimeException is a subclass of Exception, and there are a large number of RuntimeExceptions that can be thrown by virtually any code -- NullPointerException, ArrayIndexOutOfBoundsException, etc. Therefore a catch for Exception is almost always applicable.

Now, it's true, actually, that the compiler cheats a little; I'm pretty sure an empty try block can't throw an Exception (it can throw a Throwable, though: ThreadDeath is just one example.) The Java Language Spec doesn't seem to say anything about this (Jim, you listening?) But in any case, the catch block for Exception can catch the whole family of RuntimeExceptions, which needn't be declared, and therefore, in theory, can be thrown by any code.

Ans: 2

I think it does say something - it says the compiler is in error here. [shocked] The relevant section is JLS2 14.20:

"A catch block C is reachable iff [...] some expression or throw statement in the try block is reachable and can throw an exception whose type is assignable to the parameter of the catch clause C."

The same text is found in the JLS3 beta, section 14.21.

It seems that in order for a catch block to be reachable, the try block must have at least one expression or throws statement. Thus the catch blocks in both of Joseph's examples is by definition unreachable, and the compiler is required report a compile-time exception here. Since it doesn't (in the second case, anyway) I would say that the compiler does in fact violate the spec here. Unless I've missed something somewhere of course...

This does not seem to be terribly significant for any practical application, since there's really no use that I can see for ever having an empty try block anyway. It probably would've been better if they'd just considered an empty try block (or finally block) to be a compile-time error. I suppose JLS3 is still in development; maybe one of us should report this earth-shattering news to them so they can fix it.

Ans: 3

Normally, the compiler guards against catch blocks that can never be entered. But there (apparently) comes a point where that's just not practical.

It's virtually impossible for the compiler to predict what type of code might throw any type of Exception (including RuntimeException). So basically, the compiler will "look the other way" and let a catch(Exception) block pass, even if the associated try block is empty.

On the other hand, your own class, MyException, is much more specific, so it's much more reasonable for the compiler to check for code that might throw an instance of MyException.

Ans: 4

It is figured out as a bug which will have its explanation in next release of Java Language Specification.

Example:

import java.io.IOException;

public class Test {

public static void main(String[] args) {

try{

System.out.println("Checked Exception: " );

}catch(IOException ex){

System.out.println("Exception Caught: " + ex);

}

}

}

Output: Compile time error.

Test.java:10: exception java.io.IOException is never thrown in body of corresponding try statement

}catch(IOException ex){

^

1 error


Difference between Process and a Thread


A Process is in essence, a program that is executing. Thus process-based multi-tasking is the feature that allows your computer to run 2 or more programs concurrently. For example process-based multitasking enables you to run the java compiler and a text editor concurrently.


In process-based multi-tasking, a program is the smallest unit of code that can be dispatched.

In Thread-based multi-tasking, a thread is the smallest unit of code that can be dispatchable code.

For instance, a text editor can format text at the same time that it is printing, as long as these actions are being performed by 2 different threads.

Multitasking threads require less overhead than multitasking processes. Processes are heavyweight tasks that require their own seperate address spaces. Interprocess communication is expensive and limited. Context switching from one process to another is also costly.


Threads on the other hand are lightweight. They share the same address space and cooperately share the same heavyweight process. Interthread communication is inexpensive and context switching from one thread to another is low cost.


A multithreaded program contains two (or) more parts that can run concurrently. Each part of the program is called thread, and Thread defines a seperate path of execution. Thus multithreading is a specialized part of multitasking.

Multithreading allows you to write very efficient programs that make maximum use of the CPU, because idle time can be kept minimum.

A Process has its own memory space, runtime environment and process ID.

A Thread run inside a Process and shares its resources with other threads.


Thursday, September 15, 2005

Compile Time Constants - II


Value of final variables are replaced at the time of compilation where they are used.

Only if the variable is a compile-time constant. Being final is necessary but not sufficient for a variable to be a constant. It must also be of primitive type or a String, and it must have an initializer which is a compile-time constant expression. If these conditions are not met, it's not a compile-time constant.


But Even though we can initialize final variable in the constructor.

You can set a final variable in a constructor, but this is not considered an initializer for the variable - so the final variable is not a compile-time constant.


So in this case they are maintained per Object and can be intitialized on the fly. So where these variables are managed in memory. In stack or heap?

Heap.


class FinalVariableTest {

FinalVariableTest() {

b = 5;

}

final int b;

int c = b;

public static void main(String[] args) {

FinalVariableTest ft = new FinalVariableTest();

System.out.println("Hello World!");

}

}

You can set a final variable in a constructor, but this is not considered an initializer for the variable - so the final variable is not a compile-time constant.

If u compile this example it will result is compiler error because even though u initialize the final instance variable b with a value in the constructor still it is not considered an compile time constant

Initialize b with a constant like

final byte b = 5;

and assign

char c = b;

and comment b = 5 in the constructor( because once a final variable is assigned with a value u cannot re-assign(or)modify it)

now u will not get any compile time error. This is because now u are assigning a compile time constant to char.

I have only one doubt. Whether compile time constants available inside a method is stored in a Heap (or) Stack.

void display() {

final int value = 5;

}

An instance final variable must be assigned with some value before the constructor completes. Which means it has to be assigned a value atleast in the constructor.

An instance static final variable must be assigned with some value in the static block and a "instance static final variable" cannot be assigned a value in the constructor which will result in a compile time error.

If final variable is a class variable ("b") then initializing it in the constructor will result in compile time error.

static final byte b;

Because (JLS)

A field can be declared final (§4.5.4). Both class and instance variables (static and non-static fields) may be declared final.

It is a compile-time error if a blank final (§4.5.4) class variable is not definitely assigned (§16.7) by a static initializer (§8.7) of the class in which it is declared.

A blank final instance variable must be definitely assigned (§16.8) at the end of every constructor (§8.8) of the class in which it is declared; otherwise a compile-time error occurs.


class NumConvTest {


final int j; // 1

// final static int j; // 2


// int h = j; // 3

int t = call();


static int call() {

System.out.println("instance method call");

return 5;

}

static {

j =200;

}

NumConvTest() {

j = 2;

System.out.println("1000");

}

public static void main(String[] args) {

NumConvTest nc = new NumConvTest();

int b1 = nc.j;

System.out.println(b1);

}

}

O/P

instance method call

1000

2


Consider this program. This code works fine and prints 2 even when u initialize the final variable inside the constructor which is not a compile time constant. Because by the time nc.j is assigned to b1 the constructor would have completed its execution. But consider uncommenting "3". You will get compiler error. This is because before any statement in the constructor gets executed the instance variables in the class will be initialized. Hence j is not initialized to 2. So when you try to assign a final variable which has not been initialized to a constant to another instance variable then compiler will complain about it.

For the same case if j isn't a final variable then even if you assign j to another instance variable then you will not end up in compile time error because default value of instance variable which is 0 will be asigned to the another instance variable.