Reflection vs Encapsulation – Stand Off in the Java Module System(1)

Reflection vs Encapsulation – Stand Off in the Java Module System

反射vs封装—Java模块化系统下的对质

  

  Historically reflection could be used to break into any code that ran in the same JVM. With Java 9 this is going to change. One of the two main goals of the new module system is strong encapsulation; giving modules a safe space into which no code can intrude. These two techniques are clearly at odds so how can this stand off be resolved? After considerable discussions it looks like the recent proposal of open modules would show a way out.
  If you’re all down with the module system and what reflection does, you can skip the following back story and jump right into the stand off.

  过去,反射功能可以破坏任何运行在同一JVM中的代码的封装。随着Java 9的来临,这一现状将被改变。新模块化系统有两个主要目标,其中之一就是强封装,给各个模块一个安全的,无法入侵的运行空间。这两种技术是如此的的水火难容,那么如何解决这个问题呢?经过相当多的讨论之后,最近提出的开放化模块系统也许会是一个方向。
  如果你已经全部了解的模块化系统的概念和反射的功能,那么你可以直接跳过后面的故事,直接进入章节:对质。


Setting the Scene

设置场景

  Let me set the scene of how the module system implements strong encapsulation and how that clashes with reflection.

 让我来设置一些场景,解释关于模块化系统如何实现的强封装,以及如何与反射相矛盾。


Module Crash Course

模块速成

  The Java Platform Module Saloon (JPMS) is introducing the concept of modules, which in the end are just regular JARs with a module descriptor. The descriptor is compiled from a module-info.java file that defines a module’s name, its dependencies on other modules, and the packages it makes available:

  Java平台模块化平台 (JPMS)介绍了“模块”的概念, 这种“模块”最后也只是一个带着模块描述的JAR包. 这个描述是从module-info.java这个文件编译而来,文件里面定义了模块的名字,模块依赖的其他模块,以及模块提供的可用包:

module some.module {

    requires some.other.module;
    requires yet.another.module;

    exports some.module.package;
    exports some.module.other.package;

}

  In the context of encapsulation there are two points to take note of:

  • Only public types, methods, and fields in exported packages are accessible.
  • They are only accessible to modules that require the exporting module.

  Here, “being accessible” means that code can be compiled against such elements and that the JVM will allow accessing them at run time. So if code in module a user depends on code in a module owner, all we need to do to make that work is have user require owner and have owner export the packages containing the required types

  在封装的代码上下文中有两点值得注意:

  • 在要导出(exports)的包中,只有声明为public的类型,方法和字段可以访问.
  • 这些导出(exports)的包,只会被在依赖(requires)他们的模块访问.

  在这里,“允许访问”意味着可以针对包括的元素进行编译并且JVM可以在运行时访问它们. 所以,如果我们有一个模块 user 依赖模块 owner, 需要我们做的只是在 user 模块中依赖(require) owner 和在 owner 模块中导出(export) 包含着user模块依赖的类型的包:

module user {
    requires owner;
}

module owner {
    exports owner.api.package;
}

  This is the common case and apart from making the dependencies and API explicit and known to the module system all works as we’re used to.

  除了写依赖和显示API,在这些我们之前使用的已知模块化系统中,这些都是很常见的情况。


  So far everybody’s having fun! Then, in comes Reflection… conversations halt mid-sentence, the piano player stops his tune.

  目前为止,大伙都很开心,然后,反射登场… 从人声鼎沸到万籁俱寂。


Reflection

反射
  Before Java 9, reflection was allowed to break into any code. Aside from some pesky calls to setAccessible every type, method, or field in any class could be made available, could be called, could be changed – hell, even final fields were not safe!
  在Java 9之前, 反射可以破坏任意代码的封装性. 除了对 setAccessible有些烦人的调用外,任何类中的每个类型,方法,字段都可以使用,都可以调用,都可以改变 ——甚至定义为final的字段都TMD的变得不安全!

Integer two = 2;

Field value = Integer.class.getDeclaredField("value");
value.setAccessible(true);
value.set(two, 3);

if (1 + 1 != two)
    System.out.println("Math died!");
  This power drives all kinds of frameworks – starting with JPA providers like Hibernate, coming by testing libraries like JUnit and TestNG, to dependency injectors like Guice, and ending with obsessed class path scanners like Spring – which reflect over our application or test code to work their magic. On the other side we have libraries that need something from the JDK that it would rather not expose (did anybody say sun.misc.Unsafe?). Here as well, reflection was the answer.
  这种技术被使用到各种框架中 – 从JPA实现的提供者(例如:hibernate), 到测试库(例如:JUnit 和 TestNG), 再到依赖注入工具(例如:Guice), 最后到类的路径扫描工具(例如:Spring) – 这些或者完全的覆盖了我们的应用,或者通过代码测试来展示他们的魔法。也有的时候,我们有一些库可能需要一些JDK的东西,但是这些东西并没有开源 (是不是有人说了 sun.misc.Unsafe?). 这时候,反射就是你要的答案。

  So this guy, being used to getting what he wants, now walks into the Module Saloon and the bartender has to tell him no, not this time.
  所以这家伙,经常被用来获得他想要的东西,但是现在,我们走进模块化系统中,看起来这次并不会如他所愿。

  翻着玩,看心情说不定就没有(2)了,对了,这里也是我翻得
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值