基本的五种JAVA语言中实例化对象的方式

JAVA作为面向对象的编程语言,万事万物皆为对象,实际工作中我们常常会将创建(实例化)对象的操作交给框架或者容器(如SpringIoC),但我们应当了解JAVA实例化对象的多种方式

基本的五种JAVA语言中实例化对象的方式

所属分类: JAVA
专题标签: 创建 对象 反射

前言

最为JAVA开发者,无时无刻不在与JAVA对象打交道。
我们在日常工作中常常将创建(实例化)对象的任务交给依赖框架,如Spring。
但我们应当了解JAVA实例化对象的比较常见的一些形式,他们分别是:

  1. 使用new关键字(构造函数会被调用)
  2. 使用Class类的newInstance()(构造函数会被调用)
  3. 使用Constructor类的newInstance()(构造函数会被调用)
  4. 使用clone()方法(无构造函数调用)
  5. 使用deserialization(无构造函数调用)

使用new关键字

最通用、常见、普遍、简单的实例化方式,默认调用无参构造,支持调用有参构造。

  1. //无参构造创建对象
  2. User default = new User();
  3. //有参构造创建对象 有参构造的入参与自定义的构造函数一致
  4. User tom = new User("tom","boy");

使用Class类的newInstance()

使用反射的Class类的newInstance()来实例化对象,newInstance()方法将调用无参构造方法去实例化一个对象。

  1. //方法将调用类的无参构造
  2. User classIns = User.class.newInstance();

使用Constructor类的newInstance()

使用反射的Constructor类的newInstance()方法,与Class类中的newInstance()方法相似。
Constructor类的newInstance()方法我们能够调用有参构造函数和私有构造函数。

  1. //默认调用形式
  2. User consIns = User.class.getConstructor().newInstance();
  3. //调用有参构造
  4. User consInsTom = User.class.getConstructor().newInstance("tom","boy");
  5. //调用私有无参构造
  6. User consInsPrive = User.class.getDeclaredConstructor().newInstance();

使用clone()方法

调用对象的clone()方法时,JVM都会为我们创建一个新对象,并将前一个对象的所有内容复制到其中。
使用clone()方法创建对象不会调用任何构造函数,但对象的类需要实现Cloneable接口并定义clone()方法。
clone()方法是比较有争议的话题,确实有它的缺点,但其是创建任何对象副本的最流行和最简单的方法。

  1. //默认调用形式
  2. User jack = tom.clone();

使用deserialization

使用反序列化创建对象的前提是已经进行序列化操作,当进行序列化和反序列化对象时,JVM会为我们创建了一个独立的对象。
在反序列化过程中,JVM不使用任何构造函数来创建对象,需要在类中实现Serializable接口。

  1. //序列化
  2. User tom = new User("tom","boy");
  3. ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("data.tom"));
  4. out.writeObject(tom);
  5. out.close();
  6. //反序列化
  7. ObjectInputStream in = new ObjectInputStream(new FileInputStream("data.tom"));
  8. User tomBack = (User) in.readObject();
  9. in.close();

备注

反射方法

Class类的newInstance()方法和Constructor类的newInstance()方法都被称为创建对象的反射方法。
实际上,Class类的newInstance()方法内部使用Constructor类的newInstance()方法。
这就是为什么后者更受欢迎,并且也被Spring、Hibernate等不同的经典框架所使用的原因。

Constructor类的获得

上文中我们提到getConstructor()和getDeclaredConstructor()来获取Constructor类。

  • getDeclaredConstructor()返回指定参数类型、所有声明的(包括private)构造函数
  • getConstructor()返回指定参数类型、具有public访问权限的构造函数

因此getConstructor()是getDeclaredConstructor()的子集。