语法:
ClassName objectName = new ClassName();
语法:
Class c1 = Class.forName("com.java_demo01.day03.Phone");
Phone phone2 = (Phone)c1.newInstance();
// 或者
Class<Phone> c2 = Phone.class;
Phone phone3 = c2.newInstance();
弃用
。
实例化的类的全称
(比如 com.java_demo01.day03.Phone)作为参数传递过去,然后再调用 java.lang.Class 类对象的 newInstance() 方法创建对象。
创建类对象
,第二步调用类对象的newInstance()方法
。
必须要有无参构造方法
,否则将抛出InstantiationException异常。
语法:
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();
语法:
Phone phone4 = (Phone)phone2.clone();
该方法不常用,使用该方法创建对象时,要实例化的类==必须继承 java.lang.Cloneable 接口==。
语法:
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