java不通过构造函数创建对象(Unsafe)

java中不通过构造函数创建对象(也有说不创建对象直接执行成员方法)

这里就不和你们扯什么通过 反序列化、clone等方法了 个人觉得都是在胡扯。

如何不执行构造函数创建对象?

先来带大家认识一个类 sun.misc.Unsafe 该类主要提供一些直接访问系统内存资源等等(学过C语言的应该知道和C语言中的指针一样),但是由于此类能够直接操作内存,这无疑也增加了程序的安全风险。所以技术不是那么好的千万不要在应用中直接使用哟。

在这里插入图片描述

从上图可以看出 java是不允许直接创建该类对象的,但是我们可以看到第一个红框哪里明显有个Unsafe类的对象,该类是单例的。 那么怎么获取该类的实例呢?

在这里插入图片描述
注意:本版较低的jdk可能没有这个方法
有一个getUnsafe()方法,但是很不幸,该方法是提供给jdk内部使用的。我们直接调用该方法会抛异常的。具体原理就是该类会判断当前调用这个方法的类是不是由Bootstrap类加载器加载的。

那么如何获取这个Unsafe实例呢?有两种方法
一、让我们使用了Unsafe对象的类通过Bootstrap加载
二、熟悉反射的同学就会心头一冷笑,这还不简单吗?是的,我们可以直接通过反射获取

这里只讲通过反射获取的方式

获取Unsafe对象

		Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
        theUnsafe.setAccessible(true);
        Unsafe unsafe = (Unsafe) theUnsafe.get(null);

java基础好的同学,这段代码应再熟悉不过了

不执行构造函数创建对象?

Unsafe类中有一个 sun.misc.Unsafe#allocateInstance 方法, 接收一个Class<?> 类型对象,然后返回该类的一个对象

我们准备一个测试类

class Test{
    private String name;
    public Test(){
        System.out.println("test construct");
    }

}

该类构造方法私有,然后构造方法中打印了一句话,也就是,只要你创建一个新的对象就会打印这句话。

        Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
        theUnsafe.setAccessible(true);
        Unsafe unsafe = (Unsafe) theUnsafe.get(null);
        Test test = (Test) unsafe.allocateInstance(Test.class);

测试代码

上面这段代码是没有任何输出的,也就是没有执行构造方法,但是却返回了一个对象

因此也听有人说 压根就没有创建对象, 这我也不好说有没有创建对象,因为对于底层具体怎么实现的我也不造,但是我更倾向于是没有执行构造方法创建对象这种说法吧。

总结以及注意事项

通过这篇文章我们知道原来java中也提供了直接操作内存的类,而且该类还能不执行构造方法就返回一个对象,不过因此也有注意,Unsafe类是直接操作内存的,所以他所分配的内存jvm的垃圾收集器是无法释放的。该类操作的内存和C语言中一样,要手动释放。关于该类的更多使用方式可到网上找相关的资料

推荐阅读:

  • 14
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值