反射是否破坏了私有方法的思想,因为私有方法可以在类之外访问?

Yos*_*sef 28 php c# java reflection junit

反思是否打破了私人方法的想法?因为可以从类外部访问私有方法吗?(也许我不理解反思的意思或错过别的东西,请告诉我) http://en.wikipedia.org/wiki/Reflection_%28computer_science%29

编辑: 如果relection打破了私有方法的想法 - 我们是否只将私有方法用于程序逻辑而不用于程序安全?

谢谢

Eri*_*ert 27

我们是否仅将私有方法用于程序逻辑而不用于程序安全性?

目前尚不清楚"程序安全"的含义.安全无法在真空中讨论; 您在考虑哪些资源来防范哪些威胁?

CLR代码访问安全系统旨在保护用户数据资源免受在用户机器上运行恶意部分可信代码的威胁.

因此,CLR中的反射,访问控制和安全性之间的关系是复杂的.简单而不完全准确,规则如下:

  • 完全信任意味着完全信任.完全受信任的代码可以访问进程中的每一位内存.这包括私人领域.

  • 在部分信任中反映私有部分的能力由许可控制; 如果没有批准,那么部分信任代码可能不会对私有进行反思.

有关详细信息,请参见http://blogs.msdn.com/b/shawnfa/archive/2006/09/29/777047.aspx.

  • 桌面CLR支持称为"受限跳过可见性"的模式,其中反射和安全系统交互的规则略有不同.基本上,如果部分受信任的代码从具有相同较少信任的程序集的类型访问私有字段,则具有使用私有反射权的部分受信任的代码可以通过反射访问私有字段.

看到

http://blogs.msdn.com/b/shawnfa/archive/2006/10/05/using-lightweight-codegen-from-partial-trust.aspx

详情

执行摘要是:您可以充分锁定部分受信任的代码,使其无法使用反射来查看私有内容.您无法锁定完整的信任代码; 这就是为什么它被称为"完全信任".如果你想限制它,那就不要相信它.

那么:将字段私有化是否会保护它免受低信任代码试图读取它的威胁,从而窃取用户的数据?是的.它是否保护它免受高信任代码读取它的威胁?.如果代码既受用户信任又对用户不利,那么用户就会遇到大问题.他们不应该信任该代码.

请注意,例如,将字段设为私有不会保护代码中的密码不会受到拥有代码且对您有敌意的用户的影响.安全系统保护好用户免受恶意代码的侵害.它不保护好代码邪恶的用户.如果你想私下制作一些东西以保护用户,那么你就是傻瓜的差事.如果你想让它变得私密,以防止那些诱使用户运行恶意低信任代码的邪恶黑客,那么这是一个很好的技巧.


Ten*_*she 19

Reflection确实提供了绕过Java的访问保护修饰符的方法,因此违反了在C++和Java中实现的严格封装.然而,这并不像你想象的那么重要.

访问保护修改器旨在帮助程序员开发模块化的良好分解系统,而不是不妥协的门卫.有时候有很好的理由打破严格的封装,例如单元测试和框架开发.

尽管最初可能很难理解访问保护修饰符很容易被绕过,但请记住,有许多语言(Python,Ruby等)根本没有它们.这些语言用于构建大型复杂系统,就像提供访问保护的语言一样.

关于访问保护修饰符是一种帮助还是一种障碍,存在一些争论.即使您确实重视访问保护,也可以将其视为助手,而不是制作或破坏您的项目.

  • 反射确实提供了绕过Java的访问保护修饰符的方法,因此强制封装 (2认同)

Hen*_*man 13

是的,但这不是问题.

封装不是关于安全性或秘密,而是关于组织事物.

反思不是"正常"编程的一部分.如果你想用它来打破封装,你接受风险(版本问题等)

只有在没有更好(较少侵入性)的方法来完成某些事情时,才应该使用反思.

反思是系统级的"工具",如持久性映射,应该隐藏在经过良好测试的库中.我会发现在正常的应用程序代码中使用反射可疑.

我开始说"这不是问题".我的意思是:只要您按预期使用反射.小心点.

  • "封装不是关于安全性"的+1 (2认同)

cor*_*iKa 8

这就像你的房子.锁只能阻止诚实的人,或者不愿意选择锁的人.

数据是数据,如果有人确定,他们可以对您的代码做任何事情.直译任何东西.

所以,是的,反射将允许人们做你不希望他们用你的代码做的事情,例如访问私有字段和方法.然而,重要的是人们不会意外地这样做.如果他们正在使用反射,他们知道他们正在做他们可能不打算做的事情,就像没有人不小心拿到你前门上的锁一样.


Jör*_*tag 8

不,反思并没有打破私人方法的想法.至少本身不是.没有任何东西可以说反思不能遵守访问限制.

设计糟糕的反射破坏了私有方法的思想,但这与反射本身没有任何关系:任何设计糟糕的东西都可能破坏私有方法的概念.特别是,私有方法的糟糕设计也可能明显打破私有方法的想法.

设计糟糕是什么意思?好吧,正如我上面所说,没有什么可以阻止你使用一种语言,其中反射服从访问限制.问题在于,例如调试器,分析器,覆盖工具,IntelliSense,IDE,工具通常需要能够违反访问限制.由于没有办法向不同的客户提供不同版本的反射,大多数语言选择安全工具.(E是反例,它绝对没有任何反射能力,作为有意识的设计选择.)

但是,谁说你不能向不同的客户展示不同版本的反思?嗯,问题很简单,在反射的经典实现中,所有对象都可以反映自己,并且因为每个对象只有一个,所以只能有反射版本.

那么,糟糕设计的想法会在哪里出现?那么,请注意上段中的"负责"一词.每个对象都有责任自我反思.此外,每个对象都要对它首先编写的内容负责.换句话说:每个对象至少有两个职责.这违反了面向对象设计的基本原则之一:单一责任原则.

解决方案相当简单:分解对象.原始对象只负责它最初编写的内容.还有另一个对象(称为Mirror,因为它是一个反映其他对象的对象),它负责反射.现在,反思的责任被分解为一个单独的对象,是什么阻止我们从一个,而不是两个,三个,许多镜像对象?尊重访问限制的访问限制,只允许对象反映自身但不反映任何其他对象,只允许内省(即只读),只允许反映只读的呼叫站点信息(即分析器),提供对整个系统的完全访问权限,包括违反访问限制(对于调试器),只提供对方法名称和签名的只读访问权限并且遵守访问限制(对于IntelliSense)等等...

作为一个很好的奖励,这意味着镜子本质上是反射的能力(在能力安全意义上).IOW:在长达十年的调和安全性和运行时动态元编程的过程中,镜子是圣杯.

Mirrors的概念最初是在Self中发明的,从而将其转移到Animorphic Smalltalk/Strongtalk,然后是Newspeak.有趣的是,Java调试接口基于Mirrors,因此Java(或者更确切地说是JVM)的设计者清楚地了解它们,但是Java的反思被打破了.


Ale*_*x F 5

是的,反思打破了这个想法。本机语言也有一些打破 OOP 规则的技巧,例如,在 C++ 中可以使用指针技巧来更改私有类成员。然而,通过使用这些技巧,我们得到的代码可能与未来的类版本不兼容——这就是我们为违反 OOP 规则而付出的代价。


xor*_*_eq 5

正如其他已经说过的那样.

但是,我记得在Java中可以有一个活动的安全管理器,如果你没有这样做的权限,它可能会阻止你访问任何私有方法,即使是使用反射.如果运行本地JVM,则此类管理器通常不处于活动状态.