Freemarker 和 java8 默认方法?

Freemarker and java8 default methods?

我们最近开始在接口中使用 java 8 个默认方法,看起来 Freemarker 看不到它们:

${myRatings.notEmpty()}

The following has evaluated to null or missing:
==> myRatings.notEmpty

这很遗憾,因为我们在模板中调用了一堆方法。 有针对这个的解决方法吗?也许一些补丁?

互联网上谈论的大多是 getFoo() 默认方法,这确实没有多大意义,但我说的是常规方法调用,而不是 getter。

更新: FreeMarker 2.3.26 为此引入了一个解决方法。引用自 version history:

FREEMARKER-24: Added workaround (not enabled by default) to expose Java 8 default methods (and the bean properties they define) to templates, despite that java.beans.Introspector (the official JavaBeans introspector) ignores them, at least as of JRE 1.8.0_66. To enable this workaround, either increase the value of the incompatibleImprovements constructor argument of DefaultObjectWrapper or BeansWrapper used to 2.3.26, or set its treatDefaultMethodsAsBeanMembers setting to true. Note that if you leave the object_wrapper setting of the Configuration on its default, it's enough to increase the incompatibleImprovements setting of the Configuration to 2.3.26, as that's inherited by the default object_wrapper.

原回答:

Freemarker 查看对象的方式基于 JavaBeans 规范,它是许多 Java 技术的基石。它使用 java.beans.Introspector 自省 类 以确保一致性。显然,JavaBeans 不支持 Java 8 个默认方法。 BeanInfo.getMethodDescriptors() 没有 return 默认方法,我们对 BeanInfo.getPropertiesDescriptors() 和 getters 有同样的问题。我不知道为什么标准 Java API(或 JavaBeans)的维护者会做出这样的决定……当然,Freemarker 迟早要进行额外的一轮反省以解决这些 JavaBeans 限制。