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

👁️ 2762 ❤️ 912
Java创建对象的5种方式简介、语法、举例、对比

1. 使用new关键字 语法:

代码语言:javascript代码运行次数:0运行复制ClassName objectName = new ClassName();2. 调用 java.lang.Class 的 newlnstance() 方法 语法:

代码语言:javascript代码运行次数:0运行复制Class c1 = Class.forName("com.java_demo01.day03.Phone");

Phone phone2 = (Phone)c1.newInstance();

// 或者

Class 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()方法 语法:

代码语言:javascript代码运行次数:0运行复制import java.lang.reflect.Constructor;

import java.lang.reflect.InvocationTargetException;

Constructor constructor = Phone.class.getConstructor(String.class, double.class);

Phone phone5 = constructor.newInstance("OPPO", 1500.0);

phone5.printPhoneInfo();4. 调用对象的clone()方法 语法:

代码语言:javascript代码运行次数:0运行复制Phone phone4 = (Phone)phone2.clone(); 该方法不常用,使用该方法创建对象时,要实例化的类==必须继承 java.lang.Cloneable 接口==。

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

代码语言:javascript代码运行次数:0运行复制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对象的方式:

代码语言:javascript代码运行次数:0运行复制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 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 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

← 如何找到exe的api程序 SPDIF是什么接口?SPDIF接口科普与使用分享 →