我发现,在今天之前,Java 8有一个我从未听说过的语言特性
明确的接收器参数
考虑一下Java 7中的一个简单方法。
public class Currency {
public String getCode() { ... }
}
在Java 8中,事实证明还有第二种方法可以写。
public class Currency {
public String getCode(Currency this) { ... }
}
同样的技巧也适用于有参数的方法。
public class Currency {
public int compareTo(Currency this, Currency other) { ... }
}
那么,这到底是怎么回事呢?
Java语言规范的相关部分在这里。
接收参数是实例方法或内类构造函数的一种可选的语法手段。对于一个实例方法,接收方参数代表该方法被调用的对象。对于一个内类的构造函数,接收参数代表新构造的对象的紧邻的实例。无论哪种方式,接收方参数的存在只是为了让代表对象的类型在源代码中被表示出来,这样类型就可以被注释。接收方参数不是一个正式的参数;更确切地说,它不是任何种类的变量的声明,它从来没有与方法调用表达式或合格的类实例创建表达式中作为参数传递的任何值绑定,而且它在运行时没有任何作用。
这个新特性是完全可选的,它的存在是为了让类型在使用时被注解。
public class Currency {
public int compareTo(@AnnotatedUsage Currency this, Currency other) { ... }
}
@Target(ElementType.TYPE_USE)
public @interface AnnotatedUsage {}
该注释在反射中使用Method::getAnnotatedReceiverType()来实现。
展望未来
List<String> 我是在Project Valhalla的背景下发现这个功能的,该项目旨在为Java增加价值类型。正在考虑的一种可能的语法是使用接收器类型,以允许从List<int> ,不同的方法。
public class List<any T> {
public int sum(List<int> this) { ... }
}
这种语法将被用来定义一个sum() 方法,该方法只在List 被int 参数化时适用,而在被其他东西,如String 参数化时不适用。
欲了解更多信息,请看这封发给Valhalla专家邮件列表的邮件。但请注意,该列表是只读的,不能注册,而且只针对预先选定的专家。此外,那里讨论的一切都处于非常、非常早期的阶段,在真正的Java版本(如Java 10)发布之前,有可能发生很大的变化。
摘要
Java 8有一个新的语言功能,你可能从来没有听说过,也可能永远不会使用。 但至少你现在有了一些知识,你可以用来证明你是一个Java大师!