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

 更新时间:2024年03月25日 10:26:40   作者:子♂衿  
这篇文章主要介绍了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语言中一样,要手动释放。

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

总结

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

相关文章

  • JDBC连接MySQL并实现模糊查询

    JDBC连接MySQL并实现模糊查询

    本文详细讲解了JDBC连接MySQL并实现模糊查询的方式,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-01-01
  • 在 Spring Boot 3 中接入生成式 AI的操作方法

    在 Spring Boot 3 中接入生成式 AI的操作方法

    本文介绍了如何在SpringBoot3中集成生成式AI,以OpenAI的GPT模型为例,通过代码示例展示了如何实现,SpringBoot3的优势和OpenAI的生成式AI技术结合,为开发者提供了高效集成生成式AI的方法,感兴趣的朋友跟随小编一起看看吧
    2025-01-01
  • springboot 实现mqtt物联网的示例代码

    springboot 实现mqtt物联网的示例代码

    这篇文章主要介绍了springboot 实现mqtt物联网,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-03-03
  • Java实现动态生成GIF图像详解

    Java实现动态生成GIF图像详解

    在互联网上有许多有趣的场景,其中的一种就是动图。这不是视频,而是一种GIF图像信息。本文将利用Java实现动态生成GIF图像功能,需要的可以参考一下
    2022-09-09
  • SpringCloud微服务熔断器Hystrix使用详解

    SpringCloud微服务熔断器Hystrix使用详解

    这篇文章主要介绍了Spring Cloud Hyxtrix的基本使用,它是Spring Cloud中集成的一个组件,在整个生态中主要为我们提供服务隔离,服务熔断,服务降级功能,本文给大家介绍的非常详细,需要的朋友可以参考下
    2022-07-07
  • springcloud整合gateway实现网关全局过滤器功能

    springcloud整合gateway实现网关全局过滤器功能

    本文主要介绍了springcloud整合gateway实现网关全局过滤器功能,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02
  • java实现短信验证码5分钟有效时间

    java实现短信验证码5分钟有效时间

    这篇文章主要为大家详细介绍了java实现短信验证码5分钟有效时间,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-07-07
  • Spring AOP如何实现注解式的Mybatis多数据源切换详解

    Spring AOP如何实现注解式的Mybatis多数据源切换详解

    这篇文章主要给大家介绍了关于Spring AOP如何实现注解式的Mybatis多数据源切换的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11
  • SpringMVC拦截器快速掌握下篇

    SpringMVC拦截器快速掌握下篇

    拦截器(Interceptor)是一种动态拦截方法调用的机制,在SpringMVC中动态拦截控制器方法的执行。本文将详细讲讲SpringMVC中拦截器的概念及入门案例,感兴趣的可以尝试一下
    2022-08-08
  • mybatis如何获取刚刚新插入数据的主键值id

    mybatis如何获取刚刚新插入数据的主键值id

    这篇文章主要介绍了mybatis如何获取刚刚新插入数据的主键值id问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08

最新评论