Saturday, July 31, 2010
Threads - Thread Synchronization
* every instance of class Object and its subclass's has a lock
* primitive data type fields (Scalar fields) can only be locked via their enclosing class
* fields cannot be marked as synchronized however they can be declared volatile which orders the way they can be used or you can write synchronized accessor methods
* array objects can be synchronized BUT their elements cannot, nor can their elements be declared volatile
* Class instances are Objects and can be synchronized via static synchronized methods
Synchronized blocks
* allow you to execute synchronized code that locks an object without requiring you to invoke a synchronized method
synchronized( expr ) {
// 'expr' must evaluate to an Object
}
Synchronized methods
* declaring a method as synchronized ie synchronized void f() is equivalent to
void f() { synchronized(this) {
// body of method
}
}
* the synchronized keyword is NOT considered part of a method's signature. IT IS NOT AUTOMATICALLY INHERITED when subclasses override superclass methods
* methods in Interfaces CANNOT be declared synchronized
* constructors CANNOT be declared synchronized however they can contain synchronized blocks
* synchronized methods in subclasses use the same locks as their superclasses
* synchronization of an Inner Class is independent on it's outer class
* a non-static inner class method can lock it's containing class by using a synchronized block
synchronized(OuterClass.this) {
// body
}
Locking
* locking follows a built-in acquire-release protocol controlled by the synchronized keyword
* a lock is acquired on entry to a synchronized method or block and released on exit, even if the exit is the result of an exception
* you cannot forget to release a lock
* locks operate on a per thread basis, not on a per-invocation basis
* Java uses re-entrant locks ie a thread cannot lock on itself
class Reentrant {
public synchronized void a() {
b();
System.out.println("here I am, in a()");
}
public synchronized void b() {
System.out.println("here I am, in b()");
}
}
* in the above code, the synchronized method a(), when executed, obtains a lock on it's own object. It then calls synchronized method b() which also needs to acquire a lock on it's own object
* if Java did not allow a thread to reacquire it's own lock method b() would be unable to proceed until method a() completed and released the lock; and method a() would be unable to complete until method b() completed. Result: deadlock
* as Java does allow reentrant locks, the code compiles and runs without a problem
* the locking protocol is only followed for synchronized methods, it DOES NOT prevent unsynchronized methods from accessing the object
* once a thread releases a lock, another thread may acquire it BUT there is no guarantee as to WHICH thread will acquire the lock next
Class fields and methods
* locking an object does not automatically protect access to static fields
* protecting static fields requires a synchronized static block or method
* static synchronized statements obtain a lock on the Class vs an instance of the class
* a synchronized instance method can obtain a lock on the class
synchronized(ClassName.class) {
// body
}
* the static lock on a class is not related to any other class including it's superclasses
* a lock on a static method has no effect on any instances of that class (JPL pg 185)
* you cannot effectively protect static fields in a superclass by adding a new static synchronized method in a subclass; an explicit block synchronization is the preferred way
* nor should you use synchronized(getClass()); this locks the actual Class which might be different from the class in which the static fields are declared
* primitive data type fields (Scalar fields) can only be locked via their enclosing class
* fields cannot be marked as synchronized however they can be declared volatile which orders the way they can be used or you can write synchronized accessor methods
* array objects can be synchronized BUT their elements cannot, nor can their elements be declared volatile
* Class instances are Objects and can be synchronized via static synchronized methods
Synchronized blocks
* allow you to execute synchronized code that locks an object without requiring you to invoke a synchronized method
synchronized( expr ) {
// 'expr' must evaluate to an Object
}
Synchronized methods
* declaring a method as synchronized ie synchronized void f() is equivalent to
void f() { synchronized(this) {
// body of method
}
}
* the synchronized keyword is NOT considered part of a method's signature. IT IS NOT AUTOMATICALLY INHERITED when subclasses override superclass methods
* methods in Interfaces CANNOT be declared synchronized
* constructors CANNOT be declared synchronized however they can contain synchronized blocks
* synchronized methods in subclasses use the same locks as their superclasses
* synchronization of an Inner Class is independent on it's outer class
* a non-static inner class method can lock it's containing class by using a synchronized block
synchronized(OuterClass.this) {
// body
}
Locking
* locking follows a built-in acquire-release protocol controlled by the synchronized keyword
* a lock is acquired on entry to a synchronized method or block and released on exit, even if the exit is the result of an exception
* you cannot forget to release a lock
* locks operate on a per thread basis, not on a per-invocation basis
* Java uses re-entrant locks ie a thread cannot lock on itself
class Reentrant {
public synchronized void a() {
b();
System.out.println("here I am, in a()");
}
public synchronized void b() {
System.out.println("here I am, in b()");
}
}
* in the above code, the synchronized method a(), when executed, obtains a lock on it's own object. It then calls synchronized method b() which also needs to acquire a lock on it's own object
* if Java did not allow a thread to reacquire it's own lock method b() would be unable to proceed until method a() completed and released the lock; and method a() would be unable to complete until method b() completed. Result: deadlock
* as Java does allow reentrant locks, the code compiles and runs without a problem
* the locking protocol is only followed for synchronized methods, it DOES NOT prevent unsynchronized methods from accessing the object
* once a thread releases a lock, another thread may acquire it BUT there is no guarantee as to WHICH thread will acquire the lock next
Class fields and methods
* locking an object does not automatically protect access to static fields
* protecting static fields requires a synchronized static block or method
* static synchronized statements obtain a lock on the Class vs an instance of the class
* a synchronized instance method can obtain a lock on the class
synchronized(ClassName.class) {
// body
}
* the static lock on a class is not related to any other class including it's superclasses
* a lock on a static method has no effect on any instances of that class (JPL pg 185)
* you cannot effectively protect static fields in a superclass by adding a new static synchronized method in a subclass; an explicit block synchronization is the preferred way
* nor should you use synchronized(getClass()); this locks the actual Class which might be different from the class in which the static fields are declared
Thursday, July 29, 2010
Inner Classes in Java
As we all know what an inner class is so lets try to know few more rules about Inner Classes.
Inner classes cannot have static members. only static final variables.
Interfaces are never inner.
Static classes are not inner classes.
Inner classes may inherit static members that are not compile-time constants even though they may not declare them.
Nested classes that are not inner classes may declare static members freely, in accordance with the usual rules of the Java programming language. Member interfaces are always implicitly static so they are never considered to be inner classes.A statement or expression occurs in a static context if and only if the innermost method, constructor, instance initializer, static initializer, field initializer, or explicit constructor invocation statement enclosing the statement or expression is a static method, a static initializer, the variable initializer of a static variable, or an explicit constructor invocation statement.
A blank final field of a lexically enclosing class may not be assigned within an inner class.
For Example:
class HasStatic {
static int j = 100;
}
class Outer{
final int z=10;
class Inner extends HasStatic {
static final int x = 3;
static int y = 4;
}
static class Inner2 {
public static int size=130;
}
interface InnerInteface {
public static int size=100;
}
}
public class InnerClassDemo {
public static void main(String[] args) {
Outer outer=new Outer();
System.out.println(outer.new Inner().y);
System.out.println(outer.new Inner().x);
System.out.println(outer.new Inner().j);
System.out.println(Outer.Inner2.size);
System.out.println(Outer.InnerInteface.size);
}
}
Hence it gives compilation problems as y cannot be used in inner class "Inner".
Also note Method parameter names may not be redeclared as local variables of the method, or as exception parameters of catch clauses in a try statement of the method or constructor. However, a parameter of a method or constructor may be shadowed anywhere inside a class declaration nested within that method or constructor. Such a nested class declaration could declare either a local class or an anonymous class.
For Example:
public class MethodParameterExamples {
public String s="bt";
public void m1(String s) {
s=this.s;
s="uk";
//abstract
class InnerClass extends MethodParameterExamples {
String s="ros";
public void m1() {
System.out.println(super.s=this.s);
}
}
InnerClass innerClass=new InnerClass();
innerClass.s=s;
innerClass.m1();
}
public static void main(String[] args) {
MethodParameterExamples methodParameterExamples=new MethodParameterExamples();
methodParameterExamples.m1("vij");
System.out.println(methodParameterExamples.s);
}
}
Hence Prints the output:
uk
bt
Now coming to Section Nested Inner Classes:
Consider the below program.
class WithDeepNesting {
boolean toBe;
WithDeepNesting(boolean b) { toBe = b;}
class Nested {
boolean theQuestion;
class DeeplyNested {
DeeplyNested(){
theQuestion = toBe || !toBe;
}
}
}
public static void main(String[] args) {
WithDeepNesting withDeepNesting=new WithDeepNesting(true);
WithDeepNesting.Nested nested=withDeepNesting.new Nested();
nested.new DeeplyNested();
System.out.println(nested.theQuestion);
}
}
Please note that Inner classes whose declarations do not occur in a static context may freely refer to the instance variables of their enclosing class. An instance variable is always defined with respect to an instance. In the case of instance variables of an enclosing class, the instance variable must be defined with respect to an enclosing instance of that class. So, for example, the class Local above has an enclosing instance of class Outer. As a further example:
Here, every instance of WithDeepNesting.Nested.DeeplyNested has an enclosing instance of class WithDeepNesting.Nested (its immediately enclosing instance) and an enclosing instance of class WithDeepNesting (its 2nd lexically enclosing instance). Hence it prints: true.
Inner classes cannot have static members. only static final variables.
Interfaces are never inner.
Static classes are not inner classes.
Inner classes may inherit static members that are not compile-time constants even though they may not declare them.
Nested classes that are not inner classes may declare static members freely, in accordance with the usual rules of the Java programming language. Member interfaces are always implicitly static so they are never considered to be inner classes.A statement or expression occurs in a static context if and only if the innermost method, constructor, instance initializer, static initializer, field initializer, or explicit constructor invocation statement enclosing the statement or expression is a static method, a static initializer, the variable initializer of a static variable, or an explicit constructor invocation statement.
A blank final field of a lexically enclosing class may not be assigned within an inner class.
For Example:
class HasStatic {
static int j = 100;
}
class Outer{
final int z=10;
class Inner extends HasStatic {
static final int x = 3;
static int y = 4;
}
static class Inner2 {
public static int size=130;
}
interface InnerInteface {
public static int size=100;
}
}
public class InnerClassDemo {
public static void main(String[] args) {
Outer outer=new Outer();
System.out.println(outer.new Inner().y);
System.out.println(outer.new Inner().x);
System.out.println(outer.new Inner().j);
System.out.println(Outer.Inner2.size);
System.out.println(Outer.InnerInteface.size);
}
}
Hence it gives compilation problems as y cannot be used in inner class "Inner".
Also note Method parameter names may not be redeclared as local variables of the method, or as exception parameters of catch clauses in a try statement of the method or constructor. However, a parameter of a method or constructor may be shadowed anywhere inside a class declaration nested within that method or constructor. Such a nested class declaration could declare either a local class or an anonymous class.
For Example:
public class MethodParameterExamples {
public String s="bt";
public void m1(String s) {
s=this.s;
s="uk";
//abstract
class InnerClass extends MethodParameterExamples {
String s="ros";
public void m1() {
System.out.println(super.s=this.s);
}
}
InnerClass innerClass=new InnerClass();
innerClass.s=s;
innerClass.m1();
}
public static void main(String[] args) {
MethodParameterExamples methodParameterExamples=new MethodParameterExamples();
methodParameterExamples.m1("vij");
System.out.println(methodParameterExamples.s);
}
}
Hence Prints the output:
uk
bt
Now coming to Section Nested Inner Classes:
Consider the below program.
class WithDeepNesting {
boolean toBe;
WithDeepNesting(boolean b) { toBe = b;}
class Nested {
boolean theQuestion;
class DeeplyNested {
DeeplyNested(){
theQuestion = toBe || !toBe;
}
}
}
public static void main(String[] args) {
WithDeepNesting withDeepNesting=new WithDeepNesting(true);
WithDeepNesting.Nested nested=withDeepNesting.new Nested();
nested.new DeeplyNested();
System.out.println(nested.theQuestion);
}
}
Please note that Inner classes whose declarations do not occur in a static context may freely refer to the instance variables of their enclosing class. An instance variable is always defined with respect to an instance. In the case of instance variables of an enclosing class, the instance variable must be defined with respect to an enclosing instance of that class. So, for example, the class Local above has an enclosing instance of class Outer. As a further example:
Here, every instance of WithDeepNesting.Nested.DeeplyNested has an enclosing instance of class WithDeepNesting.Nested (its immediately enclosing instance) and an enclosing instance of class WithDeepNesting (its 2nd lexically enclosing instance). Hence it prints: true.
Serialization Interview Questions
Q1) What is Serialization?
Ans) Serializable is a marker interface. When an object has to be transferred over a network ( typically through rmi or EJB) or persist the state of an object to a file, the object Class needs to implement Serializable interface. Implementing this interface will allow the object converted into bytestream and transfer over a network.
Q2) What is use of serialVersionUID?
Ans) During object serialization, the default Java serialization mechanism writes the metadata about the object, which includes the class name, field names and types, and superclass. This class definition is stored as a part of the serialized object. This stored metadata enables the deserialization process to reconstitute the objects and map the stream data into the class attributes with the appropriate type
Everytime an object is serialized the java serialization mechanism automatically computes a hash value. ObjectStreamClass's computeSerialVersionUID() method passes the class name, sorted member names, modifiers, and interfaces to the secure hash algorithm (SHA), which returns a hash value.The serialVersionUID is also called suid.
So when the serilaize object is retrieved , the JVM first evaluates the suid of the serialized class and compares the suid value with the one of the object. If the suid values match then the object is said to be compatible with the class and hence it is de-serialized. If not InvalidClassException exception is thrown.
Changes to a serializable class can be compatible or incompatible. Following is the list of changes which are compatible:
* Add fields
* Change a field from static to non-static
* Change a field from transient to non-transient
* Add classes to the object tree
List of incompatible changes:
* Delete fields
* Change class hierarchy
* Change non-static to static
* Change non-transient to transient
* Change type of a primitive field
So, if no suid is present , inspite of making compatible changes, jvm generates new suid thus resulting in an exception if prior release version object is used .
The only way to get rid of the exception is to recompile and deploy the application again.
If we explicitly metion the suid using the statement:
private final static long serialVersionUID =
then if any of the metioned compatible changes are made the class need not to be recompiled. But for incompatible changes there is no other way than to compile again.
Q3) What is the need of Serialization?
Ans) The serialization is used :-
* To send state of one or more object’s state over the network through a socket.
* To save the state of an object in a file.
* An object’s state needs to be manipulated as a stream of bytes.
Q4) Other than Serialization what are the different approach to make object Serializable?
Ans) Besides the Serializable interface, at least three alternate approaches can serialize Java objects:
1)For object serialization, instead of implementing the Serializable interface, a developer can implement the Externalizable interface, which extends Serializable. By implementing Externalizable, a developer is responsible for implementing the writeExternal() and readExternal() methods. As a result, a developer has sole control over reading and writing the serialized objects.
2)XML serialization is an often-used approach for data interchange. This approach lags runtime performance when compared with Java serialization, both in terms of the size of the object and the processing time. With a speedier XML parser, the performance gap with respect to the processing time narrows. Nonetheless, XML serialization provides a more malleable solution when faced with changes in the serializable object.
3)Finally, consider a "roll-your-own" serialization approach. You can write an object's content directly via either the ObjectOutputStream or the DataOutputStream. While this approach is more involved in its initial implementation, it offers the greatest flexibility and extensibility. In addition, this approach provides a performance advantage over Java serialization.
Q5) Do we need to implement any method of Serializable interface to make an object serializable?
Ans) No. Serializable is a Marker Interface. It does not have any methods.
Q6) What happens if the object to be serialized includes the references to other serializable objects?
Ans) If the object to be serialized includes the references to other objects whose class implements serializable then all those object’s state also will be saved as the part of the serialized state of the object in question. The whole object graph of the object to be serialized will be saved during serialization automatically provided all the objects included in the object’s graph are serializable.
Q7) What happens if an object is serializable but it includes a reference to a non-serializable object?
Ans- If you try to serialize an object of a class which implements serializable, but the object includes a reference to an non-serializable class then a ‘NotSerializableException’ will be thrown at runtime.
e.g.
public class NonSerial {
//This is a non-serializable class
}
public class MyClass implements Serializable{
private static final long serialVersionUID = 1L;
private NonSerial nonSerial;
MyClass(NonSerial nonSerial){
this.nonSerial = nonSerial;
}
public static void main(String [] args) {
NonSerial nonSer = new NonSerial();
MyClass c = new MyClass(nonSer);
try {
FileOutputStream fs = new FileOutputStream("test1.ser");
ObjectOutputStream os = new ObjectOutputStream(fs);
os.writeObject(c);
os.close();
} catch (Exception e) { e.printStackTrace(); }
try {
FileInputStream fis = new FileInputStream("test1.ser");
ObjectInputStream ois = new ObjectInputStream(fis);
c = (MyClass) ois.readObject();
ois.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
On execution of above code following exception will be thrown –
java.io.NotSerializableException: NonSerial
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java)
Q8) Are the static variables saved as the part of serialization?
Ans) No. The static variables belong to the class and not to an object they are not the part of the state of the object so they are not saved as the part of serialized object.
Q9) What is a transient variable?
Ans) These variables are not included in the process of serialization and are not the part of the object’s serialized state.
Q10) What will be the value of transient variable after de-serialization?
Ans) It’s default value.
e.g. if the transient variable in question is an int, it’s value after deserialization will be zero.
public class TestTransientVal implements Serializable{
private static final long serialVersionUID = -22L;
private String name;
transient private int age;
TestTransientVal(int age, String name) {
this.age = age;
this.name = name;
}
public static void main(String [] args) {
TestTransientVal c = new TestTransientVal(1,"ONE");
System.out.println("Before serialization: - " + c.name + " "+ c.age);
try {
FileOutputStream fs = new FileOutputStream("testTransients.ser");
ObjectOutputStream os = new ObjectOutputStream(fs);
os.writeObject(c);
os.close();
} catch (Exception e) { e.printStackTrace(); }
try {
FileInputStream fis = new FileInputStream("testTransients.ser");
ObjectInputStream ois = new ObjectInputStream(fis);
c = (TestTransientVal) ois.readObject();
ois.close();
} catch (Exception e) { e.printStackTrace(); }
System.out.println("After de-serialization:- " + c.name + " "+ c.age);
}
}
Result of executing above piece of code –
Before serialization: - Value of non-transient variable ONE Value of transient variable 1
After de-serialization:- Value of non-transient variable ONE Value of transient variable 0
Explanation –
The transient variable is not saved as the part of the state of the serailized variable, it’s value after de-serialization is it’s default value.
Q11) Does the order in which the value of the transient variables and the state of the object using the defaultWriteObject() method are saved during serialization matter?
Ans) Yes. As while restoring the object’s state the transient variables and the serializable variables that are stored must be restored in the same order in which they were saved.
Q12) How can one customize the Serialization process? or What is the purpose of implementing the writeObject() and readObject() method?
Ans) When you want to store the transient variables state as a part of the serialized object at the time of serialization the class must implement the following methods –
private void wrtiteObject(ObjectOutputStream outStream)
{
//code to save the transient variables state as a part of serialized object
}
private void readObject(ObjectInputStream inStream)
{
//code to read the transient variables state and assign it to the de-serialized object
}
e.g.
public class TestCustomizedSerialization implements Serializable{
private static final long serialVersionUID =-22L;
private String noOfSerVar;
transient private int noOfTranVar;
TestCustomizedSerialization(int noOfTranVar, String noOfSerVar) {
this.noOfTranVar = noOfTranVar;
this.noOfSerVar = noOfSerVar;
}
private void writeObject(ObjectOutputStream os) {
try {
os.defaultWriteObject();
os.writeInt(noOfTranVar);
} catch (Exception e) { e.printStackTrace(); }
}
private void readObject(ObjectInputStream is) {
try {
is.defaultReadObject();
int noOfTransients = (is.readInt());
} catch (Exception e) {
e.printStackTrace(); }
}
public int getNoOfTranVar() {
return noOfTranVar;
}
}
The value of transient variable ‘noOfTranVar’ is saved as part of the serialized object manually by implementing writeObject() and restored by implementing readObject().
The normal serializable variables are saved and restored by calling defaultWriteObject() and defaultReadObject()respectively. These methods perform the normal serialization and de-sirialization process for the object to be saved or restored respectively.
Q13) If a class is serializable but its superclass in not , what will be the state of the instance variables inherited from super class after deserialization?
Ans) The values of the instance variables inherited from superclass will be reset to the values they were given during the original construction of the object as the non-serializable super-class constructor will run.
E.g.
public class ParentNonSerializable {
int noOfWheels;
ParentNonSerializable(){
this.noOfWheels = 4;
}
}
public class ChildSerializable extends ParentNonSerializable implements Serializable {
private static final long serialVersionUID = 1L;
String color;
ChildSerializable() {
this.noOfWheels = 8;
this.color = "blue";
}
}
public class SubSerialSuperNotSerial {
public static void main(String [] args) {
ChildSerializable c = new ChildSerializable();
System.out.println("Before : - " + c.noOfWheels + " "+ c.color);
try {
FileOutputStream fs = new FileOutputStream("superNotSerail.ser");
ObjectOutputStream os = new ObjectOutputStream(fs);
os.writeObject(c);
os.close();
} catch (Exception e) { e.printStackTrace(); }
try {
FileInputStream fis = new FileInputStream("superNotSerail.ser");
ObjectInputStream ois = new ObjectInputStream(fis);
c = (ChildSerializable) ois.readObject();
ois.close();
} catch (Exception e) { e.printStackTrace(); }
System.out.println("After :- " + c.noOfWheels + " "+ c.color);
}
}
Result on executing above code –
Before : - 8 blue
After :- 4 blue
The instance variable ‘noOfWheels’ is inherited from superclass which is not serializable. Therefore while restoring it the non-serializable superclass constructor runs and its value is set to 8 and is not same as the value saved during serialization which is 4.
Q14) To serialize an array or a collection all the members of it must be serializable. True /False?
Ans) true.
-------------------------------------------------------
How many methods in the Serializable interface? Which methods of Serializable interface should I implement?
There is no method in the Serializable interface. It’s an empty interface which does not contain any methods. The Serializable interface acts as a marker, telling the object serialization tools that the class is serializable. So we do not implement any methods.
What is the difference between Serializalble and Externalizable interface? How can you control over the serialization process i.e. how can you customize the seralization process?
When you use Serializable interface, your class is serialized automatically by default. But you can override writeObject() and readObject() two methods to control more complex object serailization process. When you use Externalizable interface, you have a complete control over your class's serialization process. This interface contains two methods namely readExternal and writeExternal. You should implement these methods and write the logic for customizing the serialization process.
How to make a class or a bean serializable? How do I serialize an object to a file?
Or
What interface must an object implement before it can be written to a stream as an object?
An object must implement the Serializable or Externalizable interface before it can be written to a stream as an object. The class whose instances are to be serialized should implement an interface Serializable. Then you pass the instance to the ObjectOutputStream which is connected to a fileoutputstream. This will save the object to a file.
What happens to the object references included in the object?
The serialization mechanism generates an object graph for serialization. Thus it determines whether the included object references are serializable or not. This is a recursive process. Thus when an object is serialized, all the included objects are also serialized alongwith the original object.
What is serialization?
The serialization is a kind of mechanism that makes a class or a bean persistent by having its properties or fields and state information saved and restored to and from storage. That is, it is a mechanism with which you can save the state of an object by converting it to a byte stream.
Common Usage of serialization.
Whenever an object is to be sent over the network or saved in a file, objects are serialized.
What happens to the static fields of a class during serialization?
There are three exceptions in which serialization doesn’t necessarily read and write to the stream. These are
1. Serialization ignores static fields, because they are not part of any particular state.
2. Base class fields are only handled if the base class itself is serializable.
3. Transient fields.
What one should take care of while serializing the object?
One should make sure that all the included objects are also serializable. If any of the objects is not serializable then it throws a NotSerializableException.
What is a transient variable?
Or
Explain the usage of the keyword transient?
Or
What are Transient and Volatile Modifiers
A transient variable is a variable that may not be serialized i.e. the value of the variable can’t be written to the stream in a Serializable class. If you don't want some field to be serialized, you can mark that field transient or static. In such a case when the class is retrieved from the ObjectStream the value of the variable is null.
Volatile modifier applies to variables only and it tells the compiler that the variable modified by volatile can be changed unexpectedly by other parts of the program.
What is Serialization and deserialization?
Serialization is the process of writing the state of an object to a byte stream. Deserialization is the process of restoring these objects.
What is Externalizable?
Externalizable is an interface which contains two methods readExternal and writeExternal. These methods give you a control over the serialization mechanism. Thus if your class implements this interface, you can customize the serialization process by implementing these methods.
If you think that an important java interview question is missing or some answers are wrong in the site please contribute it to sriniappl@gmail.com
Ans) Serializable is a marker interface. When an object has to be transferred over a network ( typically through rmi or EJB) or persist the state of an object to a file, the object Class needs to implement Serializable interface. Implementing this interface will allow the object converted into bytestream and transfer over a network.
Q2) What is use of serialVersionUID?
Ans) During object serialization, the default Java serialization mechanism writes the metadata about the object, which includes the class name, field names and types, and superclass. This class definition is stored as a part of the serialized object. This stored metadata enables the deserialization process to reconstitute the objects and map the stream data into the class attributes with the appropriate type
Everytime an object is serialized the java serialization mechanism automatically computes a hash value. ObjectStreamClass's computeSerialVersionUID() method passes the class name, sorted member names, modifiers, and interfaces to the secure hash algorithm (SHA), which returns a hash value.The serialVersionUID is also called suid.
So when the serilaize object is retrieved , the JVM first evaluates the suid of the serialized class and compares the suid value with the one of the object. If the suid values match then the object is said to be compatible with the class and hence it is de-serialized. If not InvalidClassException exception is thrown.
Changes to a serializable class can be compatible or incompatible. Following is the list of changes which are compatible:
* Add fields
* Change a field from static to non-static
* Change a field from transient to non-transient
* Add classes to the object tree
List of incompatible changes:
* Delete fields
* Change class hierarchy
* Change non-static to static
* Change non-transient to transient
* Change type of a primitive field
So, if no suid is present , inspite of making compatible changes, jvm generates new suid thus resulting in an exception if prior release version object is used .
The only way to get rid of the exception is to recompile and deploy the application again.
If we explicitly metion the suid using the statement:
private final static long serialVersionUID =
then if any of the metioned compatible changes are made the class need not to be recompiled. But for incompatible changes there is no other way than to compile again.
Q3) What is the need of Serialization?
Ans) The serialization is used :-
* To send state of one or more object’s state over the network through a socket.
* To save the state of an object in a file.
* An object’s state needs to be manipulated as a stream of bytes.
Q4) Other than Serialization what are the different approach to make object Serializable?
Ans) Besides the Serializable interface, at least three alternate approaches can serialize Java objects:
1)For object serialization, instead of implementing the Serializable interface, a developer can implement the Externalizable interface, which extends Serializable. By implementing Externalizable, a developer is responsible for implementing the writeExternal() and readExternal() methods. As a result, a developer has sole control over reading and writing the serialized objects.
2)XML serialization is an often-used approach for data interchange. This approach lags runtime performance when compared with Java serialization, both in terms of the size of the object and the processing time. With a speedier XML parser, the performance gap with respect to the processing time narrows. Nonetheless, XML serialization provides a more malleable solution when faced with changes in the serializable object.
3)Finally, consider a "roll-your-own" serialization approach. You can write an object's content directly via either the ObjectOutputStream or the DataOutputStream. While this approach is more involved in its initial implementation, it offers the greatest flexibility and extensibility. In addition, this approach provides a performance advantage over Java serialization.
Q5) Do we need to implement any method of Serializable interface to make an object serializable?
Ans) No. Serializable is a Marker Interface. It does not have any methods.
Q6) What happens if the object to be serialized includes the references to other serializable objects?
Ans) If the object to be serialized includes the references to other objects whose class implements serializable then all those object’s state also will be saved as the part of the serialized state of the object in question. The whole object graph of the object to be serialized will be saved during serialization automatically provided all the objects included in the object’s graph are serializable.
Q7) What happens if an object is serializable but it includes a reference to a non-serializable object?
Ans- If you try to serialize an object of a class which implements serializable, but the object includes a reference to an non-serializable class then a ‘NotSerializableException’ will be thrown at runtime.
e.g.
public class NonSerial {
//This is a non-serializable class
}
public class MyClass implements Serializable{
private static final long serialVersionUID = 1L;
private NonSerial nonSerial;
MyClass(NonSerial nonSerial){
this.nonSerial = nonSerial;
}
public static void main(String [] args) {
NonSerial nonSer = new NonSerial();
MyClass c = new MyClass(nonSer);
try {
FileOutputStream fs = new FileOutputStream("test1.ser");
ObjectOutputStream os = new ObjectOutputStream(fs);
os.writeObject(c);
os.close();
} catch (Exception e) { e.printStackTrace(); }
try {
FileInputStream fis = new FileInputStream("test1.ser");
ObjectInputStream ois = new ObjectInputStream(fis);
c = (MyClass) ois.readObject();
ois.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
On execution of above code following exception will be thrown –
java.io.NotSerializableException: NonSerial
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java)
Q8) Are the static variables saved as the part of serialization?
Ans) No. The static variables belong to the class and not to an object they are not the part of the state of the object so they are not saved as the part of serialized object.
Q9) What is a transient variable?
Ans) These variables are not included in the process of serialization and are not the part of the object’s serialized state.
Q10) What will be the value of transient variable after de-serialization?
Ans) It’s default value.
e.g. if the transient variable in question is an int, it’s value after deserialization will be zero.
public class TestTransientVal implements Serializable{
private static final long serialVersionUID = -22L;
private String name;
transient private int age;
TestTransientVal(int age, String name) {
this.age = age;
this.name = name;
}
public static void main(String [] args) {
TestTransientVal c = new TestTransientVal(1,"ONE");
System.out.println("Before serialization: - " + c.name + " "+ c.age);
try {
FileOutputStream fs = new FileOutputStream("testTransients.ser");
ObjectOutputStream os = new ObjectOutputStream(fs);
os.writeObject(c);
os.close();
} catch (Exception e) { e.printStackTrace(); }
try {
FileInputStream fis = new FileInputStream("testTransients.ser");
ObjectInputStream ois = new ObjectInputStream(fis);
c = (TestTransientVal) ois.readObject();
ois.close();
} catch (Exception e) { e.printStackTrace(); }
System.out.println("After de-serialization:- " + c.name + " "+ c.age);
}
}
Result of executing above piece of code –
Before serialization: - Value of non-transient variable ONE Value of transient variable 1
After de-serialization:- Value of non-transient variable ONE Value of transient variable 0
Explanation –
The transient variable is not saved as the part of the state of the serailized variable, it’s value after de-serialization is it’s default value.
Q11) Does the order in which the value of the transient variables and the state of the object using the defaultWriteObject() method are saved during serialization matter?
Ans) Yes. As while restoring the object’s state the transient variables and the serializable variables that are stored must be restored in the same order in which they were saved.
Q12) How can one customize the Serialization process? or What is the purpose of implementing the writeObject() and readObject() method?
Ans) When you want to store the transient variables state as a part of the serialized object at the time of serialization the class must implement the following methods –
private void wrtiteObject(ObjectOutputStream outStream)
{
//code to save the transient variables state as a part of serialized object
}
private void readObject(ObjectInputStream inStream)
{
//code to read the transient variables state and assign it to the de-serialized object
}
e.g.
public class TestCustomizedSerialization implements Serializable{
private static final long serialVersionUID =-22L;
private String noOfSerVar;
transient private int noOfTranVar;
TestCustomizedSerialization(int noOfTranVar, String noOfSerVar) {
this.noOfTranVar = noOfTranVar;
this.noOfSerVar = noOfSerVar;
}
private void writeObject(ObjectOutputStream os) {
try {
os.defaultWriteObject();
os.writeInt(noOfTranVar);
} catch (Exception e) { e.printStackTrace(); }
}
private void readObject(ObjectInputStream is) {
try {
is.defaultReadObject();
int noOfTransients = (is.readInt());
} catch (Exception e) {
e.printStackTrace(); }
}
public int getNoOfTranVar() {
return noOfTranVar;
}
}
The value of transient variable ‘noOfTranVar’ is saved as part of the serialized object manually by implementing writeObject() and restored by implementing readObject().
The normal serializable variables are saved and restored by calling defaultWriteObject() and defaultReadObject()respectively. These methods perform the normal serialization and de-sirialization process for the object to be saved or restored respectively.
Q13) If a class is serializable but its superclass in not , what will be the state of the instance variables inherited from super class after deserialization?
Ans) The values of the instance variables inherited from superclass will be reset to the values they were given during the original construction of the object as the non-serializable super-class constructor will run.
E.g.
public class ParentNonSerializable {
int noOfWheels;
ParentNonSerializable(){
this.noOfWheels = 4;
}
}
public class ChildSerializable extends ParentNonSerializable implements Serializable {
private static final long serialVersionUID = 1L;
String color;
ChildSerializable() {
this.noOfWheels = 8;
this.color = "blue";
}
}
public class SubSerialSuperNotSerial {
public static void main(String [] args) {
ChildSerializable c = new ChildSerializable();
System.out.println("Before : - " + c.noOfWheels + " "+ c.color);
try {
FileOutputStream fs = new FileOutputStream("superNotSerail.ser");
ObjectOutputStream os = new ObjectOutputStream(fs);
os.writeObject(c);
os.close();
} catch (Exception e) { e.printStackTrace(); }
try {
FileInputStream fis = new FileInputStream("superNotSerail.ser");
ObjectInputStream ois = new ObjectInputStream(fis);
c = (ChildSerializable) ois.readObject();
ois.close();
} catch (Exception e) { e.printStackTrace(); }
System.out.println("After :- " + c.noOfWheels + " "+ c.color);
}
}
Result on executing above code –
Before : - 8 blue
After :- 4 blue
The instance variable ‘noOfWheels’ is inherited from superclass which is not serializable. Therefore while restoring it the non-serializable superclass constructor runs and its value is set to 8 and is not same as the value saved during serialization which is 4.
Q14) To serialize an array or a collection all the members of it must be serializable. True /False?
Ans) true.
-------------------------------------------------------
How many methods in the Serializable interface? Which methods of Serializable interface should I implement?
There is no method in the Serializable interface. It’s an empty interface which does not contain any methods. The Serializable interface acts as a marker, telling the object serialization tools that the class is serializable. So we do not implement any methods.
What is the difference between Serializalble and Externalizable interface? How can you control over the serialization process i.e. how can you customize the seralization process?
When you use Serializable interface, your class is serialized automatically by default. But you can override writeObject() and readObject() two methods to control more complex object serailization process. When you use Externalizable interface, you have a complete control over your class's serialization process. This interface contains two methods namely readExternal and writeExternal. You should implement these methods and write the logic for customizing the serialization process.
How to make a class or a bean serializable? How do I serialize an object to a file?
Or
What interface must an object implement before it can be written to a stream as an object?
An object must implement the Serializable or Externalizable interface before it can be written to a stream as an object. The class whose instances are to be serialized should implement an interface Serializable. Then you pass the instance to the ObjectOutputStream which is connected to a fileoutputstream. This will save the object to a file.
What happens to the object references included in the object?
The serialization mechanism generates an object graph for serialization. Thus it determines whether the included object references are serializable or not. This is a recursive process. Thus when an object is serialized, all the included objects are also serialized alongwith the original object.
What is serialization?
The serialization is a kind of mechanism that makes a class or a bean persistent by having its properties or fields and state information saved and restored to and from storage. That is, it is a mechanism with which you can save the state of an object by converting it to a byte stream.
Common Usage of serialization.
Whenever an object is to be sent over the network or saved in a file, objects are serialized.
What happens to the static fields of a class during serialization?
There are three exceptions in which serialization doesn’t necessarily read and write to the stream. These are
1. Serialization ignores static fields, because they are not part of any particular state.
2. Base class fields are only handled if the base class itself is serializable.
3. Transient fields.
What one should take care of while serializing the object?
One should make sure that all the included objects are also serializable. If any of the objects is not serializable then it throws a NotSerializableException.
What is a transient variable?
Or
Explain the usage of the keyword transient?
Or
What are Transient and Volatile Modifiers
A transient variable is a variable that may not be serialized i.e. the value of the variable can’t be written to the stream in a Serializable class. If you don't want some field to be serialized, you can mark that field transient or static. In such a case when the class is retrieved from the ObjectStream the value of the variable is null.
Volatile modifier applies to variables only and it tells the compiler that the variable modified by volatile can be changed unexpectedly by other parts of the program.
What is Serialization and deserialization?
Serialization is the process of writing the state of an object to a byte stream. Deserialization is the process of restoring these objects.
What is Externalizable?
Externalizable is an interface which contains two methods readExternal and writeExternal. These methods give you a control over the serialization mechanism. Thus if your class implements this interface, you can customize the serialization process by implementing these methods.
If you think that an important java interview question is missing or some answers are wrong in the site please contribute it to sriniappl@gmail.com
Wednesday, July 21, 2010
The basics: override hashCode() and equals()
If you want to override equals method in your class, you should also override hashCode method as well. There are a lot of ways the two methods can be implemented incorrectly.
I found the easiest way is to use the wizard in Eclipse, just running Source | Generate hashCode() and equals()... either from menu or context menu. For example, this is what Eclipse generated for a simple class Scrap with a instance variable number:
Correct Implementation Example
The following code exemplifies how all the requirements of equals and hashCode methods should be fulfilled so that the class behaves correctly and consistently with other Java classes. This class implements the equals method in such a way that it only provides equality comparison for the objects of the same class, similar to built-in Java classes like String and other wrapper classes.
package com;
class Test {
private int x;
private String y;
public Test(int x, String y) {
this.x = x;
this.y = y;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + x;
result = prime * result + ((y == null) ? 0 : y.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof Test)) {
return false;
}
Test other = (Test) obj;
if (x != other.x) {
return false;
}
if (y == null) {
if (other.y != null) {
return false;
}
} else if (!y.equals(other.y)) {
return false;
}
return true;
}
}
public class HashCodeAndEquals {
/**
* @param args
*/
public static void main(String[] args) {
Test t = new Test(10,"rama");
Test t1 = new Test(10,"rama");
System.out.println(t==t1);
System.out.println(t.hashCode()==t1.hashCode());
System.out.println(t.equals(t1));
}
}
-------------------------------------------------------------
The theory (for the language lawyers and the mathematically inclined):
equals() (javadoc) must define an equality relation (it must be reflexive, symmetric, and transitive). In addition, it must be consistent (if the objects are not modified, then it must keep returning the same value). Furthermore, o.equals(null) must always return false.
hashCode() (javadoc) must also be consistent (if the object is not modified in terms of equals(), it must keep returning the same value).
The relation between the two methods is:
Whenever a.equals(b), then a.hashCode() must be same as b.hashCode().
In practice:
If you override one, then you should override the other.
Use the same set of fields that you use to compute equals() to compute hashCode().
Use the excellent helper classes EqualsBuilder and HashCodeBuilder from the Apache Commons Lang library. An example:
public class Person {
private String name;
private int age;
// ...
public int hashCode() {
return new HashCodeBuilder(17, 31). // two randomly chosen prime numbers
// if deriving: appendSuper(super.hashCode()).
append(name).
append(age).
toHashCode();
}
public boolean equals(Object obj) {
if (obj == null)
return false;
if (obj == this)
return true;
if (obj.getClass() != getClass())
return false;
Person rhs = (Person) obj;
return new EqualsBuilder().
// if deriving: appendSuper(super.equals(obj)).
append(name, rhs.name).
append(age, rhs.age).
isEquals();
}
}
Also remember:
When using a hash-based Collection or Map such as HashSet, LinkedHashSet, HashMap, Hashtable, or WeakHashMap, make sure that the hashCode() of the key objects that you put into the collection never changes while the object is in the collection. The bulletproof way to ensure this is to make your keys immutable, which has also other benefits
I found the easiest way is to use the wizard in Eclipse, just running Source | Generate hashCode() and equals()... either from menu or context menu. For example, this is what Eclipse generated for a simple class Scrap with a instance variable number:
Correct Implementation Example
The following code exemplifies how all the requirements of equals and hashCode methods should be fulfilled so that the class behaves correctly and consistently with other Java classes. This class implements the equals method in such a way that it only provides equality comparison for the objects of the same class, similar to built-in Java classes like String and other wrapper classes.
package com;
class Test {
private int x;
private String y;
public Test(int x, String y) {
this.x = x;
this.y = y;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + x;
result = prime * result + ((y == null) ? 0 : y.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof Test)) {
return false;
}
Test other = (Test) obj;
if (x != other.x) {
return false;
}
if (y == null) {
if (other.y != null) {
return false;
}
} else if (!y.equals(other.y)) {
return false;
}
return true;
}
}
public class HashCodeAndEquals {
/**
* @param args
*/
public static void main(String[] args) {
Test t = new Test(10,"rama");
Test t1 = new Test(10,"rama");
System.out.println(t==t1);
System.out.println(t.hashCode()==t1.hashCode());
System.out.println(t.equals(t1));
}
}
-------------------------------------------------------------
The theory (for the language lawyers and the mathematically inclined):
equals() (javadoc) must define an equality relation (it must be reflexive, symmetric, and transitive). In addition, it must be consistent (if the objects are not modified, then it must keep returning the same value). Furthermore, o.equals(null) must always return false.
hashCode() (javadoc) must also be consistent (if the object is not modified in terms of equals(), it must keep returning the same value).
The relation between the two methods is:
Whenever a.equals(b), then a.hashCode() must be same as b.hashCode().
In practice:
If you override one, then you should override the other.
Use the same set of fields that you use to compute equals() to compute hashCode().
Use the excellent helper classes EqualsBuilder and HashCodeBuilder from the Apache Commons Lang library. An example:
public class Person {
private String name;
private int age;
// ...
public int hashCode() {
return new HashCodeBuilder(17, 31). // two randomly chosen prime numbers
// if deriving: appendSuper(super.hashCode()).
append(name).
append(age).
toHashCode();
}
public boolean equals(Object obj) {
if (obj == null)
return false;
if (obj == this)
return true;
if (obj.getClass() != getClass())
return false;
Person rhs = (Person) obj;
return new EqualsBuilder().
// if deriving: appendSuper(super.equals(obj)).
append(name, rhs.name).
append(age, rhs.age).
isEquals();
}
}
Also remember:
When using a hash-based Collection or Map such as HashSet, LinkedHashSet, HashMap, Hashtable, or WeakHashMap, make sure that the hashCode() of the key objects that you put into the collection never changes while the object is in the collection. The bulletproof way to ensure this is to make your keys immutable, which has also other benefits
Tuesday, July 20, 2010
Struts Spring Plugin
* Overview
* Features
* What's New
o Discontinued - April 12, 2004
o 0.1 - October 17, 2003
* Requirements
* Usage
* Contact
Overview
This project was originally created to integrate the Spring Framework's Inversion of Control (IoC) into Struts 1.1+. As of Spring's 1.0.1 release, the ContextLoaderPlugin was added to Spring that has this same functionality. Therefore, this project's plugin is no longer recommended for use. We continue to maintain this site for documentation and an example app.
The integration uses Spring to create and populate Struts actions, using IoC to resolve dependencies. It does NOT use a custom request processor and therefore can be more easily used with existing web applications and/or other Struts extensions.
To demonstrate the project, we modified the struts-example webapp that is distributed with Struts 1.1 to use Spring to resolve all UserDatabase dependencies automatically. Comments and suggestions are appreciated.
Features
* Intuitive Inversion of Control (IoC)
* Requires little or no direct references to Spring in the Struts webapp
* Can be used with other Struts extensions that use a custom RequestProcessor
* Can create new Actions for every request (aleviating need for thread-safe Actions)
* Includes modified Struts example
What's New
Discontinued - April 12, 2004
* This plugin is now part of Spring (as of 1.0.1). You can read more about Spring's Struts support on Matt Raible's Spring Live blog.
0.1 - October 17, 2003
* Initial release
Requirements
This plugin requires Struts 1.1 or greater.
Usage
To use the Struts Spring plugin, add the ContextLoaderPlugIn to your Struts config file (usually struts-config.xml):
The "contextConfigLocation" property is the location of the Spring beans configuration file.
For each action that uses Spring, you need to define the action mapping to use org.springframework.web.struts.DelegatingActionProxy and declare a matching (action "path" == bean "name") Spring bean for the actual Struts action. This is an example of an action that requires an instance of UserDatabase:
The corresponding Spring bean configuration:
For more information on the Spring configuration file format, see the Spring beans DTD.
The Struts action org.apache.struts.webapp.example.LogonAction will automatically receive a reference to UserDatabase without any work on its part or references to Spring by adding a standard JavaBean setter:
private UserDatabase database = null;
public void setUserDatabase(UserDatabase database) {
this.database = database;
}
* Features
* What's New
o Discontinued - April 12, 2004
o 0.1 - October 17, 2003
* Requirements
* Usage
* Contact
Overview
This project was originally created to integrate the Spring Framework's Inversion of Control (IoC) into Struts 1.1+. As of Spring's 1.0.1 release, the ContextLoaderPlugin was added to Spring that has this same functionality. Therefore, this project's plugin is no longer recommended for use. We continue to maintain this site for documentation and an example app.
The integration uses Spring to create and populate Struts actions, using IoC to resolve dependencies. It does NOT use a custom request processor and therefore can be more easily used with existing web applications and/or other Struts extensions.
To demonstrate the project, we modified the struts-example webapp that is distributed with Struts 1.1 to use Spring to resolve all UserDatabase dependencies automatically. Comments and suggestions are appreciated.
Features
* Intuitive Inversion of Control (IoC)
* Requires little or no direct references to Spring in the Struts webapp
* Can be used with other Struts extensions that use a custom RequestProcessor
* Can create new Actions for every request (aleviating need for thread-safe Actions)
* Includes modified Struts example
What's New
Discontinued - April 12, 2004
* This plugin is now part of Spring (as of 1.0.1). You can read more about Spring's Struts support on Matt Raible's Spring Live blog.
0.1 - October 17, 2003
* Initial release
Requirements
This plugin requires Struts 1.1 or greater.
Usage
To use the Struts Spring plugin, add the ContextLoaderPlugIn to your Struts config file (usually struts-config.xml):
The "contextConfigLocation" property is the location of the Spring beans configuration file.
For each action that uses Spring, you need to define the action mapping to use org.springframework.web.struts.DelegatingActionProxy and declare a matching (action "path" == bean "name") Spring bean for the actual Struts action. This is an example of an action that requires an instance of UserDatabase:
The corresponding Spring bean configuration:
For more information on the Spring configuration file format, see the Spring beans DTD.
The Struts action org.apache.struts.webapp.example.LogonAction will automatically receive a reference to UserDatabase without any work on its part or references to Spring by adding a standard JavaBean setter:
private UserDatabase database = null;
public void setUserDatabase(UserDatabase database) {
this.database = database;
}
hashCode() and equals()
with out overriding of hashCode() method.
package com;
class Test{
String r;
Test(String r){
this.r =r;
}
}
public class TestHashCodeAndEquals {
private int no;
private String name;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setNo(int no) {
this.no = no;
}
public int getNo() {
return no;
}
public TestHashCodeAndEquals(int no,String name) {
this.setNo(no);
this.setName(name);
}
/*@Override
public int hashCode() {
return 11;
}*/
public static void main(String[] args) {
TestHashCodeAndEquals o1 = new TestHashCodeAndEquals(1,"rama");
System.out.println(o1.hashCode());
TestHashCodeAndEquals o2 = new TestHashCodeAndEquals(1,"rama");
System.out.println(o2.hashCode());
System.out.println(o1.equals(o2));
System.out.println((o1==o2)+" wew");
String s1 = "rama";
String s2 = "rama";
System.out.println(s1==s2);
System.out.println(s1.hashCode());
System.out.println(s2.hashCode());
String s11 = new String("rama");
String s21 = new String("rama");
System.out.println(s11==s21);
System.out.println(s11.equals(s21));
System.out.println(s11.hashCode());
System.out.println(s21.hashCode());
Integer i1 = new Integer(10);
Integer i2 = new Integer(1234);
System.out.println(i1==i2);
System.out.println(i1.equals(i2));
System.out.println(i1.hashCode());
System.out.println(i2.hashCode());
Test t1 = new Test("rama");
Test t2 = new Test("rama");
System.out.println(t1.equals(t2));
System.out.println(t1.hashCode());
System.out.println(t2.hashCode());
Thread t = new Thread();
Thread t11 = new Thread(t);
System.out.println(t.hashCode()+" "+t11.hashCode());
// other than System defined wapper classes, we will not get the hashcode equal if and only if we override the hashCode() method in our class.
// even though we override the hashCode() ,override the hashCode() in our class,we can have same hashcode for all instance ,still, equals() will return false
}
}
out put
.......
-1-
4072869
1671711
false
false wew
-2-
true
3492867
3492867
-3-
false
true
3492867
3492867
-4-
false
false
10
1234
-5-
false
4384790
9634993
-6-
1641745 11077203
------------------------------------------------------------------
with overriding of hashCode() method.
package com;
class Test{
String r;
Test(String r){
this.r =r;
}
}
public class TestHashCodeAndEquals {
private int no;
private String name;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setNo(int no) {
this.no = no;
}
public int getNo() {
return no;
}
public TestHashCodeAndEquals(int no,String name) {
this.setNo(no);
this.setName(name);
}
@Override
public int hashCode() {
return 11;
}
public static void main(String[] args) {
System.out.println("-1-");
TestHashCodeAndEquals o1 = new TestHashCodeAndEquals(1,"rama");
System.out.println(o1.hashCode());
TestHashCodeAndEquals o2 = new TestHashCodeAndEquals(1,"rama");
System.out.println(o2.hashCode());
System.out.println(o1.equals(o2));
System.out.println((o1==o2)+" wew");
String s1 = "rama";
String s2 = "rama";
System.out.println("-2-");
System.out.println(s1==s2);
System.out.println(s1.hashCode());
System.out.println(s2.hashCode());
System.out.println("-3-");
String s11 = new String("rama");
String s21 = new String("rama");
System.out.println(s11==s21);
System.out.println(s11.equals(s21));
System.out.println(s11.hashCode());
System.out.println(s21.hashCode());
System.out.println("-4-");
Integer i1 = new Integer(10);
Integer i2 = new Integer(1234);
System.out.println(i1==i2);
System.out.println(i1.equals(i2));
System.out.println(i1.hashCode());
System.out.println(i2.hashCode());
System.out.println("-5-");
Test t1 = new Test("rama");
Test t2 = new Test("rama");
System.out.println(t1.equals(t2));
System.out.println(t1.hashCode());
System.out.println(t2.hashCode());
System.out.println("-6-");
Thread t22 = new Thread();
Thread t11 = new Thread(t22);
System.out.println(t22.hashCode()+" "+t11.hashCode());
// other than System defined wapper classes, we will not get the hashcode equal if and only if we override the hashCode() method in our class.
// even though we override the hashCode() ,override the hashCode() in our class,we can have same hashcode for all instance ,still, equals() will return false
}
}
out put
.......
-1-
11
11
false
false wew
-2-
true
3492867
3492867
-3-
false
true
3492867
3492867
-4-
false
false
10
1234
-5-
false
1671711
11394033
-6-
4384790 9634993
package com;
class Test{
String r;
Test(String r){
this.r =r;
}
}
public class TestHashCodeAndEquals {
private int no;
private String name;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setNo(int no) {
this.no = no;
}
public int getNo() {
return no;
}
public TestHashCodeAndEquals(int no,String name) {
this.setNo(no);
this.setName(name);
}
/*@Override
public int hashCode() {
return 11;
}*/
public static void main(String[] args) {
TestHashCodeAndEquals o1 = new TestHashCodeAndEquals(1,"rama");
System.out.println(o1.hashCode());
TestHashCodeAndEquals o2 = new TestHashCodeAndEquals(1,"rama");
System.out.println(o2.hashCode());
System.out.println(o1.equals(o2));
System.out.println((o1==o2)+" wew");
String s1 = "rama";
String s2 = "rama";
System.out.println(s1==s2);
System.out.println(s1.hashCode());
System.out.println(s2.hashCode());
String s11 = new String("rama");
String s21 = new String("rama");
System.out.println(s11==s21);
System.out.println(s11.equals(s21));
System.out.println(s11.hashCode());
System.out.println(s21.hashCode());
Integer i1 = new Integer(10);
Integer i2 = new Integer(1234);
System.out.println(i1==i2);
System.out.println(i1.equals(i2));
System.out.println(i1.hashCode());
System.out.println(i2.hashCode());
Test t1 = new Test("rama");
Test t2 = new Test("rama");
System.out.println(t1.equals(t2));
System.out.println(t1.hashCode());
System.out.println(t2.hashCode());
Thread t = new Thread();
Thread t11 = new Thread(t);
System.out.println(t.hashCode()+" "+t11.hashCode());
// other than System defined wapper classes, we will not get the hashcode equal if and only if we override the hashCode() method in our class.
// even though we override the hashCode() ,override the hashCode() in our class,we can have same hashcode for all instance ,still, equals() will return false
}
}
out put
.......
-1-
4072869
1671711
false
false wew
-2-
true
3492867
3492867
-3-
false
true
3492867
3492867
-4-
false
false
10
1234
-5-
false
4384790
9634993
-6-
1641745 11077203
------------------------------------------------------------------
with overriding of hashCode() method.
package com;
class Test{
String r;
Test(String r){
this.r =r;
}
}
public class TestHashCodeAndEquals {
private int no;
private String name;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setNo(int no) {
this.no = no;
}
public int getNo() {
return no;
}
public TestHashCodeAndEquals(int no,String name) {
this.setNo(no);
this.setName(name);
}
@Override
public int hashCode() {
return 11;
}
public static void main(String[] args) {
System.out.println("-1-");
TestHashCodeAndEquals o1 = new TestHashCodeAndEquals(1,"rama");
System.out.println(o1.hashCode());
TestHashCodeAndEquals o2 = new TestHashCodeAndEquals(1,"rama");
System.out.println(o2.hashCode());
System.out.println(o1.equals(o2));
System.out.println((o1==o2)+" wew");
String s1 = "rama";
String s2 = "rama";
System.out.println("-2-");
System.out.println(s1==s2);
System.out.println(s1.hashCode());
System.out.println(s2.hashCode());
System.out.println("-3-");
String s11 = new String("rama");
String s21 = new String("rama");
System.out.println(s11==s21);
System.out.println(s11.equals(s21));
System.out.println(s11.hashCode());
System.out.println(s21.hashCode());
System.out.println("-4-");
Integer i1 = new Integer(10);
Integer i2 = new Integer(1234);
System.out.println(i1==i2);
System.out.println(i1.equals(i2));
System.out.println(i1.hashCode());
System.out.println(i2.hashCode());
System.out.println("-5-");
Test t1 = new Test("rama");
Test t2 = new Test("rama");
System.out.println(t1.equals(t2));
System.out.println(t1.hashCode());
System.out.println(t2.hashCode());
System.out.println("-6-");
Thread t22 = new Thread();
Thread t11 = new Thread(t22);
System.out.println(t22.hashCode()+" "+t11.hashCode());
// other than System defined wapper classes, we will not get the hashcode equal if and only if we override the hashCode() method in our class.
// even though we override the hashCode() ,override the hashCode() in our class,we can have same hashcode for all instance ,still, equals() will return false
}
}
out put
.......
-1-
11
11
false
false wew
-2-
true
3492867
3492867
-3-
false
true
3492867
3492867
-4-
false
false
10
1234
-5-
false
1671711
11394033
-6-
4384790 9634993
The DROP TRIGGER statement
In a DROP TRIGGER statement, the table name must be prepended to the name of the trigger:
DROP TRIGGER.
DROP TRIGGER