V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
hHarvey
V2EX  ›  程序员

有什么方法能够阻止反射对单例模式对破坏

  •  
  •   hHarvey · 2019-11-08 10:10:19 +08:00 · 2906 次点击
    这是一个创建于 1834 天前的主题,其中的信息可能已经有所发展或是发生改变。

    判断成员变量的话,反射也能修改这个变量的值啊。。

    12 条回复    2019-11-08 17:29:10 +08:00
    HongJay
        1
    HongJay  
       2019-11-08 10:11:50 +08:00   ❤️ 1
    ```
    十、枚举

    public enum Singleton {
    INSTANCE
    }

    枚举类单例模式是《 Effective Java 》作者 Josh Bloch 极力推荐的单例方法

    借助 JDK 1.5 中添加的枚举来实现单例模式。P.S. Enum 是没有 clone()方法的

    1. 枚举类类型是 final 的「不可以被继承」
    2. 构造方法是私有的「也只能私有,不允许被外部实例化,符合单例」
    3. 类变量是静态的
    4. 没有延时初始化,随着类的初始化就初始化了「从上面静态代码块中可以看出」
    5. 由 4 可以知道枚举也是线程安全的

    优点:写法简单,不仅能避免多线程同步问题,而且还能防止反序列化、反射、克隆重新创建新的对象。
    缺点:JDK 1.5 之后才能使用。
    ```
    softtwilight
        2
    softtwilight  
       2019-11-08 10:19:16 +08:00
    1 楼正解,不过有一个疑问,有必要防止反射创建单例吗,哪些场景有用?
    wysnylc
        3
    wysnylc  
       2019-11-08 10:25:50 +08:00
    枚举写单例只有一个坏处,麻烦
    hHarvey
        4
    hHarvey  
    OP
       2019-11-08 10:40:19 +08:00
    @HongJay 嗯嗯,之前没清楚枚举写单例的意思,自己枚举里又维护了一个类
    lihongming
        5
    lihongming  
       2019-11-08 10:44:26 +08:00 via iPhone
    设计模式本是用于解决一类问题的通用方法,可这么搞就成了利用某一特定语言的特性(有时甚至是 BUG )来强行实现,违背了设计模式的本意。

    另外用反射来破坏你模式的那些人,肯定是有特殊需要的,有必要封那么死么?只要防止被人非本意的破坏就好。
    Mutoo
        6
    Mutoo  
       2019-11-08 10:52:19 +08:00   ❤️ 2
    设计模式是一种设计共识,不是一种防御手段。
    hHarvey
        7
    hHarvey  
    OP
       2019-11-08 11:05:40 +08:00
    但是用枚举实现单例,这个单例的属性值并不能序列化啊
    momocraft
        8
    momocraft  
       2019-11-08 11:10:36 +08:00
    在 constructor 执行时 如果已有 instance 就 java.lang.System.exit(1)

    然后等人提 bug
    Raymon111111
        9
    Raymon111111  
       2019-11-08 11:36:06 +08:00
    用枚举

    官方推荐
    loshine1992
        10
    loshine1992  
       2019-11-08 11:44:46 +08:00
    @lihongming

    设计模式是总结出来的最佳实践

    Java 里用枚举实现单例就是绝大多数情况下最佳实践
    ysweics
        11
    ysweics  
       2019-11-08 13:02:09 +08:00
    如果没有开始写,那就用枚举实现,如果已经是老项目里面,可以在构造方法里面加上限制,方案就是 8 楼给出的方案,当然既然有反射破坏,那你反序列破坏也要考虑到
    cco
        12
    cco  
       2019-11-08 17:29:10 +08:00
    想想谁没事去破坏你的单例?了解其思想即可,想那么多干嘛
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2827 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 32ms · UTC 11:32 · PVG 19:32 · LAX 03:32 · JFK 06:32
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.