在 Swift 中,您可以创建现有类的扩展,以便在需要时向现有类添加附加功能。这也有助于避免创建现有类的子类。
我只是想知道Java中是否存在类似的功能?或者向现有 Java 类添加其他方法的唯一方法是创建现有类的子类?
不,vanilla Java 没有扩展方法。然而,由于其注释和字节码生成,Lombok 添加了许多有用的功能 - 包括扩展方法语法。
您可以使用其 @ExtensionMethod 注解将现有静态方法“转换”为扩展方法。静态方法的第一个参数基本上变成了
this
。例如,这是一个有效的 Lombok 增强型 Java 代码:
import lombok.experimental.ExtensionMethod;
@ExtensionMethod({java.util.Arrays.class, Extensions.class})
public class ExtensionMethodExample {
public String test() {
int[] intArray = {5, 3, 8, 2};
intArray.sort();
String iAmNull = null;
return iAmNull.or("hELlO, WORlD!".toTitleCase());
}
}
class Extensions {
public static <T> T or(T obj, T ifNull) {
return obj != null ? obj : ifNull;
}
public static String toTitleCase(String in) {
if (in.isEmpty()) return in;
return "" + Character.toTitleCase(in.charAt(0)) +
in.substring(1).toLowerCase();
}
}
请注意,可以在 null 对象上“调用”Lombok 扩展方法 - 只要静态方法是 null 安全的,就不会抛出
NullPointerException
,因为这基本上翻译为静态方法调用。是的 - 这归结为语法糖,但我想这仍然比通常的静态方法调用更具可读性。
除此之外,如果您的项目可以的话,您还可以使用具有 Java 互操作性的其他 JVM 语言。例如,Kotlin带有扩展方法功能,以及标准库中已经定义的一些有用的扩展。这是 Kotlin 和 Lombok 比较。
List.metaClass.printSize = {
println delegate.size()
}
[1,2,3].printSize() //prints 3
在 Scala 中你可以使用
implicit class
:
implicit class PrefixedString(val s: String) {
def prefix = "prefix_" + s
}
"foo".prefix // returns "prefix_foo"
请看看这篇文章。
重要的一点是,Groovy/Scala 源代码旨在编译为 Java 字节码,以便生成的类可以在 Java 代码中使用。
提供了在 Java 中模拟类扩展(类别)的能力。 该库支持以下创建类扩展的方法:
Book book = new Book("The Mythical Man-Month");
Shippable shippable = StaticClassExtension.sharedExtension(book, Shippable.class);
shippable.ship();
或
Book book = new Book("The Mythical Man-Month");
Shippable shippable = DynamicClassExtension.sharedExtension(book, Shippable.class);
shippable.ship();
运送一系列物品同样简单:
Item[] items = {
new Book("The Mythical Man-Month"),
new Furniture("Sofa"),
new ElectronicItem("Soundbar")
};
for (Item item : items) {
Shippable shippable = StaticClassExtension.sharedExtension(item, Shippable.class);
item.ship();
}