私有,公共,受保护的修饰符在Java中仍然是必不可少的吗?

时间:2017-07-14 06:40:18

标签: java oop reflection encapsulation

随着Reflection API的引入,我们现在可以随意访问任何私有字段。

例如:

Field f = obj.getClass().getDeclaredField("stuffIWant"); 

现在,如果我们消除所有修饰符并为Java开发人员设置一个不直接访问字段但通过getter / setter的通用规则会怎样?显然,人们可以违反规则,但即使我们有修饰符,我们仍然可以在不使用修饰符的情况下访问它们。

2 个答案:

答案 0 :(得分:2)

错误的心态。

您可以在运行时覆盖某些保护级别这一事实并不意味着您现在(或将来)突然想到或允许您编写错误的源代码)。

您不要使用这些关键字在运行时建立保证。这是一个理想的副作用,但不是这些关键字的真实点。你主要用它们表达意图!使您的源代码更好地为人类读者理解。 与使用反射在运行时可以执行的操作有关。

给出另一个例子:javac编译器会将你的源代码变成字节码;并且JVM实时编译器会在某些时候将java字节代码转换为机器代码。当我们遵循你的逻辑时 - 我们应该停止用Java编写程序,而是直接编写机器代码吗?你知道吗,因为在运行时,反正只会有机器代码? (我知道,不是最好的比较,它只是为了强调运行时功能与源代码内容无关)。

除此之外:还有一个安全管理器可能阻止您禁用此保护。

我希望您明白使用反射只能在非常特殊的角落情况下进行。反思是一种表演杀手;它使用起来非常麻烦,而且非常容易出错。当您其他选择时,使用Java的这些功能之一。您为“日常任务”选择的“常规”工具集中

最后:java 9引入的模块概念将不再允许您访问模块内的任何内容 - 只有公共导出的元素才可访问。对于反思来说也是如此。它有点复杂,并且有命令行开关来改变行为 - 但是很容易到达任何地方的时间基本上都是编号的。

答案 1 :(得分:0)

  

随着Reflection API的引入,我们现在可以随意访问任何私有字段。

仅仅因为有反射,并不意味着你可以访问它。

不,你不能。除非您在没有任何Security Manager (with defined secure policy)的情况下分发代码,否则可以执行这些不安全/较慢的操作。但是你仍然可以阻止他们这样做。

  

安全管理器是一个允许应用程序实现安全策略的类。它允许应用程序在执行可能不安全或敏感的操作之前确定操作是什么以及是否在允许执行操作的安全上下文中尝试操作。应用程序可以允许或禁止操作。

     

权限属于以下类别:文件,套接字,网络,安全性,运行时,属性,AWT,反映和可序列化。管理这些不同权限类别的类是java.io.FilePermission,java.net.SocketPermission,java.net.NetPermission,java.security.SecurityPermission,java.lang.RuntimePermission,java.util.PropertyPermission,java.awt.AWTPermission, java.lang.reflect.ReflectPermission和java.io.SerializablePermission。