Java module

模块的主要作用有:

  • 模块间需要显示地声明(模块)依赖,而不是以前的简单的基于 classpath
  • 更强的封装隔离,模块不主动导出的话无法被 import;不 open 则无法对其使用反射技术

指令

模块通过在模块根目录下的 module-info.java 中的指令来约束使用。

定义模块

最好(或则是必须,没找到规定说明) moduleName 和文件夹名称一致,否则 javac 编译时提示 module 和预期的不一致

module moduleA {
}

引入依赖

requires moduleB;

可加 transitive 来表示依赖传递,如 requires transitive moduleB;,然后在 moduleCrequires moduleA; 后,那么在 moduleC 中可使用在 moduleB 中导出的类或接口。

导出 package

exports packageFullName;

表示当别的模块(A) requires 了当前模块,那么 packageFullName 这个包(及子孙包)里的 publicprotected 的类和接口可在模块 A 里被访问使用。

可用 exports packageFullName to moduleA, moduleB 来表示仅 moduleAmoduleB 可访问 packageFullName

提供服务

provides full.name.Service with full.name.concreateService, full.name.concreateService2;

表示该模块向外提供 full.name.Service 的实现 full.name.concreateServicefull.name.concreateService2

使用服务

uses full.name.Service;

表示该模块需要使用 full.name.Service。同时,不直接依赖具体的实现,而是使用抽象类或接口。然后搭配 ServiceLoader 或别的 IoC 工具来做依赖注入,从而达到和具体实现解耦的目的。

配合反射

opens fullPackageName;

表示 fullPackageName 可被使用反射技术。也可使用 opens fullPackageName to moduleA, moduleB 限定开放反射的范围。

open module moduleD {} 表示整个模块都是开放的。

其它

java --list-modules 查看 JDK 内置的模块

编译运行

可通过 javac -d mods --module-source-path src $(find src -name "*.java") 来编译运行(多个模块),src 表示各模块所在的目录。

也可使用 javac -d dist --module-source-path src -m client 来编译指定的模块。

继续阅读

服务态度

前些时候,上年双十一京东买的一款耳机出了点问题,一边声音有点小,使用起来非常难受,于是申请了售后。印象中是在提交了当天还是第二天后,来电说除了可以按照标准的三包政策外,考虑到我在京东的消费也算有一点,信用也不错,所以可以由京东在收到退货后直接换新的而不用等待返厂检测维修后再寄回来。

这个服务,有点超出我的预期,或许也我和几乎不申请售后有关,所以对售后服务积累的样本不多,没法判断这是中位数还是 top 之类。

但,如果作为服务提供商,在消费者是信用比较良好的消费者的大概率的情况下,这样的服务态度是会为自己加分的。

在网商这个场景下,京东这个偏自营的模式更容易做到这种服务方式,淘宝这种平台模式的看起来会比较难,因为商家是否支持方式要看商家服务规则,要看商家对消费者的信用的了解和信任,还要看商家对其运营的放权以及防腐的能力。

除了狭义的服务业,任何工作理论上都是向别人提供服务,除了按照服务规章来提供专业服务,我们也应该用一种比较友好的更能吸引新用户和提高留存率的态度来提供服务,或者叫换位思考。

当年的广告用语依然可用于激励自己:

今时今日,噉嘅服务态度系唔够嘎

 

MacOS 中切换 JDK

倘若装有多个版本,特别是从 8 跨到 9 这个分界线,如果是基于 IDE,那么一般使用 IDE 提供的 JDK 设置来指定就可以了。但如果是直接命令执行,那就需要来个方便切换版本的方法。

对于 MacOS,只需要设定 JAVA_HOME 这个环境变量就可以了,甚至不必要把这个路径添加到 PATH 中。

同时,在 MacOS 中,JAVA 相关有个好用的内置工具:/usr/libexec/java_home

$ /usr/libexec/java_home -h
Usage: java_home [options...]
    Returns the path to a Java home directory from the current user's settings.

Options:
    [-v/--version   <version>]       Filter Java versions in the "JVMVersion" form 1.X(+ or *).
    [-a/--arch      <architecture>]  Filter JVMs matching architecture (i386, x86_64, etc).
    [-d/--datamodel <datamodel>]     Filter JVMs capable of -d32 or -d64
    [-t/--task      <task>]          Use the JVM list for a specific task (Applets, WebStart, BundledApp, JNI, or CommandLine)
    [-F/--failfast]                  Fail when filters return no JVMs, do not continue with default.
    [   --exec      <command> ...]   Execute the $JAVA_HOME/bin/<command> with the remaining arguments.
    [-R/--request]                   Request installation of a Java Runtime if not installed.
    [-X/--xml]                       Print full JVM list and additional data as XML plist.
    [-V/--verbose]                   Print full JVM list with architectures.
    [-h/--help]                      This usage information.

所以,通过 /usr/libexec/java_home -v 1.8 这样的形式即可把 JDK 切到指定版本(这里是 8,当然,需要先安装对应的版本)。

然后给 bash/zsh 等 shell 添加上一个 function 就可以简单地来切换了,我用的是 fish,在 ~/.config/fish/functions/ 下添加一个 setjdk.fish,填写以下内容,那么就可以在终端中使用 setjdk 1.8 / setjdk 9 的形式来切换到 JDK8 和 JDK9 了。

继续阅读

c君不在

2018/04/10

连五分钟的慢跑都扛不下了,中学年代能跑三千米的我连幻影都看不到了,我这个渣渣!

c君不在

2018/03/31

看的美剧其实不多,最近在补「灵书妙探(Castle)」,以前看了些许别的,剧中谈到中国时,除了唐人镇、中餐这些普通元素外,似乎谈到中国,多半是和间谍相关,不会认为中国多强大,但隐约有威胁的样子。当然,这比起恐怖事件容易和阿拉伯人群挂钩来说,待遇还是好很多的。

北京时间,又名中国标准时间,英语 China Standard Time,缩写 CST.

统一采用 UTC+8 对于中部和西部的人来说,和太阳照射的确很有差距。但如果多时区,对我这种习惯了中国正八区认知的人,似乎又很麻烦。可能不仅仅是这个,包括很多程序、应用可能长期以来都是默认了 UTC+8 的设定,一旦改变,可能有不少的东西需要调整。

The codes for languages and countries seem a bit random because some of them are derived from local languages. German in German is Deutsch, Chinese in Chinese is zhongwen: hence de and zh.          — Core JAVA