吃透Java基础二:创建对象的五种方式

一:使用new关键字

这是最常见也是最简单的创建对象的方式了。通过这种方式,我们可以调用任意的构造函数(无参的和带参数的)。

public static void main(String[] args) {
        People people = new People();
    }

二:使用Class类的newInstance方法

利用反射来获取class对象调用newInstance方法创建对象,其调用了无参的构造函数,所以类必须有public无参构造函数才行

如下可以正常运行,因为People有默认的无参构造器

public class People {
    public static void main(String[] args) {
        try {
            People people = (People) Class.forName("People").newInstance();
            System.out.println(people);
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

如下运行报错,因为People没有提供无参构造器

public class People {
    public People(String a) {
    }

    public static void main(String[] args) {
        try {
            People people = (People) Class.forName("People").newInstance();
            System.out.println(people);
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

三:使用Constructor类的newInstance方法

和Class类的newInstance方法很像。但是它可以调用任意构造函数创建对象,包括私有的。(所以即使你私有了构造函数,还是可以创建对象的)

Constructor<People> constructor = (Constructor<People>) Class.forName("People").getConstructor();
People people1 = constructor.newInstance();

此种方法和方法二的newInstance方法就是大家所说的反射。事实上Class的newInstance方法内部调用Constructor的newInstance方法。这也是众多框架,如Spring、hibernate、Struts等使用后者的原因。

四:使用clone方法

调用一个对象的clone方法,jvm就会创建一个新的对象,将前面对象的内容全部拷贝进去。用clone方法创建对象并不会调用任何构造函数。
但是要使用clone方法,我们需要先实现Cloneable接口并实现其定义的clone方法。

public class People implements Cloneable {
    public static void main(String[] args) {
        People people1 = new People();
        try {
            People people2 = (People) people1.clone();
            System.out.println(people1);
            System.out.println(people2);
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }
}

输出

People@4554617c
People@74a14482

五:使用反序列化

当我们序列化和反序列化一个对象,jvm会给我们创建一个单独的对象。在反序列化时,jvm创建对象并不会调用任何构造函数。
但是为了反序列化一个对象,我们需要让我们的类实现Serializable接口

public class People implements Serializable {
    public static void main(String[] args) {
        People people1 = new People();
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        try {
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
            objectOutputStream.writeObject(people1);

            ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
            ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
            People people2 = (People) objectInputStream.readObject();

            System.out.println(people1);
            System.out.println(people2);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

输出

People@14ae5a5
People@7f31245a
发布了66 篇原创文章 · 获赞 138 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/u013277209/article/details/102689454