Yahor最近提出的Stack Overflow问题引起了我的兴趣: 如何在Java 8编译时确保方法签名“实现”功能接口 。 这是一个很好的问题。 让我们假设以下名义类型:
@FunctionalInterface
interface LongHasher {int hash(long x);
}
该类型强加了清晰的合同。 实现者必须提供一个带有long
参数的名为hash()
方法,并返回一个int
值。 当使用lambda或方法引用时,则hash()
方法名称不再相关,结构类型long -> int
就足够了。
在他的问题中,Yahor希望通过三种静态方法(由我修改的示例)强制实施上述类型:
class LongHashes {// OKstatic int xorHash(long x) {return (int)(x ^ (x >>> 32));}// OKstatic int continuingHash(long x) {return (int)(x + (x >>> 32));}// Yikesstatic int randomHash(NotLong x) {return xorHash(x * 0x5DEECE66DL + 0xBL);}
}
而且他希望Java编译器在第三种情况下抱怨,因为randomHash()
不“符合” LongHasher
。
当然,通过将static
方法以其功能符号(方法引用)实际分配给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);}
}
实际上,您现在已经可以实现这样的注释,并编写自己的注释处理器( 或JSR-308检查器 )来验证这些方法。 期待另一个伟大的注释 !
那么,谁敢打赌我们将在JDK 10中使用此注释?
翻译自: https://www.javacodegeeks.com/2015/06/were-taking-bets-this-annotation-will-soon-show-up-in-the-jdk.html