我们打赌:这个注解很快就会出现在JDK里面

Java8函数式接口与方法签名
本文探讨了如何确保Java8编译时一个方法签名实现了函数式接口,并提出了一种通过注解来约束静态方法类型的解决方案。

最近由雅和提出的堆栈溢出问题引起了我兴趣:怎么确保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);
    }
}

事实上,今天你就能实现这样一个注解并且写下你自己的注解处理器来验证这些方法。期待另一个伟大的注解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值