当前位置: 首页 > 知识库问答 >
问题:

更改不可变的构建器构造函数以使用泛型

司空俊雅
2023-03-14

我有一个下面的类,它是子类的基本DTO。我需要修复受保护的构造函数,因为Intellij说:“参数化类生成器的原始使用”。有人可以看看,并指出如何重新编写这个构造函数,以支持通用风格在这里。

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;

import java.util.List;
import java.util.Objects;

import static com.fasterxml.jackson.annotation.JsonProperty.Access.READ_ONLY;

@JsonDeserialize(builder = PageableResponse.Builder.class)
public class PageableResponse<T>
{
    @JsonProperty(value = "data", required = true, access = READ_ONLY)
    private final List<T> data;
    @JsonProperty(value = "total", required = true, access = READ_ONLY)
    private final Long total;

    // constructor required for spring
    public PageableResponse(List<T> data, Long total)
    {
        this.data = data;
        this.total = total;
    }

    // here is an issue: Raw use of parameterized class Builder
    protected PageableResponse(Builder builder)
    {
        data = (List<T>) builder.data; // and here unchecked cast as well
        total = builder.total;
    }

    public static <T extends Builder<T>> Builder<T> newBuilder()
    {
        return new Builder<T>();
    }

    public static <T extends Builder<T>> Builder<T> newBuilder(PageableResponse<T> copy)
    {
        Builder<T> builder = new Builder<T>();
        builder.data = copy.getData();
        builder.total = copy.getTotal();
        return builder;
    }

    public List<T> getData()
    {
        return data;
    }

    public Long getTotal()
    {
        return total;
    }

    @Override
    public boolean equals(Object o)
    {
        if (this == o)
        {
            return true;
        }
        if (o == null || getClass() != o.getClass())
        {
            return false;
        }
        PageableResponse<?> that = (PageableResponse<?>) o;
        return Objects.equals(data, that.data) && Objects.equals(total, that.total);
    }

    @Override
    public int hashCode()
    {
        return Objects.hash(data, total);
    }

    @JsonPOJOBuilder(withPrefix = "")
    public static class Builder<T extends Builder<T>>
    {
        private List<T> data;
        private Long total;

        protected Builder()
        {
        }

        public Builder<T> data(List<T> data)
        {
            this.data = data;
            return this;
        }

        public Builder<T> total(Long total)
        {
            this.total = total;
            return this;
        }

        public PageableResponse<T> build()
        {
            return new PageableResponse<T>(this);
        }
    }
}

你觉得可能吗?有人看到此代码的潜在问题吗?感谢先进。

共有1个答案

乌灿
2023-03-14

您可以通过向PageResponse(Builder)构造函数添加类型参数来修复警告。

protected PageableResponse(Builder<T> builder)

此外,您的Builder的类型参数定义有点奇怪。

public static class Builder<T extends Builder<T>>

暗示T必须是Builder

public static class Builder<T>

意味着T可以是任何东西。可能更有意义?

 类似资料:
  • 问题内容: 如果我有一个像这样的抽象类: 还有一些从Item派生的类是这样的: 我不明白为什么我不能使用泛型调用构造函数: 我知道可以有一个没有构造函数的类型,但是这种情况是不可能的,因为Pencil具有没有参数的构造函数,而Item是抽象的。但是我从eclipse中得到了这个错误: 无法实例化 我不明白为什么的 T类型 ,以及如何避免这种情况? 问题答案: 无法使用Java类型系统来强制类层次结

  • 问题内容: 我有一些大对象(超过3个字段),它们可以并且应该是不变的。每次遇到这种情况时,我倾向于使用长参数列表创建构造函数可憎的对象。 感觉不对,很难使用,并且可读性受到影响。 如果字段是某种类型的集合类型(如列表),那就更糟了。一个简单的方法可以极大地简化对象的创建过程,但是使对象可变。 你们在这种情况下使用什么? 我使用的是Scala和Java,但我认为只要语言是面向对象的,问题就与语言无关

  • @adilooze解决方案

  • 问题内容: 我所知道的是,编译器在字节码中编写了一个默认的无参数构造函数。但是,如果我们自己编写,则该构造函数会自动调用。这种现象是构造函数压倒一切的吗? 问题答案: 您所描述的不是最重要的。如果您未指定默认构造函数,则编译器将创建一个默认构造函数。如果是子类,它将调用默认的父构造函数(super()),还将所有实例变量初始化为由该类型的默认值确定的默认值(数字类型为0,布尔值为false,对象为

  • 问题内容: 如何构建接收另一个点(x,y)并复制其值的复制构造函数? 我决定签名:,但我不知道该写些什么… Point类看起来像: 我试过了: 但我几乎可以肯定我会做得更好。 n 问题答案: 不,您的尝试 绝对没问题…(我已经更正了参数类型。) 我很想进行make 和final的操作,并且使该类final的操作,但这是因为我喜欢不可变的类型。其他人肯定有不同意见:) 在继承层次结构上进行克隆比较棘

  • 问题内容: 我一直认为无需调用构造函数即可创建对象。 但是,在 明智地 阅读《有效的Java 项目11:覆盖克隆》时 ,我发现了一条声明,指出 “没有调用构造函数”的规定太强了。行为良好的克隆方法可以调用构造函数来创建正在构建的克隆内部的对象。如果该类是最终的,则clone甚至可以返回由构造函数创建的对象。 有人可以向我解释一下吗? 问题答案: 我一直以为clone()会创建一个对象而不调用构造函