如何在Java 8编译时确保方法签名"实现"功能接口

Yah*_*hor 10 java java-8 functional-interface

Java 8中是否存在implements方法关键字的任何模拟?

假设我有一个功能界面:

@FunctionalInterface
interface LongHasher {
    int hash(long x);
}
Run Code Online (Sandbox Code Playgroud)

一个包含3个静态方法的库"实现"这个功能接口:

class LongHashes {
    static int xorHash(long x) {
        return (int)(x ^ (x >>> 32));
    }
    static int continuingHash(long x) {
        return (int)(x + (x >>> 32));
    }
    static int randomHash(long x) {
         return xorHash(x * 0x5DEECE66DL + 0xBL);
    }
}
Run Code Online (Sandbox Code Playgroud)

在将来,我希望能够互换地使用对这3种方法的任何引用作为参数.例如:

static LongHashMap createHashMap(LongHasher hasher) { ... }
...
public static void main(String[] args) {
    LongHashMap map = createHashMap(LongHashes::randomHash);
    ...
}
Run Code Online (Sandbox Code Playgroud)

我如何能确保在编译时间LongHashes::xorHash,LongHashes::continuingHash并且LongHashes::randomHash具有相同的签名LongHasher.hash(long x)

Luk*_*der 9

在过去,我也曾希望这样做,但不,你不能这样做.但是你知道.在Java 8之前有Java.请改为:

enum LongHashes implements LongHasher {
    XOR {
        @Override
        public int hash(long x) { ... }
    },
    CONTINUING {
        @Override
        public int hash(long x) { ... }
    },
    RANDOM {
        @Override
        public int hash(long x) { ... }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后:

public static void main(String[] args) {
    LongHashMap map = createHashMap(LongHashes.RANDOM);
    ...
}
Run Code Online (Sandbox Code Playgroud)

  • @Yahor如果你的意思是答案中的代码是否可行,绝对是.如果你的意思是`enum`中是否可以使用`XOR = x->`,那么; 但是你不需要枚举,只需声明静态字段`LongHasher XOR = x - > {...}`它看起来就像一个简单的方法. (3认同)
  • 这对8岁以前有好处.在java 8中,直接lambda`XOR = x - > ...`更简单 (2认同)
  • @Lukas Eder:我只是想指出之前的想法,因为bayou.io的评论听起来像将lambda表达式与`enum`结合起来是不可能的,我认为,链接可以避免评论中的长时间讨论. (2认同)

Tag*_*eev 8

你要求没有这样的语法结构.但是,您可以在显式将方法引用分配给接口时创建静态常量:

class LongHashes {
    private static final LongHasher XOR_HASH = LongHashes::xorHash;
    private static final LongHasher CONTINUING_HASH = LongHashes::continuingHash;
    private static final LongHasher RANDOM_HASH = LongHashes::randomHash;

    static int xorHash(long x) {
        return (int)(x ^ (x >>> 32));
    }
    static int continuingHash(long x) {
        return (int)(x + (x >>> 32));
    }
    static int randomHash(long x) {
         return xorHash(x * 0x5DEECE66DL + 0xBL);
    }
}
Run Code Online (Sandbox Code Playgroud)

这样,如果方法签名或接口以不兼容的方式更改,则编译将中断.如果您愿意,可以声明它们public并使用而不是方法引用.

如果您担心这些静态lambda将在运行时挂在内存中,您可以将此声明移动到单独的类(例如,嵌套),该类编译但从未加载.