我最近遇到了错误消息"空白的最终字段obj可能尚未初始化".
通常情况下,如果您尝试引用可能尚未分配给值的字段.示例类:
public class Foo {
private final Object obj;
public Foo() {
obj.toString(); // error (1)
obj = new Object();
obj.toString(); // just fine (2)
}
}
Run Code Online (Sandbox Code Playgroud)
我用Eclipse.在行中(1)我得到错误,在行中(2)一切正常.到目前为止这是有道理的.
接下来,我尝试obj在构造函数内创建的匿名接口中访问.
public class Foo {
private Object obj;
public Foo() {
Runnable run = new Runnable() {
public void run() {
obj.toString(); // works fine
}
};
obj = new Object();
obj.toString(); // works too
}
}
Run Code Online (Sandbox Code Playgroud)
这也有效,因为我obj在创建界面时无法访问.我也可以将我的实例传递给其他地方,然后初始化对象obj然后运行我的界面.(但null在使用之前检查是否合适). …
最近我发现了匿名类和lambda表达式之间的细微差别:
public class FinalTest {
final Runnable x = new Runnable() {
@Override
public void run() {
System.out.println(x.hashCode());
}
};
final Runnable y = () -> System.out.println(y.hashCode());
}
Run Code Online (Sandbox Code Playgroud)
通常lambdas等同于匿名类.甚至我的Eclipse IDE都有重构转换x为lambda(它变得完全像y)并转换y为匿名类(它变得完全一样x).然而lambda给了我一个编译错误,而匿名类可以完美编译.错误消息如下所示:
>javac FinalTest.java
FinalTest.java:9: error: self-reference in initializer
final Runnable y = () -> System.out.println(y.hashCode());
^
1 error
Run Code Online (Sandbox Code Playgroud)
所以问题是:为什么会有这样的差异?
我使用 java 和 springboot 创建了一个简单的休息服务。这是我的服务层代码
@Service
class MyService {
private final TestService service;
@Autowired
public MyService(final TestService service) {
this.service = service;
}
// here is the issue
private final Predicate<User> userPredicate = (user) -> this.service.isValidUser(user);
}
Run Code Online (Sandbox Code Playgroud)
在上面的行中,抱怨变量服务的 ide 可能未初始化,并且我无法在谓词实现中使用它。我尝试删除服务中的final,这有效,但我不想删除TestService 声明中的final。
有人有什么解决办法吗?
我不明白这种行为.
这段代码符合:
public class A {
private String s;
private Function<String, String> f = e -> s;
public A(String s) {
this.s = s;
}
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我做s最后的,那么我得到一个编译器错误:
public class A {
private final String s;
private Function<String, String> f = e -> s; // Variable 's' might not have been initialized
public A(String s) {
this.s = s;
}
}
Run Code Online (Sandbox Code Playgroud)
这是为什么?如果是另一种方式,我明白了,但是当我声明一个字段final(这迫使我在构造函数中初始化它的值)时,编译器是怎么抱怨的,当它不是时它就可以了final?