1 Serialization & anti-Serialization
package Execise;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Date;
public class Test{
public static void main(String[] args) throws Exception{
//open an output stream
ObjectOutputStream out=new ObjectOutputStream(new FileOutputStream("E:\\objectFile.obj"));
String obj1="hello";
Date obj2=new Date();
out.writeObject(obj1);// String class implemented the java.io.Serializable interface
out.writeObject(obj2);
/*the objectFile can not be read by normal text editor.It can be handeled
* by only ObjectInputStream, i.e. anti-serialization
*/
ObjectInputStream in= new ObjectInputStream(new FileInputStream("E:\\objectFile.obj"));
/*keep the same order when objects are read in
* Date obj2=(Date) in.readObject();
* String obj1=(String) in.readObject();
* error
*/
String obj11=(String) in.readObject();
Date obj22=(Date) in.readObject();
System.out.println(obj1);
System.out.println(obj2);
System.out.println("whether still the same object"+" "+(obj1==obj11));
/*
* output is:whether still the same object false
* they have different address before and after serialization but same information
*/
}
}
Through serialization we can obtain objects from file without calling the constructor.
The class must have implemented the java.io.serializable interface.
2 clone
The class must have implemented the java.lang.Cloneable interface. But there is no method in interface Cloneable.http://docs.oracle.com/javase/7/docs/api/java/lang/Cloneable.html
Invoking Object's clone method on an instance that does not implement the
Cloneable
interface results in the exception
CloneNotSupportedException
being thrown.
In class Object there is a method clone() to be overrided.
protected Object clone() throws CloneNotSupportedException
By convention, classes that implement this interface should override Object.clone (which is protected) with a public method.
I have a Customer.class
class Customer implements Cloneable{
String name;
int age;
public Customer(){
this.name="anonymous";
}
public Customer(String name){
this.name=name;
}
public Customer(String name,int age){
this(name);
this.age=age;
}
public Object clone() throws CloneNotSupportedException{
return super.clone();
}
}
test it
public class Test{
public static void main(String[] args) throws Exception{
Customer c1=new Customer("Tom");
Customer c2=new Customer("Mary",23);
Customer c3=(Customer)c1.clone();
System.out.println(c1.toString());
System.out.println(c2.toString());
System.out.println(c3.toString());
System.out.println("if: c1==c3 "+(c1==c3));
}
}
you would get the following result
name: Tom , age: -1
name: Mary , age: 23
name: Tom , age: -1
if: c1==c3 false
Creates and returns a copy of this object. The precise meaning of "copy" may depend on the class of the object. The general intent is that, for any object x, the expression:
x.clone() != x
will be true, and that the expression:
x.clone().getClass() == x.getClass()
will be true, but these are not absolute requirements. While it is typically the case that:
x.clone().equals(x)
will be true, this is not an absolute requirement.
By convention, the returned object should be obtained by calling super.clone. If a class and all of its superclasses (except Object)obey this convention, it will be the case that x.clone().getClass() == x.getClass().
What should be specially mentioned! Deep Clone
By convention, the object returned by this method should be independent of this object (which is being cloned)!!!
To achieve this independence, it may be necessary to modify one or more fields of the object returned by super.clone before returning it. Typically, this means copying any mutable objects that comprise the internal "deep structure" of the object being cloned and replacing the references to these objects with references to the copies. If a class contains only primitive fields or references to immutable objects, then it is usually the case that no fields in the object returned by super.clone need to be modified.
We make our Customer more complex by adding an ArrayList<String> type reference.
class Customer implements Cloneable{
String name;
int age;
ArrayList<String> info=new ArrayList<String>();
public Customer(String name,int age){
this.name=name;
this.age=age;
}
public Object clone() throws CloneNotSupportedException{
return super.clone();
}
public String toString(){
return "name: "+name+" ,"+" age: "+age+" info: "+info.toString();
}
}
By testing it we found the simple copy of reference will lead to dependence of two objects where clonation happens.
public class Test{
public static void main(String[] args) throws Exception{
Customer c1=new Customer("Tom",22);
c1.info.add("hot");
Customer c2=new Customer("Mary",23);
c2.info.add("large");
Customer c3=(Customer)c1.clone();
c3.info.add("mild");
System.out.println(c1.toString());
System.out.println(c2.toString());
System.out.println(c3.toString());
}
}
The reference info of c1 and c3 represent the same object. The change of one influences the other.
A solution will be deep clone.
public Object clone() throws CloneNotSupportedException{
Customer c=null;
c=(Customer)super.clone();
c.info=new ArrayList<String>();
Iterator<String> itr=this.info.iterator();
while(itr.hasNext()){
c.info.add(itr.next());
}
return c;
}
3 Reflection
Still using that
Class customerClass=Customer.class; //step 1: get class
//step 2: get constructors
Constructor[] constructors=customerClass.getConstructors();
for(Constructor c:constructors){
System.out.println(c.toString());
}
//step 3: using one of the constructors, passing in arguments
Constructor constructor=customerClass.getConstructor(new Class[]{java.lang.String.class});
Customer c1=(Customer)constructor.newInstance("new Customer");// step 4: create new instance
System.out.println(c1.toString());
public Execise.Customer(java.lang.String,int)
public Execise.Customer(java.lang.String)
public Execise.Customer()
name: new Customer age: 0
4 New key word
calling constructor explicitly.