1、使用new关键字创建。
2、调用对象的clone方法,对象都继承自object类,它的clone方法是protected类型的,如果想要扩大使用范围,必须重写clone方法为public。
3、利用反射,调用class类或者是Constructor类的newInstance()方法,创建时默认使用对象的无参构造函数。
4、用反序列化,调用ObjectInputStream类的readObject()方法:
ObjectInputStream in = new ObjectInputStream (new FileInputStream("CloneTest.obj"));
CloneTest cloneTest3= (CloneTest)in.readObject();
使用一个Demo来说明:
public class CloneTest implements Cloneable {
private int id;
private String name;
public CloneTest() {
}
public CloneTest(int id, String name) {
this.name = name;
this.id = id;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
public String toString() {
return "CloneTest{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof CloneTest)) {
return false;
} else {
if (this.id == ((CloneTest) obj).id && this.name.equals(((CloneTest) obj).name)) {
return true;
}
}
return false;
}
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, CloneNotSupportedException {
CloneTest cloneTest = (CloneTest) Class.forName("CloneTest").newInstance();
System.out.println(cloneTest);
CloneTest cloneTest1 = new CloneTest(1001, "li");
System.out.println(cloneTest1);
CloneTest cloneTest2 = (CloneTest) cloneTest1.clone();
System.out.println(cloneTest2);
System.out.println(cloneTest1 == cloneTest2);
System.out.println(cloneTest1.equals(cloneTest2));
}
}
输出:
CloneTest{id=0, name='null'}
CloneTest{id=1001, name='li'}
CloneTest{id=1001, name='li'}
false
true
通过反射调用newInstance方法默认使用无参构造方法来创建对象,可通过toString方法输出的属性值都是默认值。
通过new关键字创建可以自由使用构造方法。
通过调用clone方法创建的对象,实际是复制了一个对象,把之前对象的属性值复制过来,但和原来的对象拥有不同的内存地址。
最后还有一种,隐式创建对象,通过直接给String赋值,就相当于创建了String对象,不过这是jvm虚拟机做的。