Java中创建对象的5种方式
1.使用new关键字
package com.zmy.java.object;
public class Student{
private String name;
private Integer age;
public Student() {
System.out.println("无参构造方法!");
}
public Student(String name, Integer age) {
this.name = name;
this.age = age;
System.out.println("有参构造方法!");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + ''' +
", age=" + age +
'}';
}
public static void main(String[] args) {
Student student = new Student();
student.setName("小明");
student.setAge(15);
System.out.println(student.toString());
}
}代码执行结果:
执行结果分析:
通过new关键字创建对象时,会通过调用该类的无参构造方法或有参构造方法来创建一个对象实例。
2.使用clone()方法
通过其他对象的clone()来生成新对象
package com.zmy.java.object;
public class Student implements Cloneable{
private String name;
private Integer age;
public Student() {
System.out.println("无参构造方法!");
}
public Student(String name, Integer age) {
this.name = name;
this.age = age;
System.out.println("有参构造方法!");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + ''' +
", age=" + age +
'}';
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
public static void main(String[] args) throws CloneNotSupportedException{
Student student = new Student();
student.setName("小明");
student.setAge(15);
Student student2 = (Student) student.clone();
System.out.println(student2);
student2.setAge(14);
student2.setName("小华");
System.out.println(student2);
}
}
代码执行结果
执行结果分析:
使用clone()方法来创建对象B时,前提是已创建有对象A,然后通过调用对象A的clone()方法来赋值给对象B,此时对象B中的成员变量值均与对象A中的成员变量值一样。
执行的顺序是:先创建对象A,并给对象A的成员变量赋值;
调用对象A的clone()方法,JVM会创建一个新对象B,并将对象A中的内容全部拷贝一份给对象B。
注意:通过clone()创建对象时不会调用任何构造方法。
3.使用Class类的newInstance()方法
package com.zmy.java.object;
public class Student{
private String name;
private Integer age;
public Student() {
System.out.println("无参构造方法!");
}
public Student(String name, Integer age) {
this.name = name;
this.age = age;
System.out.println("有参构造方法!");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + ''' +
", age=" + age +
'}';
}
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
Student student = (Student)Class.forName("com.zmy.java.object.Student").newInstance();
student.setName("小明");
student.setAge(15);
System.out.println(student);
}
}
代码执行结果
执行结果分析:
通过Class.forName("该类的类路径").newInstance()来创建对象时,会调用无参构造方法来创建一个对象。
4.使用Constructor的newInstance()方法
package com.zmy.java.object;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class Student{
private String name;
private Integer age;
private Student() {
System.out.println("无参构造方法!");
}
public Student(String name, Integer age) {
this.name = name;
this.age = age;
System.out.println("有参构造方法!");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + ''' +
", age=" + age +
'}';
}
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, CloneNotSupportedException, NoSuchMethodException, InvocationTargetException {
Constructor constructor = Student.class.getDeclaredConstructor();
Student student = (Student)constructor.newInstance();
student.setName("小明");
student.setAge(18);
System.out.println(student);
}
}
代码执行结果:
执行结果分析:
通过Constructor的newInstance()方法来创建对象时,会通过调用无参构造方法或有参构造方法来创建对象。
注意本代码实例中无参构造方法为private类型!!!
注意:类名.class.getDeclaredConstructor()和类名.class.getConstructor()的区别!!!
getDeclaredConstructor:返回指定参数类型、所有声明的(包括private)构造函数
getConstructor**:返回指定参数类型、具有public访问权限的构造函数
5.使用反序列化
package com.zmy.java.object;
import java.io.*;
public class Student implements Serializable {
private String name;
private Integer age;
public Student() {
System.out.println("无参构造方法!");
}
public Student(String name, Integer age) {
this.name = name;
this.age = age;
System.out.println("有参构造方法!");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + ''' +
", age=" + age +
'}';
}
public static void main(String[] args) throws IOException, ClassNotFoundException {
Student student = new Student("小明",18);
System.out.println("java序列化开始");
// 文件输出流
FileOutputStream fos = new FileOutputStream("E:\IdeaProjects\project01\src\com\zmy\java\object\Student.ser");
// 对象输出流
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(student);
oos.close();
fos.close();
System.out.println("-----------------------------------------------------");
System.out.println("java反序列化开始");
// 文件输入流
FileInputStream fis = new FileInputStream("E:\IdeaProjects\project01\src\com\zmy\java\object\Student.ser");
// 对象输入流
ObjectInputStream ois = new ObjectInputStream(fis);
Student student1 = (Student) ois.readObject();
System.out.println(student1);
}
}
代码执行结果分析:
执行结果分析:
Student类实现了Serializable接口后才可以被序列化!编译器先将代码序列化到文件中,java默认序列化后的文件后缀为.ser。然后,反序列化操作后得到Student对象。
反序列化时并不会调用Student类的无参或有参构造方法!
如果不想实例化对象的某个成员变量,可以在成员变量前使用transient关键字!则该字段不会被序列化!
示例:
public class Student implements Serializable {
private String name;
private transient Integer age;
对于 JVM 可以反序列化对象,它必须是能够找到字节码的类。如果JVM在反序列化对象的过程中找不到该类,则抛出一个 ClassNotFoundException 异常。
注意,readObject() 方法的返回值被转化成 Student引用。



