创建对象的几种方式

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.














评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值