Why does "final" on a POJO throw compile error on a "new" with inline setters?

huangapple go评论66阅读模式
英文:

Why does "final" on a POJO throw compile error on a "new" with inline setters?

问题

为什么我不能在一个 final 类上编写一个 "inline" 对象创建器?

这是该类的(非 final)版本。

public class ValidationResult {

    private boolean isValid;

    private int statusCode;

    private String statusMessage;

    public boolean isValid() {
        return isValid;
    }

    public void setValid(boolean valid) {
        isValid = valid;
    }

    public int getStatusCode() {
        return statusCode;
    }

    public void setStatusCode(int statusCode) {
        this.statusCode = statusCode;
    }

    public String getStatusMessage() {
        return statusMessage;
    }

    public void setStatusMessage(String statusMessage) {
        this.statusMessage = statusMessage;
    }
}

这是带有内联设置器的新版本。

ValidationResult vr = new ValidationResult() {{
    setStatusCode(55555);
    setValid(false);
    setStatusMessage("This snipplet is working");
}};

我将这个简单的 POJO 类设置为 "final"。

public final class ValidationResult {

    private boolean isValid;

    private int statusCode;

    private String statusMessage;

    public boolean isValid() {
        return isValid;
    }

    public void setValid(boolean valid) {
        isValid = valid;
    }

    public int getStatusCode() {
        return statusCode;
    }

    public void setStatusCode(int statusCode) {
        this.statusCode = statusCode;
    }

    public String getStatusMessage() {
        return statusMessage;
    }

    public void setStatusMessage(String statusMessage) {
        this.statusMessage = statusMessage;
    }
}

并且使用相同的新内联方式。

ValidationResult vr = new ValidationResult() {{
    setStatusCode(55555);
    setValid(false);
    setStatusMessage("Huh??");
}};

我得到一个错误:

> 错误:(23, 41)java: 无法从 final com.me.myproject.domain.ValidationResult 继承

"无法继承"?

Huh?

英文:

Why can I not write an "inline" object creator on a final class?

Here is the (non final) version of the class.

public class ValidationResult {

    private boolean isValid;

    private int statusCode;

    private String statusMessage;

    public boolean isValid() {
        return isValid;
    }

    public void setValid(boolean valid) {
        isValid = valid;
    }

    public int getStatusCode() {
        return statusCode;
    }

    public void setStatusCode(int statusCode) {
        this.statusCode = statusCode;
    }

    public String getStatusMessage() {
        return statusMessage;
    }

    public void setStatusMessage(String statusMessage) {
        this.statusMessage = statusMessage;
    }
}

Here is the new with inline setters.

                ValidationResult vr = new ValidationResult() {{
                    setStatusCode(55555);
                    setValid(false);
                    setStatusMessage("This snipplet is working");
                }};

I make the simple POJO class "final"

public final class ValidationResult {

    private boolean isValid;

    private int statusCode;

    private String statusMessage;

    public boolean isValid() {
        return isValid;
    }

    public void setValid(boolean valid) {
        isValid = valid;
    }

    public int getStatusCode() {
        return statusCode;
    }

    public void setStatusCode(int statusCode) {
        this.statusCode = statusCode;
    }

    public String getStatusMessage() {
        return statusMessage;
    }

    public void setStatusMessage(String statusMessage) {
        this.statusMessage = statusMessage;
    }
}

And with the same new-inline

                ValidationResult vr = new ValidationResult() {{
                    setStatusCode(55555);
                    setValid(false);
                    setStatusMessage("Huh??");
                }};

I get a

> Error:(23, 41) java: cannot inherit from final
> com.me.myproject.domain.ValidationResult

"cannot inherit" ?

Huh??

答案1

得分: 3

使用双括号初始化时,实际上是在幕后创建一个匿名内部类,该类继承了 ValidationResult 类。

在Java中,不允许使用 final 关键字扩展类,因此会出现编译错误。

此外,当使用双括号初始化时,请记住以下缺点

> - 这是一种晦涩的、不广为人知的初始化方法
> - 每次使用时都会创建一个额外的类
> - 不支持“钻石操作符”(Java 7引入的特性)
> - 如果要扩展的类被标记为final,则无法使用
> - 会持有对封闭实例的隐藏引用,可能导致内存泄漏

英文:

When you use double braces initialization, behind the scene you're making an anonymous inner class that extends ValidationResult class.

In Java, you're not allowed to extend classes with final keyword, hence the compilation error you're seeing.

Also, keep in mind the following drawbacks when using double braces initialization:

> - Obscure, not widely known way to do the initialization
> - It creates an extra class every time we use it
> - Doesn’t support the use of the “diamond operator” – a feature introduced in Java 7
> - Doesn't work if the class we are trying to extend is marked final
> - Holds a hidden reference to the enclosing instance, which may cause memory leaks

huangapple
  • 本文由 发表于 2020年9月12日 04:46:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/63854108.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定