-
Notifications
You must be signed in to change notification settings - Fork 0
Description
看到作者在twi上介绍这个库的起因是看到Per Minborg说要研究StableValue(JDK自带的@Stable用API发布),暂时分享下看这个库的感想:(很多词不知道中文术语,将就看看吧)
现在公开能当stable用的功能基本都和class绑定,主要是<clinit>(Holder class)、indy(Lambda)、condy三种模式。这个仓库用indy模式再加一层class。
1、我个人设计API会设计个 MethodHandle initializer->MethodHandle memoized 模式,这样相当于动态Holder class,memoized指向Holder class static final field,Holder class 会呼叫initializer。
2、为了使用方便,API设计(比如这个项目)一般都实现一个接口。但是实现接口的问题是要创建实例,然后实例要调用stable功能就要专门用一个class,比如一个实现class自带indy/condy创建一次实例。这个为了支持接口相当于多一层class皮,但是这层皮里面能用condy indy还算不错。我个人倾向写condy,ConstantBootstraps.invoke + MethodHandle(Supplier.get) + MethodHandles.classData,定义时传入supplier当classdata,比这种用static field更安全。
这两个的最大问题都是每一个StableValue都要定义一个class,但是class定义多了吃内存,而且如果一个interface有太多实现,也会有profile pollution,尤其是放list里面。
相比之下,@Stable几乎没有任何成本,只需要字段额外占用一个全零值,同时赋值也更灵活。StableValue相比之下封装就很厚了。因为Java设计理念是下限比较高,然后stable玩坏的后果也比正常field玩坏的后果大,所以封装比较复杂,再写了一套dcl封装;但是还是比额外定义class成本更低,而且它基础的get+setIfUnset可以替代现有的atomicreference get+compareAndExchange,效率更高。
然后关于classfile api用途,一般创建classdesc是clazz.describeConstable().orElseThrow(),最好存static final,或者直接拿ConstantDescs里面的用;然后TypeKind有TypeKind.from(TypeDescriptor.OfField)可以直接接收Class。这样写起来会方便很多。
还是很喜欢作者这个实验项目的,因为能了解用户对classfile api和stable value的看法,对提升这两个API的用户体验有帮助。