获得徽章 0
- 今天在 IDEA 里跑单测时发现一个有趣的现象:我把`POLL_SCHEDULED_AVG_INTERVAL_SEC`这个常量的值从2变为1,图一 Utils 类中 set后的值应该为 1 * 1000 = 1000,debug看却仍然是旧值 2000。打开class文件一看常量值确实变成1,但 Utils 中的代码却是 `p.setPollScheduledAvgIntervalMS(2000)`。原来是 Utils 类没有更新。
分析:我推断IDEA的编译机制应该是仅重新编译有内容变更的文件,以保证编译速度,由于 Utils 类引用是常量,JVM编译存在“常量折叠”优化现象,Utils 类对应的字节码直接使用 2000,而不是动态引用常量类,且 Utils 类没有内容变更,未触发重新编译,因此一直使用的是 2000 这个旧值。
解决:也不用 `mvn clean` 强制全部重编译,直接改动 Utils 类,比如加一行空格,最后再改回来,就可以触发 Utils 类重新编译了。展开
赞过评论1 - **接口的实现类的实例不能调用该接口定义的静态方法**
这是我在使用 Java 8 的 `Comparator` 时发现的,比如这段代码
`Comparator<String> comparator = Comparator.comparing(String::length).thenComparing(String.CASE_INSENSITIVE_ORDER)`
`comparing` 是 static 方法,返回一个 `Comparator` 实例,然后调用实例方法 `thenComparing`,再返回一个新的 Comparator 实例。
通过这种链式调用实现组合 comapring 的逻辑。
我突然好奇如果连续调用两次 comparing 方法会怎么样,这样后面的 comparing 逻辑不就覆盖前面的 comparing 逻辑了吗?
然后就发现这个限制🚫,这样的代码是不能通过编译的: `illegal static interface method call`。
原因:
虽然类实例可以调用该类定义的静态方法,但是这种设计是不好的,但因为需要先前兼容,只能保留这种“怀设计”了。
接口可以在定义静态方法是在 Java 8 才引入,没了历史包袱,自然可以改正这种不良设计,不再重复犯错。
同时也可以避免上述这种非法调用的情况,更好地实现的链式调用~展开评论点赞 - 阅读技术文章时的两大痛点:1. 代码不会自动软换行 (特别是在手机上阅读的时候); 2. 文章没有目录。
今天偶然发现 SimpRead 这款 Chrome 插件可以解决第二个痛点,能自动生成文章目录,贴心~等人赞过评论8 - 在消除 Java 方法声明中的 throws checked exception 上, 发现 Lombok 的做法好高明: 直接将 checked execption 强转成 runtime exception, 通过欺骗编译器, 最终抛出的还是原本的 exception, 这样就不用像有的工具类提供的解决方案那样, 还要将其 wrap 成一个 runtime exception.展开赞过评论1