Roc*_*oty 28 java lambda java-8 method-reference constructor-reference
给出以下代码:
package com.gmail.oksandum.test;
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
}
public void foo() {
class LocalFoo {
LocalFoo(String in) {
//Some logic
}
}
List<String> ls = new ArrayList<>();
ls.stream().map(LocalFoo::new); //Line 21
}
}
Run Code Online (Sandbox Code Playgroud)
我的IDE没有给我任何错误.也就是说,直到我尝试构建项目并运行它.当我这样做它给我一个编译器错误,如下所示:
Error:(21, 24) java: incompatible types: cannot infer type-variable(s) R
(argument mismatch; invalid constructor reference
cannot access constructor LocalFoo(java.lang.String)
an enclosing instance of type com.gmail.oksandum.test.Test is not in scope)
Run Code Online (Sandbox Code Playgroud)
现在,我想,给出错误消息,如果foo()是静态的,这不会发生.而且非常正确,只有当foo()是实例方法时才会发生这种情况.只有当LocalFoo是实例方法中的本地类时才会发生,并且只有在使用构造函数引用时才会发生(即从不是常规方法引用).
更重要的是,如果我将第21行改为
ls.stream().map(str -> new LocalFoo(str));
Run Code Online (Sandbox Code Playgroud)
编译器突然没有错误.
所以回顾一下.如果我尝试在实例方法中声明的本地类上使用构造函数引用,编译器会抱怨无法访问构造函数,我很困惑.
如果有人能够阐明为什么会发生这种情况,我们将不胜感激.谢谢.
看起来好像LocalFoo
以某种方式被视为非静态类。这就是为什么它声称没有Test实例在范围内的原因。
从教程中:
局部类是非静态的,因为它们可以访问封闭块的实例成员。因此,它们不能包含大多数静态声明。
https://docs.oracle.com/javase/tutorial/java/javaOO/localclasses.html
该方法foo()
或类LocalFoo
必须是静态的才能起作用。但是不能将方法内部的类声明为静态的。因此,如果foo()
应该保持非静态(作为内部静态类),则必须将其移出方法。另一种选择是仅使用此:
ls.stream().map(s -> new LocalFoo(s));
应该有一种只说的方法Test.this.LocalFoo
,但这是行不通的。如果这样做的话,编译器也应该接受LocalFoo::new
。
现在有一个错误报告:https : //bugs.openjdk.java.net/browse/JDK-8144673
(请参见Brian Goetz的评论)
归档时间: |
|
查看次数: |
1702 次 |
最近记录: |