快捷搜索: 王者荣耀 脱发

Java创建对象的4种方式

1. 四种方式

new 反射 Clone 反序列化

1.1 new

最常见的创建对象的方式,通过这种方式我们还可以调用任意的构造器(无参的和有参的)

public class Main {
          
   
    public static void main(String[] args) {
          
   
        Person person1 = new Person();
        Person person2 = new Person("fsx", 18);
    }
}

1.2 反射

Class.newInstance 这是我们运用反射创建对象时最常用的方法。Class类的newInstance使用的是类的public的无参构造器。因此也就是说使用此方法创建对象的前提是必须有public的无参构造器才行,否则报错。

public class Main {
          
   
    public static void main(String[] args) throws Exception {
          
   
        Person person = Person.class.newInstance();
        System.out.println(person); // Person{name=null, age=null}
    }
}

Constructor.newInstance 本方法和Class类的newInstance方法很像,但是比它强大很多。 java.lang.relect.Constructor类里也有一个newInstance方法可以创建对象。我们可以通过这个newInstance方法调用有参数(不再必须是无参)的和私有的构造函数(不再必须是public)。

public class Main {
          
   
    public static void main(String[] args) throws Exception {
          
   
        // 包括public的和非public的,当然也包括private的
        Constructor<?>[] declaredConstructors = Person.class.getDeclaredConstructors();
        // 只返回public的~~~~~~(返回结果是上面的子集)
        Constructor<?>[] constructors = Person.class.getConstructors();

        Constructor<?> noArgsConstructor = declaredConstructors[0];
        Constructor<?> haveArgsConstructor = declaredConstructors[1];

        noArgsConstructor.setAccessible(true); // 非public的构造必须设置true才能用于创建实例
        Object person1 = noArgsConstructor.newInstance();
        Object person2 = declaredConstructors[1].newInstance("fsx", 18);
        System.out.println(person1);
        System.out.println(person2);
    }
}

1.3 clone

调用一个对象的clone方法,JVM就会创建一个新的对象,将前面的对象的内容全部拷贝进去,用clone方法创建对象并不会调用任何构造函数。 要使用clone方法,我们必须先实现Cloneable接口并复写Object的clone方法。

public class Person implements Cloneable {
          
   
	...
	// 访问权限写为public,并且返回值写为person
    @Override
    public Person clone() throws CloneNotSupportedException {
          
   
        return (Person) super.clone();
    }
    ...
}

public class Main {
          
   

    public static void main(String[] args) throws Exception {
          
   
        Person person = new Person("fsx", 18);
        Object clone = person.clone();

        System.out.println(person);
        System.out.println(clone);
        System.out.println(person == clone); //false
    }
}

这种复制称为浅复制,如果需要clone完成深复制则需要在Son也实现Cloneable接口和重写clone方法。

1.4 反序列化

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

public class Main {
          
   

    public static void main(String[] args) throws Exception {
          
   
        Person person = new Person("fsx", 18);
        byte[] bytes = SerializationUtils.serialize(person);

        // 字节数组:可以来自网络、可以来自文件(本处直接本地模拟)
        Object deserPerson = SerializationUtils.deserialize(bytes);
        System.out.println(person);
        System.out.println(deserPerson);
        System.out.println(person == deserPerson);
    }
}

2 对比

Java创建实例对象,并不一定必须要调用构造器的。 创建对象方式 是否调用了构造器 new关键字 是 Class.newInstance 是 Constructor.newInstance 是 Clone 否 反序列化 否

经验分享 程序员 微信小程序 职场和发展