你知道几种实例化一个类的方式?
new? 反射? 还有呢?
笔者总结了一下大概有以下六种方式:
(1) 通过构造方法实例化一个类;
(2) 通过 Class 实例化一个类;
(3) 通过反射实例化一个类;
(4) 通过克隆实例化一个类;
(5) 通过反序列化实例化一个类;
(6) 通过 Unsafe 实例化一个类;
Let us 直接上代码:
- 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. 构造方法
- User user1 = new User();
- // 2. Class, 里面实际也是反射
- User user2 = User.class.newInstance();
- // 3. 反射
- User user3 = User.class.getConstructor().newInstance();
- // 4. 克隆
- User user4 = (User) user1.clone();
- // 5. 反序列化
- 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"));
- // 反序列化
- 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();
- }
- }
- }
先不要急着往下看, 你猜猜上面六种方式打印语句输出各是多少?
不要看!
不要看!
不要看!
最后打印的结果是这样:
10 10 10 10 10 0
意不意外? 惊不惊喜?
最后一种通过 Unsafe 实例化的类, 里面的 age 的值竟然是 0, 而不是 10 或者 20.
这是因为调用 Unsafe 的 allocateInstance() 方法只会给对象分配内存, 并不会初始化对象中的属性, 所以 int 类型的默认值就是 0.
还有其它方式实例化类吗? 欢迎补充!
来源: http://www.bubuko.com/infodetail-3050509.html