既然Java反射可以访问和修改私有成员变量,那封装成private还有意义么?

作者:大宽宽
链接:https://www.zhihu.com/question/28161668/answer/518225224
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

简单来说,private并不是解决“安全”问题的。安全是指不让代码被非法看到/访问。但是只要人能拿到代码,总会有办法去查看和改变代码。其他答案提到反射可以用SecurityManager来防止private被访问。但是从更高一层的角度,即便使用了SecurityManager,还是可以通过各种方式拿到java的bytecode,并做任意修改。比如有asm这样的lib,也有instrument api这种东西可以帮你。所以记得,如果你真有一段代码不允许被别人看/用,就不要把这段代码放到其他人可以碰到的地方,而是做一个server,通过接口允许有限制的访问。其他人想破解,只能破解你的服务器网关和跳板机器。关于真正的安全性,可以参考激活服务器的工作原理private想表达的不是“安全性”的意思,而是OOP的封装概念,是一种编译器可以帮助你的设计上的hint。这就像是一家没人的店挂了个牌子“闲人免进”,但你真要进去还是有各种办法可以办到。所以private,以及所有其他的access modifier都有一层隐含的含义:如果你按照遵守这套规则,开发者可以保证不问题(不考虑bug的情况下);否则,后果自负。比如,你在用spring的IoC的时候,你知道你要“注入”,不管它是不是private的,你知道“注入”是你自己控制的,是你设计好的效果。那么通过spring的IoC利用反射帮你注入一些private property是再正常不过的用法。再比如,单元测试,你就想测一个private方法。但是因为private的缘故就是测不了。于是你可以用反射绕开这个限制,开心的做测试。虽说某些人坚持“不应该测试private方法,而应该通过测试其他方法间接测试private方法,但并没有形成广泛的共识。这里不对这个问题展开。虽然能绕开,但绕开的代码很繁琐。久而久之就会厌倦。毕竟,代码应该为你工作,而不是你为代码工作。因此,我的经验是通常会用protected或者default来代替private。我曾设想runtime应该给一种运行模式,通过设定一个启动参数使其不管private这类的限制,这样做UT,做profiling等工作都会轻松许多。等到最后发布时,再用普通模式。但可惜现实当中并没有这种设定。评论区提到了Android里的VisibleForTesting,可以实现我期望的功能。大赞!感谢 @尤华杰 我之所以敢用protected/default来代替private是因为现实当中非private不可的情景非常少见。实际上,很多时候private带来的麻烦比起带来的好处要多,这是因为很多时候对OOP的误用造成的。OOP的误用造成了无谓的private,然后逼着你必须得绕开private。其实private就是个约定而已。看看其他语言,比如python,它的“private“是一种很松散的约定,所有private的成员都用下划线开头,告诉调用者“不要随便调用我哦”,但是如果真调用了也就调用了。C++,通过指针就能绕开private。有人说,private会避免新手误用。但问题是,大家从出道开始,自己或者周围的同事朋友有谁曾经出过这个问题?IDE知道一个成员当前不能访问,就根本就不会提示。如果一个人已经开始通过源代码/反编译研究“我能不能调用这个私有方法了“,他还算是一个菜鸟吗?他会不知道这里的潜在风险吗?如果真的误用了,code review能过吗?测试能过吗?如果一个公司因为误用private成员,造成了重大的损失,那这个公司就活该倒闭算了,不要在世上丢人。OOP是一种编程思想,是众多编程思想中的一种。是开发者决定了一个问题应该用OOP合适,并且用了Java这样的语言来简化自己开发OOP代码时的工作。如果抱着这种态度,就不会误用,因为private在开发者的心中。其他人也不太可能误用,如果他上过几天java培训。不要因为语言是OOP的就去套,把不适合的OOP的代码强用OOP的各种套路实现,然后给自己后续的维护扩展埋坑。

作者:金自翔
链接:https://www.zhihu.com/question/28161668/answer/515906087
来源:知乎
妹子穿超短裙时里面会穿个安全裤。超短裙是public,妹子露出来就随便你看。安全裤是private,妹子认为正常人不应该往里看。其实安全裤也能硬扒下来(reflect),但如果你在街上随便扒女孩裤子,被警察抓你也没啥可说的是不是。“既然安全裤能被硬扒下来,那妹子穿安全裤还有意义么?”

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值