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

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

  •  
  •   hHarvey · 33 天前 · 1318 次点击
    这是一个创建于 33 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

    12 回复  |  直到 2019-11-08 17:29:10 +08:00
        1
    HongJay   33 天前   ♥ 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 之后才能使用。
    ```
        2
    softtwilight   33 天前
    1 楼正解,不过有一个疑问,有必要防止反射创建单例吗,哪些场景有用?
        3
    wysnylc   33 天前
    枚举写单例只有一个坏处,麻烦
        4
    hHarvey   33 天前
    @HongJay 嗯嗯,之前没清楚枚举写单例的意思,自己枚举里又维护了一个类
        5
    lihongming   33 天前 via iPhone
    设计模式本是用于解决一类问题的通用方法,可这么搞就成了利用某一特定语言的特性(有时甚至是 BUG )来强行实现,违背了设计模式的本意。

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

    然后等人提 bug
        9
    Raymon111111   33 天前
    用枚举

    官方推荐
        10
    loshine1992   33 天前
    @lihongming

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

    Java 里用枚举实现单例就是绝大多数情况下最佳实践
        11
    ysweics   33 天前
    如果没有开始写,那就用枚举实现,如果已经是老项目里面,可以在构造方法里面加上限制,方案就是 8 楼给出的方案,当然既然有反射破坏,那你反序列破坏也要考虑到
        12
    cco   33 天前
    想想谁没事去破坏你的单例?了解其思想即可,想那么多干嘛
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   2617 人在线   最高记录 5043   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 24ms · UTC 13:48 · PVG 21:48 · LAX 05:48 · JFK 08:48
    ♥ Do have faith in what you're doing.