我有一个带有一个方法的类(其中一半不使用他们的参数,因此将其命名为下划线),我只是切换到Java 8.现在我想用lambdas替换它们。
这是我的代码:
interface I {
void stuffHappened(Integer howManyStuff);
}
public class A {
void go() {
I i = new I() {
public void stuffHappened(Integer _) {
System.out.println("woah!!");
}
};
}
}
之后:
interface I {
void stuffHappened(Integer howManyStuff);
}
public class A {
void go() {
I i = _ -> System.out.println("woah!!");
}
}
如您所见,它显然已不再有效,声称使用“_”作为参数名称不再有效。但那么为什么它首先允许这个重构呢?为什么它适用于匿名类,而不是lambdas?这真的是一条新规吗?或者它在IDEA中是否存在某种差异?
我正在使用Intellij-IDEA(第一次使用它),实际上是Android Studio(Beta)0.8.1(使用retrolambda允许在Android上使用lambdas),我认为它使用IDEA。
答案 0 :(得分:7)
在Java 8之前,单个下划线_
是有效的标识符。从Java 8开始,不允许使用下划线,以便将来可能使其成为普通标识符以外的其他内容。有关说明,请参阅此message from Brian Goetz。
在现有(pre-lambda)代码中使用下划线将生成警告,但使用下划线作为lambda形式参数名称将生成错误。正如Brian所说,“因为没有lambda的现有代码。”
在您的示例中,匿名内部类中的形式参数_
是合法代码,但它应该生成警告。将此代码重构为使用_
的lambda将使其成为非法!由于IntelliJ IDEA正在重构此代码,因此它应该知道此规则,并且它应该提供将参数名称重命名为其他名称。
在IDEA的重构机制中,这可能被视为一个错误,或者至少需要一个增强功能。
答案 1 :(得分:4)
Lambdas不允许_
作为参数名称,但现有的构造可以。
来自JLS 15.27.1. Lambda Parameters:
如果lambda参数的名称为_(那个,那么这是一个编译时错误 是,一个下划线字符。)
不鼓励在任何上下文中使用变量名_。未来 Java编程语言的版本可以保留此名称作为 关键字和/或赋予它特殊的语义。
我建议将参数重命名为__
,$
或节省空间,因为您已经使用了unicode,_
(尽管后者可能是语言的滥用 - 我不知道实际代码点的用途是什么。