java - 使方法返回类型泛型

标签 java generics

我有以下具有 builder() 方法的管理器类:

public class Manager extends Employee {

    public static Manager.Builder builder() {
        return new ManagerBuilder();
    }

    public abstract static class Builder<T extends Employee, B extends Builder<T,B>> extends Employee.Builder<T,B>{
    }

    public static class ManagerBuilder extends Builder<Manager,ManagerBuilder> {

    @Override
    protected ManagerBuilder self() {
        return this;
    }

        @Override
    public Manager build() {
        return new Manager(this);
    }
    }
}

不幸的是,尝试使用 Manager.builder().age(25).build(); 构建一个对象 返回一个 Person 而不是我需要的 Manager

我应该如何更改 Manager.builder() 返回类型以返回 Manager,同时不与 Employee.builder() 方法签名冲突。

代码Employee.builder().age(25).build();返回Employee,这很好。

Employee 类如下所示:

public class Employee extends Person {

    public static Employee.Builder<Employee, EmployeeBuilder> builder() {
        return new EmployeeBuilder();
    }

    public abstract static class Builder<T extends Person, B extends Builder<T,B>> extends Person.Builder<T,B>{

    }

    public static class EmployeeBuilder extends Builder<Employee, EmployeeBuilder> {

    @Override
    protected EmployeeBuilder self() {
        return this;
    }
    @Override
    public Employee build() {
        return new Employee(this);
    }
    }

}

public class Person implements PersonInterface {

    private Optional<Integer> age;

    protected Person(Builder<?,?> builder) {
        this.age = builder.age;
        }

    public abstract static class Builder<T extends Person, B extends Builder<T,B>> {
        private Optional<Integer> age;

        protected Builder() {
        }

        public B age(Integer age) {
            if (Objects.isNull(age) || age == 0)  throw new IllegalArgumentException("Age ist empty");
            this.age = Optional.of(age);
            return self();
        }

        protected abstract B self();
        public abstract T build();
    }

    public static class PersonBuilder extends Builder<Person, PersonBuilder>{

        @Override
        protected PersonBuilder self() {
            return this;
        }

        @Override
        public Person build() {
            return new Person(this);
        }
    }

}

最佳答案

核心问题是你奇怪的继承结构,它重载了类名Builder。我无法完全确定问题,但在某些时候您的 ManagerBuilder 的特定类型信息丢失了。这可以简单化很多:

public class Employee extends Person {

    public static EmployeeBuilder builder() {
        return new EmployeeBuilder();
    }

    public static class EmployeeBuilder extends Person.Builder<Employee, EmployeeBuilder> {

        @Override
        protected EmployeeBuilder self() {
            return this;
        }

        @Override
        public Employee build() {
            return new Employee(this);
        }
    }
}

public class Manager extends Employee {

    public static ManagerBuilder builder() {
        return new ManagerBuilder();
    }

    public static class ManagerBuilder extends Person.Builder<Manager, ManagerBuilder> {

        @Override
        protected ManagerBuilder self() {
            return this;
        }

        @Override
        public Manager build() {
            return new Manager(this);
        }
    }
}

这应该可以解决您的一些问题。

现在你还面临一个问题。静态方法 builder 因返回类型不兼容而重载。您可以在Why does Java enforce return type compatibility for overridden static methods?找到相关信息。 如果您以不同的方式命名这些方法,它应该可以工作。

关于java - 使方法返回类型泛型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49551228/

相关文章:

java - 在 VSCode 中使用 Formatter 写入文件

java - StringBuffer类与汉字编码

wcf - 如何控制通用 WCF 返回类型的名称?

generics - 我可以使用泛型来利用密封类的优势吗?

c# - 使用 IEnumerable 和多重继承时出现 BadImageFormatException

java - 在 java 中使用泛型时设置 intellij 询问类型参数

java - 使用 JPA Hibernate 创建 MySQL 存储过程

java - lucene/hibernate : @FullTextFilterDef not working with FilterFactory

java - JodaTime:两个日期之间的工作日数

c# - 索引器继承在泛型中如何工作?