1. 使用new关键字
语法:
代码语言:javascript复制ClassName objectName = new ClassName();
2. 调用 java.lang.Class 的 newlnstance() 方法
语法:
代码语言:javascript复制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()方法
语法:
代码语言:javascript复制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()方法
语法:
代码语言:javascript复制Phone phone4 = (Phone)phone2.clone();
该方法不常用,使用该方法创建对象时,要实例化的类==必须继承 java.lang.Cloneable 接口==。
5. 调用 java.io.ObjectlnputStream 对象的 readObject() 方法
语法:
代码语言:javascript复制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复制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