Java中创建对象的几种方法

5种显式地创建对象的方式:

1、用new语句创建对象,这是最常用的创建对象的方式。

2、运用反射手段,调用Java.lang.Class或者java.lang.reflect.Constructor类的newInstance()实例方法。Class.forName()

3、调用对象的clone()方法

4、调用ClassLoader类加载器

5、运用反序列化手段,调用java.io.ObjectInputStream对象的readObject()方法.

下面演示了5种方式创建对象的过程。

package com.youcl.demo;

public class Customer implements Cloneable{
  private String name;
  private int age;

  public Customer() {
    System.out.println("默认构造");
  }

  public Customer(String name, int age) {
    this.name = name;
    this.age = age;
    System.out.println("参数构造");
  }
  
  public boolean equals(Object o) {
    if (this == o)
      return true;
    if (!(o instanceof Customer))
      return false;
    final Customer other = (Customer) o;
    if (this.name.equals(other.name) && this.age == other.age)
      return true;
    else
      return false;
  }

  public String toString() {
    return "name=" + name + ",age=" + age;
  }

  public static void main(String args[]) throws Exception {
    // 运用反射手段创建Customer对象
    Class objClass = Class.forName("com.youcl.demo.Customer");
    Customer c1 = (Customer) objClass.newInstance(); // 会调用Customer类的默认构造方法
    System.out.println("c1: " + c1); // 打印name=unknown,age=0

    // 用new语句创建Customer对象
    Customer c2 = new Customer("Tom", 20);
    System.out.println("c2: " + c2); // 打印name=tom,age=20

    // 运用克隆手段创建Customer对象,测试发现要实现Cloneable接口
    Customer c3 = (Customer) c2.clone(); // 不会调用Customer类的构造方法
    System.out.println("c2==c3 : " + (c2 == c3)); // 打印false
    System.out.println("c2.equals(c3) : " + c2.equals(c3)); // 打印true
    System.out.println("c3: " + c3); // 打印name=tom,age=20
  }
}

以上程序的打印结果如下:

默认构造
c1: name=null,age=0
参数构造
c2: name=Tom,age=20
c2==c3 : false
c2.equals(c3) : true
c3: name=Tom,age=20

从以上打印结果看出,用new语句或Class对象的newInstance()方法创建Customer对象时,都会执行Customer类的构造方法,而用对象的clone()方法创建Customer对象时,不会执行Customer类的构造方法。(区别)

ClassLoader 类加载器方式

这种方法其实跟Class.forName()有点类似,但有所区别,Class.forName()默认会将类装载到JVM并完成初始化(执行static块并对static变量赋值),而使用loadClass()方式则不会进行初始化。当然,两者在加载完类之后都要通过newInstance()才能创建对象。

package com.youcl.demo;

public class TestClass {
  String msg;

  void test() {
    System.out.println("Hello World");
  }

  public static void main(String args[]) throws Exception {
    TestClass object = (TestClass) TestClass.class.getClassLoader().loadClass("com.youcl.demo.TestClass").newInstance();
    object.test();
  }
}

反序列化方式示例

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class TestClass implements Serializable {
  String msg;

  void test() {
    System.out.println(msg);
  }

  public static void main(String args[]) throws Exception {
    TestClass object = new TestClass();
    // 修改对象中的变量值
    object.msg = "Hello World";
    // 将对象保存成文件
    FileOutputStream fos = new FileOutputStream("d://test.txt");
    ObjectOutputStream oos = new ObjectOutputStream(fos);
    oos.writeObject(object);
    // 从文件读取对象
    FileInputStream fis = new FileInputStream("d://test.txt");
    ObjectInputStream ois = new ObjectInputStream(fis);
    TestClass desObject = (TestClass) ois.readObject();
    desObject.test();
  }
}

输出
Hello World

反序列化文件查看示例值

除了以上5种显式地创建对象的方式以外,在程序中还可以隐含地创建对象,包括以下几种情况:

1、对于java命令中的每个命令行参数,Java虚拟机都会创建相应的String对象,并把它们组织到一个String数组中,再把该数组作为参数传给程序入口main(String args[])方法。

2、程序代码中的String类型的直接数对应一个String对象,例如:

String s1="Hello";  
String s2="Hello"; //s2和s1引用同一个String对象  
String s3=new String("Hello");  
System.out.println(s1==s2); //打印true  
System.out.println(s1==s3); //打印false

执行完以上程序,内存中实际上只有两个String对象,一个是直接数,由Java虚拟机隐含地创建,还有一个通过new语句显式地创建。

3、字符串操作符“+”的运算结果为一个新的String对象。例如:

String s1="H";  
String s2=" ello";  
String s3=s1+s2; //s3引用一个新的String对象  
System.out.println(s3=="Hello"); //打印false  
System.out.println(s3.equals("Hello")); //打印true

4、当Java虚拟机加载一个类时,会隐含地创建描述这个类的Class实例.

内容总结自开发经验,如有不对之处还请留言指出,感谢!

赞(52) 打赏
未经允许不得转载:优客志 » JAVA开发
分享到:

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏