Java创建对象的5种方式简介、语法、举例、对比

Java创建对象的5种方式简介、语法、举例、对比

原文地址:Java创建对象的5种方式简介、语法、举例、对比

1. 使用new关键字

语法:

ClassName objectName = new ClassName();

2. 调用 java.lang.Class 的 newlnstance() 方法

语法:

Class c1 = Class.forName("com.java_demo01.day03.Phone");
Phone phone2 = (Phone)c1.newInstance();
// 或者
Class<Phone> c2 = Phone.class;
Phone phone3 = c2.newInstance();
  • newInstance()自jdk 9开始已经弃用

  • 调用 java.lang.Class 类中的 forName() 方法时,需要将要实例化的类的全称(比如 com.java_demo01.day03.Phone)作为参数传递过去,然后再调用 java.lang.Class 类对象的 newInstance() 方法创建对象。

  • 即该方法创建对象需要两步,第一步创建类对象,第二步调用类对象的newInstance()方法

  • newInstance()只能调用public类型的无参构造方法,因此通过此方法实例化对象,则类必须要有无参构造方法,否则将抛出InstantiationException异常。

3. 调用java.lang.reflect.Constructor 类的newInstance()方法

语法:

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

Constructor<Phone> constructor = Phone.class.getConstructor(String.class, double.class);
Phone phone5 = constructor.newInstance("OPPO", 1500.0);
phone5.printPhoneInfo();

4. 调用对象的clone()方法

语法:

Phone phone4 = (Phone)phone2.clone();

该方法不常用,使用该方法创建对象时,要实例化的类必须继承 java.lang.Cloneable 接口

5. 调用 java.io.ObjectlnputStream 对象的 readObject() 方法

语法:

Phone phone = new Phone(); // 调用无参构造方法
// 序列化对象phone
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("data.obj"));
out.writeObject(phone);
out.close();

// 反序列化
ObjectInputStream in = new ObjectInputStream(new FileInputStream("data.obj"));
Phone phone1 = (Phone) in.readObject();
in.close();

上述结果表明通过反序列化创建对象,该对象的属性值为被序列化的对象的属性值。

显式创建对象总结

创建方式调用何种构造方法说明
new任意最常用
Class.newInstance()只能调用public无参构造方法自JDK 9开始弃用
Constructor.newInstance()任意、私有也可调用有参构造方法时要在
getConstructor中指明参数类型
clone()不调用任何构造方法JVM创建对象并将被clone的
对象内容拷贝进去;
类需要实现Cloneable接口
readObject()反序列化不调用任何构造方法类需要实现Serializable接口;
JDK序列化、反序列化特别特别耗内存。

因此Java创建对象不一定要通过构造方法

举例

下面例子实现了上述5种创建Java对象的方式:

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

public class Phone implements Cloneable, Serializable {
    private String brand;
    private double price;

    public Phone() {
        this("小米", 2000.0);
    }

    public Phone(String brand, double price) {
        this.brand = brand;
        this.price = price;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public void printPhoneInfo() {
        String result = "Phone brand: " + this.brand + " price: " + this.price;
        System.out.println(result);
    }

    public static void main(String[] args){
        try {
            // 使用第一种方式创建无参对象(前提是Phone有无参构造方法,否则报错)
            Phone phone1 = new Phone();
            phone1.printPhoneInfo();
            // 使用第一种方式创建有参对象(前提是Phone有有参构造方法,否则报错)
            Phone phone2 = new Phone("华为", 1999.9);
            phone2.printPhoneInfo();

            // 使用第二种方式创建无参对象(前提Phone有无参构造方法,否则抛出InstantiationException异常)
            Class<Phone> phoneClass = Phone.class;
            Phone phone3 = phoneClass.newInstance();
            phone3.printPhoneInfo();
            // 或者,前提同上
            Class<?> c1 = Class.forName("com.java_demo01.day03.Phone"); // 引号中是类的全称
            Phone phone4 = (Phone)c1.newInstance();
            phone4.printPhoneInfo();
            // 可以通过setBrand和setPrice方法为属性赋值,这里不再演示
		   // 使用第三种方式创建对象,该对象可以带有参数,且可以调用私有构造方法
            Constructor<Phone> constructor = Phone.class.getConstructor(String.class, double.class);
            Phone phone5 = constructor.newInstance("OPPO", 1500.0);
            phone5.printPhoneInfo();

            // 使用第三种方式创建对象,该对象的属性和被clone的对象属性相同,但是两个不同的对象
            Phone phone6 = (Phone)phone2.clone();
            phone6.printPhoneInfo();

            // 使用第四种方式创建对象,该对象的属性和被序列化的对象属性相同,但是两个不同的对象
            // 序列化对象phone
            ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("data.obj"));
            out.writeObject(phone2);
            out.close();

            // 反序列化
            ObjectInputStream in = new ObjectInputStream(new FileInputStream("data.obj"));
            Phone phone7 = (Phone) in.readObject();
            in.close();
            phone7.printPhoneInfo();
        } catch (IllegalAccessException |
                IOException |
                ClassNotFoundException |
                InstantiationException |
                CloneNotSupportedException |
                InvocationTargetException |
                NoSuchMethodException e) {
            e.printStackTrace();
        }

    }
}
// 输出结果
Phone brand: 小米 price: 2000.0
Phone brand: 华为 price: 1999.9
Phone brand: 小米 price: 2000.0
Phone brand: 小米 price: 2000.0
Phone brand: OPPO price: 1500.0
Phone brand: 华为 price: 1999.9
Phone brand: 华为 price: 1999.9
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小吴不会敲代码吧

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值