Java创建对象的方式
一、前言
在Java中,创建对象是一项基本任务。Java提供了多种创建对象的方式,包括使用new
关键字和构造函数、使用带参数的构造函数、使用反射、使用clone()
方法、使用对象序列化等。这些不同的方式适用于不同的场景,例如创建默认对象、创建带参数对象、创建对象副本等。了解并掌握这些创建对象的方式将使开发人员能够根据需要选择最合适的方式,并提高代码的灵活性和可扩展性。无论你是初学者还是有经验的Java开发人员,掌握这些方式都是非常重要的。本文将介绍几种常见的创建对象的方式。
二、具体创建
1. new关键字
通过使用new
关键字和构造函数,可以在Java中动态地创建对象,并根据需要进行自定义初始化操作。这是Java中最常见和基本的对象创建方式之一。
// 省略setter和getter
public class User {
private String name;
private Integer age;
}
public static void main(String[] args) {
// 使用new关键字创建对象
User user = new User();
user.setName("isabener");
user.setAge(18);
// 打印创建的对象
System.out.println(user);
}
结果记录:
User{name=isabener, age=18}
2. class的newInstance()
使用Class
对象的newInstance()
方法来创建该类的实例。该方法通过调用类的默认构造函数来创建一个新实例。需要注意的是,newInstance()
方法在Java 9中已被弃用,并在Java 11中被移除。但是它仍然适用于旧版本的Java,但建议使用其他方式来创建对象,如使用构造函数或工厂方法。
// 省略setter和getter
public class User {
private String name;
private Integer age;
}
public static void main(String[] args) throws
InstantiationException, IllegalAccessException {
// 使用class.newInstance()创建对象
User user = User.class.newInstance();
user.setName("isabener");
user.setAge(18);
// 打印创建的对象
System.out.println(user);
}
结果记录:
User{name=isabener, age=18}
3. Constructor.newInstance()
使用Constructor.newInstance()
方法可以更灵活地创建对象,包括调用非公共构造函数和传递自定义参数。这种方式常用于反射和动态创建对象的场景。可以使用Class
对象的getConstructor()
或getDeclaredConstructor()
方法来获取构造函数对象。getConstructor()
方法用于获取公共的构造函数,而getDeclaredConstructor()
方法可以获取所有类型的构造函数,包括私有构造函数,然后使用Constructor
对象的newInstance()
方法来创建对象实例,该方法会调用构造函数并返回一个新的实例。
// 省略setter和getter
public class User implements Serializable {
private String name;
private Integer age;
public User() {
}
public User(String name, Integer age) {
this.name = name;
this.age = age;
}
}
public static void main(String[] args) throws
InstantiationException, IllegalAccessException,
NoSuchMethodException, InvocationTargetException {
// 使用Constructor.newInstance()创建对象
// getConstructor()
Constructor<User> con = User.class.getConstructor();
User user1 = con.newInstance();
user1.setName("isabener");
user1.setAge(18);
// getDeclaredConstructor()
Constructor<User> deCon = User.class.getDeclaredConstructor(String.class, Integer.class);
deCon.setAccessible(true);
User user2 = deCon.newInstance("ISABENER", 19);
// 打印创建的对象
System.out.println(user1);
System.out.println(user2);
}
结果记录:
User{name=isabener, age=18}
User{name=ISABENER, age=19}
4. Clone()
使用clone()
方法可以创建对象的副本,但需要注意以下几点:
- 要复制的类必须实现
Cloneable
接口。 - 默认情况下,
clone()
方法会进行浅拷贝,即复制对象及其引用类型的成员变量的引用。如果需要深拷贝,必须在类中重写clone()
方法,并在其中执行深层次的复制操作。 - 在调用
clone()
方法时,需要进行类型转换。 clone()
方法是Object
类的受保护方法,因此需要在类中重写该方法并将其设置为公共访问权限。
// 省略setter和getter
public class User implements Cloneable{
private String name;
private Integer age;
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
public static void main(String[] args) throws CloneNotSupportedException {
// 使用clone()创建对象
User user = new User();
user.setName("isabener");
user.setAge(18);
User target = (User) user.clone();
// 打印创建的对象
System.out.println(target);
}
结果记录:
User{name=isabener, age=18}
5. 反序列化
使用反序列化可以创建对象的副本,包括其状态和数据。这种方式常用于对象的持久化和网络通信等场景。但是需要注意以下几点:
- 要进行反序列化,类必须实现
Serializable
接口。 - 序列化和反序列化操作通常需要将对象写入文件或网络流进行传输。
// 省略setter和getter
public class User implements Serializable {
private String name;
private Integer age;
}
public static void main(String[] args) throws IOException, ClassNotFoundException {
// 使用反序列化创建对象
User user = new User();
user.setName("isabener");
user.setAge(18);
// 将原始对象写入字节流
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(user);
oos.close();
// 从字节流中读取对象,进行反序列化
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
User target = (User) ois.readObject();
// 打印创建的对象
System.out.println(target);
}
结果记录:
User{name=isabener, age=18}
三、总结
总的来说,Java中创建对象的方式有很多种,可以根据具体的需求和设计模式选择适合的方式。每种方式都有其适用的场景和特点,在使用时可以根据实际情况选择最合适的创建对象的方式。