@ExtensionMethod
API 令人讨厌?自己修复它:为现有类型添加新方法!
@ExtensionMethod
在 lombok v0.11.2 版本中作为实验性特性引入。
实验性
实验性是因为- 对代码风格影响很大。
- 很希望能够附带实用工具方法来扩展常用类,但到目前为止,lombok 还没有针对此类运行时依赖项的良好分发方法。
- 对 Eclipse 影响较大,并且例如自动完成功能在 NetBeans 中尚无法工作。
- @ExtensionMethod 应该可以用于方法吗?应该可以用于包吗?
- 此特性相关的 bug 比我们希望的要多,并且维护负担很重。
概述
你可以创建一个类,其中包含一堆 public
、static
方法,这些方法都至少接受 1 个参数。这些方法将扩展第一个参数的类型,就像它们是实例方法一样,使用 @ExtensionMethod
特性。
例如,如果你创建 public static String toTitleCase(String in) { ... }
,你可以使用 @ExtensionMethod
特性使其看起来像 java.lang.String
类有一个名为 toTitleCase
的方法,该方法没有参数。静态方法的第一个参数充当实例方法中 this
的角色。
所有 public
、static
且至少有一个参数(其类型不是原始类型)的方法都被视为扩展方法,并且每个方法都将被注入到第一个参数类型的命名空间中,就像它们是实例方法一样。如上面的示例所示,看起来像这样的调用:foo.toTitleCase()
将被替换为 ClassContainingYourExtensionMethod.toTitleCase(foo);
。请注意,如果 foo
为 null,实际上不会立即抛出 NullPointerException
- 它会像任何其他参数一样传递。
你可以将任意数量的类传递给 @ExtensionMethod
注解;将搜索所有这些类以查找扩展方法。这些扩展方法适用于注解类中的任何代码。
Lombok (目前) 没有任何运行时依赖项,这意味着 lombok (目前) 不会附带任何有用的扩展方法,因此你必须自己创建。但是,这里有一个可能会激发你的想象力的方法
public class ObjectExtensions { public static <T> T or(T object, T ifNull) { return object != null ? object : ifNull; } }
使用上面的类,如果你将 @ExtensionMethod(ObjectExtensions.class)
添加到你的类定义中,你可以编写
String x = null; System.out.println(x.or("Hello, World!"));
上面的代码不会因
NullPointerException
而失败;它实际上会输出 Hello, World!
使用 Lombok
import lombok.experimental.ExtensionMethod;
|
原生 Java
public class ExtensionMethodExample {
|
支持的配置键
-
lombok.extensionMethod.flagUsage
= [warning
|error
] (默认值:未设置) - 如果配置,Lombok 将把任何
@ExtensionMethod
的使用标记为警告或错误。
小字部分
调用被重写为对扩展方法的调用;静态方法本身不会被内联。因此,扩展方法必须在编译时和运行时都存在。
泛型被完全应用于确定扩展方法。例如,如果你的扩展方法的第一个参数是 List<? extends String>
,那么任何与之兼容的表达式都将拥有你的扩展方法,但其他类型的列表则不会。因此,List<Object>
不会获得它,但 List<String>
会。