The sixth way to instantiate classes

Posted by steply on Fri, 08 Nov 2019 22:36:41 +0100

How many ways do you know to instantiate a class?

new? Reflection? And?

The author summarizes the following six ways:

(1) instantiate a class by constructing a method;

(2) instantiate a Class through Class;

(3) instantiate a class by reflection;

(4) instantiate a class by cloning;

(5) instantiate a class through deserialization;

(6) instantiate a class through Unsafe;

Let us direct code:

public class InstantialTest {

    private static Unsafe unsafe;
    static {
        try {
            Field f = Unsafe.class.getDeclaredField("theUnsafe");
            f.setAccessible(true);
            unsafe = (Unsafe) f.get(null);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
    
    public static void main(String[] args) throws Exception {
        // 1. Construction method
        User user1 = new User();
        // 2. Class, which is actually reflection
        User user2 = User.class.newInstance();
        // 3. reflection
        User user3 = User.class.getConstructor().newInstance();
        // 4. cloning
        User user4 = (User) user1.clone();
        // 5. Deserialization
        User user5 = unserialize(user1);
        // 6. Unsafe
        User user6 = (User) unsafe.allocateInstance(User.class);

        System.out.println(user1.age);
        System.out.println(user2.age);
        System.out.println(user3.age);
        System.out.println(user4.age);
        System.out.println(user5.age);
        System.out.println(user6.age);
    }

    private static User unserialize(User user1) throws Exception {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D://object.txt"));
        oos.writeObject(user1);
        oos.close();

        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D://object.txt"));
        // De serialization
        User user5 = (User) ois.readObject();
        ois.close();
        return user5;
    }

    static class User implements Cloneable, Serializable {
        private int age = 20;

        public User() {
            this.age = 10;
        }

        @Override
        protected Object clone() throws CloneNotSupportedException {
            return super.clone();
        }
    }
}

Don't worry about looking down. Guess how many of the above six ways of printing statements are output?

Don't look!

Don't look!

Don't look!

The final result is as follows:

10
10
10
10
10
0

Did it happen? Surprise or not?

In the last class instantiated through Unsafe, the value of age in it is 0 instead of 10 or 20.

This is because calling the allocateInstance() method of Unsafe only allocates memory to the object and does not initialize the properties in the object, so the default value of int type is 0.

Is there any other way to instantiate a class? Welcome to add!

Topics: Programming