Java中5种创建对象的方式小笔记

方式是否调用了构造函数
使用new关键字
使用Class类的newInstance方法
使用Constructor类的newInstance方法
使用clone方法
使用反序列化

创建一个Cat类来说明,该类实现了Cloneable和Serializable接口。

package com.joshua317;

import java.io.Serializable;

public class Cat implements Cloneable, Serializable {
    private String name;
    private int age;

    public Cat() {
        System.out.println("调用无参构造函数");
    }

    public Cat(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public Cat clone() {
        Cat cat = null;
        try {
            cat = (Cat)super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return cat;
    }

    @Override
    public String toString() {
        return "Cat [name=" + name + ", age=" + age +  "]";
    }
}

注意:

1.java.lang.CloneNotSupportedException 原因是没有 implements Cloneable。

2.java.io.NotSerializableException 原因是没有 implements Serializable。

接下来我们编程来说明:

package com.joshua317;


import java.io.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class Main {

    public static void main(String[] args) {

        Cat cat1 = null, cat2 = null,cat3 = null ,cat4 = null ,cat5 = null;
        /**
         * 1.使用new关键字;
         * 通过使用这种方法我们可以调用任何我们需要调用的构造函数。
         */
        cat1 = new Cat();
        cat1.setName("小猫1");
        cat1.setAge(1);
        System.out.println("cat1:" + cat1);
        System.out.println();

        /**
         * 2.使用class类的newInstance方法
         * 此newInstance()方法调用无参构造函数以创建对象。
         */
        try {
            cat2 = (Cat) Class.forName("com.joshua317.Cat").newInstance();
            cat2.setName("小猫2");
            cat2.setAge(2);

            System.out.println("cat2:" + cat2);
            System.out.println();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        /**
         * 3.使用构造函数类的newInstance方法;
         * 与使用class类的newInstance()方法相似
         * java.lang.reflect.Constructor类中有一个可以用来创建对象的newInstance()函数方法。
         * 通过使用这个newInstance()方法我们也可以调用参数化构造函数和私有构造函数。
         */
        Constructor  constructor = null;
        try {
            constructor = Cat.class.getConstructor();
            try {
                cat3 = (Cat)constructor.newInstance();
                cat3.setName("小猫3");
                cat3.setAge(3);

                System.out.println("cat3:" + cat3);
                System.out.println();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }

        /**
         * 4.使用clone方法
         *
         * 在程序开发中,有时可能好会遇到下列情况:
         * 已经存在一个对象A,现在需要一个与对象A完全相同的B对象,并对B对象的值进行修改,但是A对象的原有的属性值不能改变。
         * 这时,如果使用java提供的对象赋值语句,当修改B对象值后,A对象的值也会被修改。
         * 那么应该如何实现创建一个和对象A完全相同的对象B,而且修改对象B时,对象A的属性值不被改变呢?
         *
         * clone方法可以完成对象的浅克隆。
         * 所谓浅克隆就是说被克隆的对象的各个属性都是基本类型,而不是引用类型(接口、类、数组),
         * 如果存在引用类型的属性,则需要进行深克隆。
         *
         * 实际上无论何时我们调用clone() 方法,JAVA虚拟机都为我们创建了一个新的对象并且复制了之前对象的内容到这个新的对象中。
         * 使用 clone()方法创建对象不会调用任何构造函数。
         * 为了在对象中使用clone()方法,我们需要在其中实现可克隆类型并定义clone()方法。
         */
        cat4 = (Cat) cat1.clone();
        cat4.setName("小猫4");
        cat4.setAge(4);

        System.out.println("cat4:" + cat4);
        System.out.println();
        /**
         * 5.使用反序列化
         * 无论何时我们对一个对象进行序列化和反序列化,JAVA虚拟机都会为我们创建一个单独的对象。
         * 在反序列化中,JAVA虚拟机不会使用任何构造函数来创建对象。
         * 对一个对象进行序列化需要我们在类中实现可序列化的接口。
         */


        //序列化
        FileOutputStream fileOut = null;
        try {
            fileOut = new FileOutputStream("./cat.ser");
            try {
                ObjectOutputStream out = new ObjectOutputStream(fileOut);
                out.writeObject(cat1);
                out.close();
                fileOut.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }


        //反序列化
        ObjectInputStream in = null;
        try {
            FileInputStream fileIn = new FileInputStream("./cat.ser");
            in = new ObjectInputStream(fileIn);
            try {
                cat5 = (Cat) in.readObject();
                in.close();
                fileIn.close();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("cat5:" +cat5);
        System.out.println();
    }
}

 

posted @ 2022-03-02 22:05  joshua317  阅读(57)  评论(0编辑  收藏  举报