有什么方法能够阻止反射对单例模式对破坏 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
hHarvey
V2EX    程序员

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

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

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

    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     Solana     3875 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 32ms UTC 10:15 PVG 18:15 LAX 03:15 JFK 06:15
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86