java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > java不通过构造函数创建对象

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

作者:子♂衿

这篇文章主要介绍了java如何不通过构造函数创建对象(Unsafe)问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

java中不通过构造函数创建对象

(也有说不创建对象直接执行成员方法)

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

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

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

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

注意:本版较低的jdk可能没有这个方法

有一个getUnsafe()方法,但是很不幸,该方法是提供给jdk内部使用的。我们直接调用该方法会抛异常的。

具体原理就是该类会判断当前调用这个方法的类是不是由Bootstrap类加载器加载的。

那么如何获取这个Unsafe实例呢?

有两种方法

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

获取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语言中一样,要手动释放。

关于该类的更多使用方式可到网上找相关的资料

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文