我在重构代码时遇到过类似这样的情况;为了示例而在这里重写:
public class UrlProbe {
private final OkHttpClient http;
private final String url;
private final Function<Response, Object> transform;
private Object cachedValue;
public UrlProbe(OkHttpClient http, String url) {
this(http, url, this::debuggingStringTransform);
}
public UrlProbe(OkHttpClient http, String url, Function<Response, Object> transform) {
this.http = http;
this.url = url;
this.transform = transform;
}
private Object debuggingStringTransform(Response response) {
String newValue = response.body().toString();
System.out.println("Debugging new value from url " + url + ": " + newValue);
return newValue;
}
public synchronized Object probe() {
if (cachedValue != null) {
return cachedValue;
}
try (Response response = http.newCall(new Request.Builder().url(url).get().build()).execute()) {
cachedValue = transform.apply(response);
return cachedValue;
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
}
此代码将无法编译,因为我们在调用父类(super class)型构造函数之前无法引用此代码
:
public UrlProbe(OkHttpClient http, String url) {
this(http, url, this::debuggingStringTransform);
}
以下内容也不会编译:
public UrlProbe(OkHttpClient http, String url) {
this(http, url, response -> debuggingStringTransform(response));
}
我发现解决这个问题的唯一方法是显式使用非链接构造函数:
public UrlProbe(OkHttpClient http, String url) {
this.http = http;
this.url = url;
this.transform = this::debuggingStringTransform;
}
虽然在构造函数链接参数中限制使用 this
是有意义的,但我发现在这种特定的上下文中令人惊讶,因为似乎没有对正在构造的对象进行任何类型的评估由于在方法引用和 lambda 表达式的内容方面使用 this
导致。
除了 JLS §8.8.7.1 如此规定之外,此限制背后是否还有其他理由?
最佳答案
允许过早引用此作用域会破坏如下所示的代码
public class UrlProbe {
final String url;
final String param2;
public UrlProbe(String url) {
this(url, this::debuggingStringTransform);
}
public UrlProbe(String url, Function<String, String> transform) {
this(url, transform.apply("")); // <-- What should happen when url is referenced here?
}
public UrlProbe(String url, String param2) {
this.url = url;
this.param2 = param2;
}
private String debuggingStringTransform(String response) {
System.out.println("Debugging new value from url " + url + ": " + response);
return response;
}
}
这至少是违反规则的一种方式。
关于Java 构造函数与方法引用的链接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46457124/