Please go to DobbyKim’s Question of the Day for more questions

A:

There are four common ways to create objects:

  1. Use the new keyword
  2. reflection
  3. Use the clone() method
  4. Serialization and deserialization
1. Use the new keyword to create an object
public class Person {
    
    private String name;
    private int age;

    public Person(a) {
        this.name = "default";
        this.age = 0;
    }

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

    public void info(a) {
        System.out.println("My name is " + name + ", I'm " + age + "years old.");
    }

    public static void main(String[] args) {
        Person p1 = new Person("Jack".30); p1.info(); }}Copy the code

Program output result:

My name is Jack, I'm 30 years old.
Copy the code
2. Use reflection to create objects

Using reflection to create objects can also be specifically divided into:

  1. Use the Class newInstance method
  2. Use the Constructor class’s newInstance method
Create objects using the Class newInstance method

This method calls the no-parameter constructor to create the object

public class Person {
    private String name;
    private int age;

    public Person(a) {
        this.name = "default";
        this.age = 0;
    }

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

    public void info(a) {
        System.out.println("My name is " + name + ", I'm " + age + " years old.");
    }

    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
		// copy reference
        Person p2 = (Person)Class.forName("test.Person").newInstance(); Person p3 = Person.class.newInstance(); p2.info(); p3.info(); }}Copy the code

Program output result:

My name is default, I'm 0 years old.
My name is default, I'm 0 years old.
Copy the code
Create objects using the newInstance method of the Constructor class

And Class Class newInstance method like Java. Lang. Reflect. The Constructor in the Class has a newInstance method can create the object. We can use this newInstance method to call both parametered and private constructors.

import java.lang.reflect.InvocationTargetException;

public class Person {
    private String name;
    private Integer age;

    public Person(a) {
        this.name = "default";
        this.age = 18;
    }

    public Person(String name){
        this(name,18);
    }
	// Private constructor
    private Person(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public void info(a) {
        System.out.println("My name is " + name + ", I'm " + age + " years old.");
    }

    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {

        Person p4 = (Person) Class.forName("test.Person").getConstructor(String.class).newInstance("Tracy");
        p4.info();

        Person p5 = (Person) Class.forName("test.Person").getDeclaredConstructor(String.class,Integer.class).newInstance("James".25); p5.info(); }}Copy the code

Program running results:

My name is Tracy, I'm 18 years old.
My name is James, I'm 25 years old.
Copy the code
3. Use the clone() method to create an object

The following points need to be noted about the Clone () method:

  1. A class, you need to implement the Cloneable interface to invoke the Object’s clone () method, or you will quote CloneNotSupportedException
  2. The clone() method does not call the constructor of the copied instance
  3. The Clone () method is actually a shallow copy, as mentioned in * Core Java * : You should avoid using the Clone () method altogether and use other methods for copying, such as factory mode, serialization, etc.

Let’s look at the procedure:

public class Person implements Cloneable {
    private int age;
    private String name;

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

    public int getAge(a){
        return this.age;
    }
    public String getName(a){
        return this.name;
    }

    @Override
    public Object clone(a){
        Person p = null;
        try {
            p = (Person) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return p;
    }

    public static void main(String[] args) {
        Person p1 = new Person(26."kim");
        Person p2 = (Person)p1.clone();
        System.out.println(p1.getName() == p2.getName() ? "shallow copy" : "deep copy"); }}Copy the code

The results of the program are as follows:

shallow  copy
Copy the code

Let’s take a look at the p1 object and P2 object memory allocation schematic diagram:

As you can see from this figure, the clone() method is just field-to-field-copy, whereas a true deep copy would look like this:

public class Person implements Cloneable {
    private int age;
    private String name;

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

    public int getAge(a) {
        return this.age;
    }

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

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


    @Override
    public Object clone(a) {
        Person p = null;
        try {
            p = (Person) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return p;
    }

    public static void main(String[] args) {
        Person p1 = new Person(26."kim");
        // shallow copy
        Person p2 = (Person) p1.clone();
        // deep copy
        Person p3 = new Person();
        String name = new String("kim");
        int age = 26;
        p3.setAge(age);
        p3.setName(name);
        System.out.println(p1.getName() == p2.getName() ? "shallow copy" : "deep copy");
        System.out.println(p1.getName() == p3.getName() ? "shallow copy" : "deep copy"); }}Copy the code

Program output result:

shallow  copy
deep copy
Copy the code

Let’s take a look at the memory allocation diagram of P1 and P3:

From the comparison of the two figures above, we can also see that the fundamental difference between shallow copy and deep copy is that the deep copy is a copy of an object, not a reference.

Here’s an example:

Let’s say B is A copy of A

If B changes as we modify A, it is A shallow copy, indicating that we are modifying the same value in heap memory.

If B does not change when we modify A, then it is A deep copy, which means we are modifying A different value in the heap

4. Create objects using serialization and deserialization

Serialization refers to streaming objects to disk;

Deserialization converts object information from disk to memory

With serialization, we first implement the Serializable interface. If the class of the object we want to serialize does not implement the Serializable interface, then we throw a NotSerializableException; Second requirements:

  1. All properties in an object must be serialized to be serialized. Static variables cannot be serialized
  2. If an attribute does not want to be serialized, you can add the TRANSIENT keyword to the attribute

Examples of the program are as follows:

serialization
import java.io.*;

public class Person implements Serializable {
    private int age;
    private String name;

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

    public int getAge(a) {
        return age;
    }

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

    public String getName(a) {
        return name;
    }

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

    public void info(a) {
        System.out.println("My name is " + name + ", I'm " + age + " years old.");
    }

    public static void main(String[] args) throws IOException {
        File file = new File("src\\test\\file.txt");
        ObjectOutputStream o = new ObjectOutputStream(new FileOutputStream(file));
        Person p = new Person(30."Jack"); o.writeObject(p); }}Copy the code
deserialization
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

public class Test {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        File file = new File("src\\test\\file.txt");
        ObjectInputStream o = new ObjectInputStream(newFileInputStream(file)); Person p = (Person) o.readObject(); p.info(); }}Copy the code

Program output result:

My name is Jack, I'm 30 years old.
Copy the code

Serialization and deserialization create objects without calling the class constructor, and the nature of serialization deserialization create objects is deep copy.