Java是否支持类似Swift的类扩展?

Java是否支持类似Swift的类扩展?,java,subclass,extension-methods,Java,Subclass,Extension Methods,在Swift中,您可以创建现有类的扩展,以便在需要时向现有类添加其他函数。这也有助于避免创建现有类的子类 我只是想知道Java中是否存在类似的函数?或者向现有Java类添加其他方法的唯一方法是创建现有类的子类吗?可能是最匹配的方法。它使用接口来维护类型兼容性和组合,以增强现有类的功能。这与您描述的原则不同,但可能有相同的目的。不,vanilla Java没有扩展方法。然而,由于其注释和字节码生成,它添加了许多有用的特性,包括扩展方法语法 可以使用其注释将现有静态方法“转换”为扩展方法。静态方法的

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


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

可能是最匹配的方法。它使用接口来维护类型兼容性和组合,以增强现有类的功能。这与您描述的原则不同,但可能有相同的目的。

不,vanilla Java没有扩展方法。然而,由于其注释和字节码生成,它添加了许多有用的特性,包括扩展方法语法

可以使用其注释将现有静态方法“转换”为扩展方法。静态方法的第一个参数基本上变成
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();
  }
}
导入lombok.experimental.ExtensionMethod;
@ExtensionMethod({java.util.Arrays.class,Extensions.class})
公共类扩展MethodExample{
公共字符串测试(){
int[]intArray={5,3,8,2};
intArray.sort();
字符串iAmNull=null;
返回iAmNull.or(“你好,世界!”.toTitleCase());
}
}
类扩展{
公共静态T or(T obj,T ifNull){
返回obj!=null?obj:ifNull;
}
公共静态字符串toTitleCase(字符串输入){
如果(in.isEmpty())返回in;
返回“”+字符总数(在字符(0)中)+
in.substring(1).toLowerCase();
}
}
请注意,Lombok扩展方法可以在null对象上“调用”——只要静态方法是null安全的,
NullPointerException
将不会被抛出,因为这基本上被转换为静态方法调用。是的,这可以归结为语法糖,但我想这仍然比通常的静态方法调用更具可读性


除此之外,您还可以使用其他一些具有Java互操作性的JVM语言,如果在您的项目中可以的话。例如,标准库中已经定义了一些有用的扩展。这里有一个.

它可以在JVM的其他语言中完成,比如Scala或Close

例如,在Groovy中:

List.metaClass.printSize = {
    println delegate.size()
}

[1,2,3].printSize() //prints 3
在Scala中,您可以使用
隐式类

implicit class PrefixedString(val s: String) {
   def prefix = "prefix_" + s 
}

"foo".prefix // returns "prefix_foo"
请看一看

重要的一点是,Groovy/Scala源代码旨在编译为Java字节码,以便生成的类可以在Java代码中使用。

Java提供全面、无缝的C#风格扩展方法支持,允许您向不受控制的类添加方法,例如。,
java.lang.String

演示:

了解更多信息:


此外,Lombok在内部有一些魔力,但它是Java,所以说它的“不可能”并不完全正确。Scala示例可能应该使用一个
隐式类
,它扩展了AnyVal
,而不是Java。然而,并不是每个人都对Scala的说法感到满意。因为它会影响可读性、可维护性。通常,我们用函数创建一个类,比如XxxUtils或Xxxs。继承也有它自己的问题(最终类、旧代码的强制废弃、集中制=只有一个扩展点)。为Java提供全面、无缝的C#风格扩展方法支持,允许您向不受控制的类添加方法,例如,
Java.lang.String
。演示:让龙目山跑起来很痛苦。。也许更容易些?它能在Eclipse中工作吗?流形不难使用,您可以轻松地将它集成到现有项目中。基本上,您可以为Javac添加
-Xplugin:Manifold
arg,如果您使用的是运行时特性,那么可以将Manifold jar添加到类路径中。它完全支持Java8-11,并与Maven和Gradle配合良好。IntelliJ IDEA作为plugin为Manifold提供全面支持。目前还没有对Eclipse的支持。我喜欢lombok:)这在swift中仍然非常清晰/可读,但至少我们也可以在Java中做到这一点(相当直接)。