有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 net.ibloger.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("net.ibloger.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 net.ibloger.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("net.ibloger.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")); //打印true4、当Java虚拟机加载一个类时,会隐含地创建描述这个类的Class实例.
内容总结自开发经验,如有不对之处还请留言指出,感谢!
未经允许请勿转载:程序喵 » Java中创建对象的几种方法
程序喵