我遇到過在重構代碼時或多或少看起來像這樣的情況;這裏改寫爲示範起見:Java構造函數與方法參考鏈接
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);
}
}
}
此代碼不能編譯,因爲我們cannot reference this before supertype constructor has been called
:
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
是有意義的,但我發現它在這個特定的上下文中令人驚訝,因爲似乎沒有任何形式的對使用this
當涉及到方法引用和lambda表達式的內容時。
除了這是因爲JLS§8.8.7.1這麼說嗎?
你也可以使'debuggingStringTransform'方法靜態並使用靜態方法參考 –
@VladBochenin我在工作中遇到的情況比這更復雜一點,但在我的例子'debuggingStringTransform'中我注意包含一個引用到實例字段'url',以便它不能是靜態的 – Hay
這是因爲在調用super或super之前不能保證調用debugginStringTransform。如果下一個構造函數在執行super之前調用函數呢? – jontro