在Java泛型类中,在构造函数级别添加额外的通用约束?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在Java泛型类中,在构造函数级别添加额外的通用约束?相关的知识,希望对你有一定的参考价值。

我有一个名为Bar的接口和一个在Foo类型上参数化的泛型类Bar

class Foo<B extends Bar> { }

我的类有一个通用的构造函数,需要一个Class和一个Stream

class Foo<B extends Bar> {
    B[] bs;
    Foo(Class<B> clazz, Stream<B> stream) { // General ctor
        bs = someFunctionOf(clazz, stream);
    }
}

我正在尝试添加一个专门的构造函数,它要求它的实际方法参数都是Barenum类,以便我可以从特殊构造函数调用我的通用构造函数:

class Foo<B extends Bar> {
    B[] bs;
    Foo(Class<B> clazz, Stream<B> stream) { // General ctor
        bs = someFunctionOf(clazz, stream);
    }
    // FIX THIS ----+
    //              |
    //              ˅
    Foo(Class<Something> clazz) { // Special ctor
        // Can we make this work so Something is a Bar and an enum
        // and we can call the other constructor like this?
        this(clazz, Arrays.stream(clazz.getEnumConstants());
    }
}
答案

一般来说,您可以编写通用构造函数。我们最近有a question about them, and how they might be useful。通过这种方式,您可以提供一个构造函数,该构造函数将一个类作为参数,该类表示一个类,该类既扩展了某个特定的其他类又实现了接口Bar

class Foo<B extends Bar> {
    B[] bs;
    Foo(Class<B> clazz, Stream<B> stream) { // General ctor
        bs = someFunctionOf(clazz, stream);
    }

    private B[] someFunctionOf(Class<B> clazz, Stream<B> stream) {
        return null;
    }

    <T extends SomeClass & Bar> Foo(Class<T> clazz) {
        // ...
    }
}

但这并不能让你达到你想要的位置,因为构造函数的类型参数T的界限需要是显式类型。类型变量(例如类的类型参数B)不提供,并且没有办法将T连接到B,特殊的泛型构造函数不能调用常规构造函数。

但您可以使用工厂方法而不是特殊构造函数来执行此操作:

class Foo<B extends Bar> {
    B[] bs;
    Foo(Class<B> clazz, Stream<B> stream) { // General ctor
        bs = someFunctionOf(clazz, stream);
    }

    private B[] someFunctionOf(Class<B> clazz, Stream<B> stream) {
        return null;
    }

    static <T extends Enum<T> & Bar> Foo<T> createEnumFoo(Class<T> clazz) {
        return new Foo<>(clazz, Arrays.stream(clazz.getEnumConstants()));
    }
}
另一答案

我不认为你可以用构造函数做到这一点。创建子类:

class EnumFoo<B extends Enum<B>&Bar> extends Foo<B> {
    public EnumFoo(Class<B> clazz) {
        super(clazz, Arrays.stream(clazz.getEnumConstants()));
    }
}

或工厂方法:

public static <T extends Enum<T>&Bar> Foo<T> of(Class<T> clazz) { 
    return new Foo<>(clazz, Arrays.stream(clazz.getEnumConstants()));
}
另一答案

这可以通过使用&运算符来实现:<Something extends Bar & Enum<?>>

以上是关于在Java泛型类中,在构造函数级别添加额外的通用约束?的主要内容,如果未能解决你的问题,请参考以下文章

在Java中实例化一个泛型类[重复]

Kotlin泛型 ① ( 泛型类 | 泛型参数 | 泛型函数 | 多泛型参数 | 泛型类型约束 )

Java泛型详解

iPhone - 在泛型类中引用应用程序委托

Java泛型详解

Java 无类型泛型类,删除它们的函数泛型类型