Java 支持类似 Swift 的类扩展吗?

问题描述 投票:0回答:4

在 Swift 中,您可以创建现有类的扩展,以便在需要时向现有类添加附加功能。这也有助于避免创建现有类的子类。

我只是想知道Java中是否存在类似的功能?或者向现有 Java 类添加其他方法的唯一方法是创建现有类的子类?

java subclass extension-methods
4个回答
8
投票

不,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 比较


2
投票

“装饰器模式”可能是最接近的匹配。它使用接口来保持类型兼容性和组合,以增强现有类的功能。这与您所描述的原理不同,但可能具有相同的目的。


2
投票
Groovy

或 Closure。 例如在 Groovy 中:

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 代码中使用。


0
投票
Java 类扩展库

提供了在 Java 中模拟类扩展(类别)的能力。 该库支持以下创建类扩展的方法:

    静态类扩展
  1. :像平常的 Java 类一样定义和实现扩展,然后利用 Java 类扩展库来查找匹配的扩展。
  2. 动态类扩展
  3. :利用 Java 类扩展库通过将扩展组合为 lambda 操作集来定义扩展,并让库动态动态创建扩展。
  4. 这两种方法都利用了 ClassExtension 接口,这有助于根据对象的扩展接口查询扩展。一旦获得,这些扩展就可以非常轻松地解锁附加功能。例如,获取 Shippable 扩展并使用其 ship() 方法来执行运送一本书的操作如下所示:

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(); }

	
© www.soinside.com 2019 - 2024. All rights reserved.