Java 创建对象方法

来源:互联网 发布:如何连接条形码数据库 编辑:程序博客网 时间:2024/06/05 14:33

    本文主要介绍java创建对象的方法,闲话少叙。


Java创建对象的方法有多种,常见基本如下:


1、用new语句创建对象,这是最常见的创建对象的方法。

2、通过工厂方法返回对象,如:String str = String.valueOf(23); 
3、运用反射手段,调用java.lang.Class或者java.lang.reflect.Constructor类的newInstance()实例方法。

      Object obj = Class.forName("java.lang.Object").newInstance(); 
4、调用对象的clone()方法。实现Cloneable接口,然后重写Object.clone()方法创建对象.
5、通过I/O流(包括反序列化),如运用反序列化手段,调用java.io.ObjectInputStream对象的 readObject()方法。

6、String str="abc" 直接由jvm创建 或者使用 字符串操作符"+"  String str1 = "a"+"bc"由jvm创建。

创建对象方法比较:


工厂方法往往是调用new的,所以可以看作new的一种变形,对于虚拟机,本质一致。反序列化就是将数据读入后,调用反射生成新对象,唯一需要注意的是反射调用了类的无参构造函数,反射需要保证类有无参构造函数。下面重点介绍new,clone和反射。


new: 


  1.JVM首先检查该类是否加载,没有加载会先加载类,对类进行加载,解析和初始化;

  2.加载类后,JVM对该对象在Java堆中分配内存,

  3.设置对象,先对对象的初始化零值,就是对象字段初始化为零值;再对对象的对象头部分初始化,就是设置该对象的JVM相关属性,比如该对象属于哪个类,hash值,GC年代等。至此,从JVM看,对象创建了。

  4.执行<init>方法,按照程序员的意愿对对象的各个属性设置。比如,设置各个域的初始值。


clone:


  clone目的是复制一个原对象的copy,简单的就是内存复制,所以简单的clone是很快的,即与原对象相同,但是不一样,对新对象的操作不会影响原对象。clone在java规范中要求 1. a.clone() != a; 2. a.clone().getClass = a.getClass(); 3. a.clone().equals(a).

clone要求对象实现clonable接口,Object的clone方法会检测对象是够实现了这个接口。Object方法的clone方法是protected,即只有子类和同包(自定义类自然做不到和Object同包)才能调用。

    clone分浅clone和深clone。 

    浅clone,Shallow Clone,就是逐域拷贝,默认实现cloneable接口或者简单覆盖clone方法就是浅clone。例如:

public class A implements Cloneable {      public String name;        public Object clone() {          A o = null;          try {              o = (A) super.clone();          } catch (CloneNotSupportedException e) {              e.printStackTrace();          }          return o;      }  } 
    一个类如果只有基本类型和字符串这样的不可变对象,那么仅仅实现Cloneable就够了。但是如果类中包含数组或者复杂对象,就需要深clone,即正确生成新对象。例如:

public class A implements Cloneable {public String name[];public Vector<B> claB;public A(){name=new String[2];claB=new Vector<B>();}public Object clone() {A o = null;try {o = (A) super.clone();            o.name==(String[])name.clone();//深度clone            o.claB=new Vector<B>();//将clone进行到底            for(int i=0;i<claB.size();i++){            B temp=(B)claB.get(i).clone();//当然Class B也要实现相应clone方法            o.claB.add(temp);    }} catch (CloneNotSupportedException e) {e.printStackTrace();}return o;}}


其实,clone方法分三种情况处理。

1.对象只包含基本类型的域或者域指向了一个不可变对象,这种情况只需实现cloneable接口即可。

2.域中包含数组的对象,只需调用数组的clone方法。

3.域包含可变对象。这就是需要我们特别关照的情况,我们必须将这些可变的部分手动。比如,List。

下面有例子(有些正确clone,有些没有):

package basic.objects.methods;import java.util.ArrayList;import java.util.List;/** * 检测数组的clone的正确定。 c2的改变不应该引起c1对象的改变,这是clone的意义。 */public class Clones implements Cloneable {int[] ints;// 没有正确clonedouble[] doubles;// 正确处理List<String> strs;// 没有正确处理List<Character> chs; // 正确处理public Clones() {ints = new int[] { 0 };doubles = new double[] { 0 };strs = new ArrayList<String>();chs = new ArrayList<Character>();}@Overridepublic Clones clone() {try {Clones c = (Clones) super.clone();c.doubles = doubles.clone();c.chs = new ArrayList<Character>(chs);return c;} catch (CloneNotSupportedException e) {e.printStackTrace();}return null;}public static void main(String[] args) throws CloneNotSupportedException {Clones c1 = new Clones();Clones c2 = (Clones) c1.clone();c2.ints[0] = 1;c2.doubles[0] = 1;c2.strs.add("new str in c2 added");c2.chs.add('H');System.out.println(c1.ints[0]);System.out.println(c1.doubles[0]);System.out.println(c1.strs);System.out.println(c1.chs);}}



反射:


    反序列化往往是对于类在remote或者是一串特殊文本等的情况。简单说,Java自带的反序列化就是读取字节流,然后通过反射调用class的newInstance()方法,构造出新对象。反射构造对象具体见这里


下面是关于创建速度的文章,有兴趣可以一看。http://my.oschina.net/u/1428349/blog/299205

0 0