Java创建对象的几种方式

1:Java创建对象的方式和使用范围

创建方式的对比
创建方式调用机制使用场景
new 关键字创建 实例化调用了构造函数对象最通用、常规,简单的方法 适用于任何可通过构造器来实例化对象的地方。

Class类的newInstance方法

实例化调用了构造函数

newInstance()是实现IOC、反射、面对接口编程和依赖倒置等技术常用方式,一般用于设计框架

例如spring 框架的 对象实例化等。利用类路径进行对象实例化。

Contructor 的 newInstance()方法实例化调用了构造函数

newInstance()是实现IOC、反射、面对接口编程和依赖倒置等技术常用方式,一般用于设计框架

例如spring 框架的 对象实例化等。利用类路径进行对象实例化。 这种 方式比class 方式用得更多,因为class 方式也是调用contructor构造器。并且这种方式可以是无参和有参都可以,class则

只有一种 无参构造器。

clone()方法无构造函数调用

如果想创建一个对象新的副本,保持对象初始状态完全相同,但是随后又可以改变新的副本的对象

的属性和值则此时适用

deserialization无构造函数调用

提及反序列化时需要理解序列化,所谓序列化:即将一个对象用一串字符表示。因此,序列化可以看成是为了把对象存储在磁盘上或者是从磁盘上读出来并重建对象而把对象扁平化的一种方式。反序列化是把对象从扁平状态转化成活动对象的相反的步骤。

 

1.1: new 关键字创建 

package com;

public class Student {

    public static void main(String[] args) {
        Book  book  =  new Book();
        System.out.println(book.getBookName());
    }
}


package com;

public class Book {

    private  String bookName;

    private  String bookNum;

    public String getBookName() {
        return bookName;
    }

    public void setBookName(String bookName) {
        this.bookName = bookName;
    }

    public String getBookNum() {
        return bookNum;
    }

    public void setBookNum(String bookNum) {
        this.bookNum = bookNum;
    }
}

 1.2:  Class类的newInstance方法 和  Contructor 的 newInstance()  从如下图种 java.lang.reflect可看出

        该创建对象使用反射技术,所以一般用于设计框架阶段使用

package com;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class Student {

    public static void main(String[] args) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {

        //通过class newIstance() 该对象只能是无参构造器
        Book  book1 =   Book.class.newInstance();

        //通过Constructor newIstance 实例化对象 此时该对象可以是无参或者有参都行
        Constructor constructor = Book.class.getConstructor();
        Book emp3 = (Book) constructor.newInstance();
    }
}

1.3: clone()方法创建  需要实现Cloneable 创建对象时效率要高于使用new来创建 

package com;

import java.lang.reflect.Constructor;
import java.util.List;

public class Student {

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

        Book  book  =  new Book();
        book.setBookName("数学");
        book.setBookNum(1);
        List<Book> list = new ArrayList<Book>();
        for(int i =0 ;i<6;i++){
            Book b2 =   (Book) book.clone();
            b2.setBookNum(i);
            list.add(b2);
       }
        System.out.println(list.toString());

    }
}



package com;

public class Book implements Cloneable{

    private  String bookName;

    private  Integer bookNum;

    public Book(String name) {
        this.bookName = name;
        if (name.length() != 0) {
            bookName = name.substring(0, 1);
            bookName += "abc";
        }
    }

    public String getBookName() {
        return bookName;
    }

    public void setBookName(String bookName) {
        this.bookName = bookName;
    }

    public Integer getBookNum() {
        return bookNum;
    }

    public void setBookNum(Integer bookNum) {
        this.bookNum = bookNum;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    @Override
    public String toString() {
        return "Book{" +
                "bookName='" + bookName + '\'' +
                ", bookNum=" + bookNum +
                '}';
    }
}

输出结果:::: 
[Book{bookName='数学', bookNum=0}, Book{bookName='数学', bookNum=1}, Book{bookName='数学', bookNum=2}, Book{bookName='数学', bookNum=3}, Book{bookName='数学', bookNum=4}, Book{bookName='数学', bookNum=5}]
输出哈希值:
460141958
1163157884
1956725890
356573597
1735600054
21685669

1614008253363
clone时间差40
1614008253403
new时间差50

从输出结果可看出 克隆对象具备原有对象的值,但是可以改变原有对象的默写属性 其中地址也不一样。
在某个对象中无构造函数时创建对象 少了没有差异,大于100000时new 效率高,在有参构造器中做操作时
clone效率明显,所以轻量级对象创建使用new 否则其他使用clone()

1.4:deserialization 生成对象

       串行化(serialization)是指将一个对象的当前状态转换成字节流(a stream of bytes)的过程,而反串行化(deserialization)则指串行化过程的逆过程,将字节流转换成一个对象,

package com.qxkj;

import java.io.Serializable;

public class Employ implements Serializable {

    private static final long serialVersionUID = 1L;
    private int age; // will persist
    private String name; // will persist
    // transient 为Java保留字,告诉JVM以transient宣告的基本型态(primitive type)或物
    // 件(object)变量不要序列化,例如敏感性数据像是密码等。
    private transient String pwd; // will not persist
    public Employ() {
    }

    public Employ(int age, String name,String pwd) {
        this.age = age;
        this.name = name;
        this.pwd=pwd;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPwd() {
        return pwd;
    }

    public void setPwd(String pwd) {
        this.pwd = pwd;
    }
}



package com.qxkj;

import java.io.*;

/**
 * @author Administrator
 * @title: TestSerializable
 * @projectName day_test_project
 * @description: TODO
 * @date 2021/2/22 002223:48
 */
public class TestSerializable {

    private static File f = null;

    //串行化
    public static void serialization() {
        f = new File("D://t.m");
        try {
            if (f.exists())
                f.delete();
            f.createNewFile();

        } catch (IOException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        Employ p = new Employ(10, "xplq", "123456");
        try {
            ObjectOutputStream out = new ObjectOutputStream(
                    new FileOutputStream(f));
            out.writeObject(p);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    //反串行化
    public static void deserialization() {
        if (!f.exists())
            return;
        try {
            ObjectInputStream input = new ObjectInputStream(
                    new FileInputStream(f.getPath()));
            try {
                Employ p = (Employ) input.readObject();
                System.out.println(p.getName());
                System.out.println(p.getAge());
                System.out.println(p.getPwd());
            } catch (ClassNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    //测试
    public static void main(String[] args) {
        TestSerializable.serialization();
        TestSerializable.deserialization();
    }

}


输出结果
李四
50
null
数学
密码为null 是因为ransient 为Java保留字,告诉JVM以transient宣告的基本型态(primitive type)或物
    // 件(object)变量不要序列化,例如敏感性数据像是密码等。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值