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

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

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

目录

  • Java创建对象的5种方式简介、语法、举例、对比
    • 1. 使用new关键字
    • 2. 调用 java.lang.Class 的 newlnstance() 方法
    • 3. 调用java.lang.reflect.Constructor 类的newInstance()方法
    • 4. 调用对象的clone()方法
    • 5. 调用 java.io.ObjectlnputStream 对象的 readObject() 方法
    • 显式创建对象总结
    • 举例

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

你可能感兴趣的:(JAVA,java,jvm,开发语言)