Java 构造函数与方法引用的链接

标签 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);
        }
    }
}

此代码将无法编译,因为我们在调用父类(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/

相关文章:

java - JCE无法验证Jboss中部署的Webapp中的提供者BC。为什么?

java - "contains not only spaces"的正则表达式模式

java - 如何使用 Google Finance API 获取股票报价?

java - 用什么来存储可以查询的序列化数据?

java - 新手javac导入库(httpclient)命令行

java - 如何在不编写重复代码的情况下处理继承链中的默认值?

java - selectOne 和 selectMany 选项是否受 SelectItems 限制?

java - Hibernate:无法从底层数据库获取连接

java - Infinispan-10.0.1.Final : No marshaller registered for Java type java. util.UUID

java - 将 log4j 与继承的类一起使用