最近由雅和提出的堆栈溢出问题引起了我兴趣:怎么确保Java 8 编译时,一个方法签名实现了函数式接口。这个是一个好问题。我们假设下面的定义:
@FunctionalInterface
interface LongHasher {
int hash(long x);
}
这个类型强加了一个清晰的约定。实现类必须提供一个单独的hash方法 ,传一个长整型参数,返回一个整型值。当使用lambdas或方法引用时,这个hash()方法名就不再相关了并且结构类型long–>int 也满足。
在他的问题中,雅和想要强制三个静态方法上的类型(我修改的例子):
class LongHashes {
// OK
static int xorHash(long x) {
return (int)(x ^ (x >>> 32));
}
// OK
static int continuingHash(long x) {
return (int)(x + (x >>> 32));
}
// Yikes
static int randomHash(NotLong x) {
return xorHash(x * 0x5DEECE66DL + 0xBL);
}
}
他想要Java 编译器报怨randomHash()与LongHasher不一致。
这样很容易产生一个编译错误,当然,用函数注解(方法引用)可以自然地给LongHasher实例的静态方法赋值。
// OK
LongHasher good = LongHashes::xorHash;
LongHasher alsoGood = LongHashes::continuingHash;
// Yikes
LongHasher ouch = LongHashes::randomHash;
但是这样不太简洁。类型约束应该直接强加在static方法上面。
用Java的方式怎么做到这些呢?
我敢打赌下面的模式将会出现在JDK 10里面。
class LongHashes {
// Compiles
@ReferenceableAs(LongHasher.class)
static int xorHash(long x) {
return (int)(x ^ (x >>> 32));
}
// Compiles
@ReferenceableAs(LongHasher.class)
static int continuingHash(long x) {
return (int)(x + (x >>> 32));
}
// Doesn‘t compile
@ReferenceableAs(LongHasher.class)
static int randomHash(NotLong x) {
return xorHash(x * 0x5DEECE66DL + 0xBL);
}
}
事实上,今天你就能实现这样一个注解并且写下你自己的注解处理器来验证这些方法。期待另一个伟大的注解。
原文地址:http://blog.csdn.net/supercrsky/article/details/46344761