实例化几种方式_杂谈 论实例化类的第六种方式

88efe4f56c663085ac59ce05c4042ab1.png

你知道几种实例化一个类的方式?

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(); } }}

先不要急着往下看,你猜猜上面六种方式打印语句输出各是多少?

不要看!

不要看!

不要看!

最后打印的结果是这样:

10101010100

意不意外?惊不惊喜?

最后一种通过Unsafe实例化的类,里面的age的值竟然是0,而不是10或者20。

这是因为调用Unsafe的allocateInstance()方法只会给对象分配内存,并不会初始化对象中的属性,所以int类型的默认值就是0。

还有其它方式实例化类吗?欢迎补充!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C++ 中实例化对象的方式有以下几种: 1. 直接赋值初始化:使用默认构造函数直接初始化对象。 ```c++ MyClass obj; // 使用默认构造函数初始化 ``` 2. 调用构造函数:使用自定义的构造函数初始化对象。 ```c++ MyClass obj(10); // 调用构造函数,初始化对象 ``` 3. 拷贝构造函数:使用已有的对象来初始化新的对象。 ```c++ MyClass obj1(10); // 调用构造函数,初始化对象 MyClass obj2(obj1); // 使用 obj1 的值来初始化 obj2 ``` 4. 赋值构造函数:使用等号(=)来初始化对象。 ```c++ MyClass obj1(10); // 调用构造函数,初始化对象 MyClass obj2 = obj1; // 使用 obj1 的值来初始化 obj2 ``` 5. new 运算符:使用 new 运算符来动态分配内存并初始化对象。 ```c++ MyClass *ptr = new MyClass(10); ``` 6. 模板:使用模板来创建对象。 ```c++ template <typename T> class MyClass { // ... }; MyClass<int> obj(10); // 创建 int 型的 MyClass 对象 ``` 这些方式的区别主要在于对象的初始化方式和内存分配方式。其中,前四种方式都是静态分配内存,即在编译期间就分配好了内存空间,而后两种方式是动态分配内存,即在运行时根据需要动态分配内存空间。 模板的方式是通过定义一个具有通用性的模板,使得可以根据具体的型来生成不同的。在创建对象时,需要指定模板参数型,这样编译器就可以根据指定的型生成相应的。例如,MyClass<int> 表示使用 int 型来实例化 MyClass 模板,编译器会根据 MyClass<int> 型生成一个 int 型的 MyClass 模板的方式可以在多种数据型之间重用代码,提高代码的可重用性和扩展性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值