在java中,我可以指定任意数量的泛型类型参数吗?

epfja78i  于 2021-06-30  发布在  Java
关注(0)|答案(3)|浏览(340)

我希望在java中创建一种特殊类型的接口(尽管这同样适用于常规类)。这个接口需要包含一些方法,比如, invoke ; 根据所提供的泛型类型参数,将使用不同数量的参数来调用它。
例如:

public interface Foo<T...> {
    public void invoke(T... args);
}

// In some other class
public static Foo<Float, String, Integer> bar = new Foo<Float, String, Integer>() {
    @Override
    public void invoke(Float arg1, String arg2, Integer arg3) {
        // Do whatever
    }
};

要简单地解释如何使用它(并提供一些上下文),请考虑一个类 Delegator :该类接受不同数量的泛型类型,并具有单个方法- invoke ,使用这些参数类型。方法将其参数传递给列表中的对象:的示例 IDelegate ,它采用相同的泛型类型。这允许 Delegator 在几个委托方法(定义在 IDelegate )无需为每个参数类型的特定列表创建新类。
有这样的吗?我读过c++中的可变模板,但在java中找不到类似的模板。有这种东西吗?如果不是,那么最干净的方法是什么来模拟相同的数据模型?

kiayqfof

kiayqfof1#

不,没有这样的东西可以直接买到。但是,如果您使用具有 Tuple 类,您可以通过创建接口来模拟它

interface Foo<T> {
    void invoke(T t);
}

(此接口与 Consumer<T> .)
那你可以做个例子

Foo<Tuple<String, Integer, Date, Long>> foo = new Foo<>() {
    ...
}

你需要一个单独的 Tuple 为每个参数数键入。如果你有 Tuple 为4个参数初始化,而不是为5个参数初始化,您可以使用 Pair 班级。

Foo<Tuple<String, Integer, Date, Pair<Long, BigDecimal>>> foo = ...

通过以这种方式嵌套元组类型,可以获得无限数量的参数。然而,这些解决方法真的很难看,我不会使用它们。

elcex8rz

elcex8rz2#

鉴于您提供的上下文,我建议使用 List 作为参数。如果这些参数有共同点,可以限制列表 <T extends CommonParrent> 而不是使用 List<Object> . 如果没有,您可能仍然希望使用标记接口。
下面是一个例子。

public class Main {

    public static void main(String[] args) {
        delegate(asList(new ChildOne(1), new ChildTwo(5), new ChildOne(15)));
    }

    private static <T extends Parent> void delegate(List<T> list) {
        list.forEach(item -> {
            switch (item.type) {
                case ONE: delegateOne((ChildOne) item); break;
                case TWO: delegateTwo((ChildTwo) item); break;
                default: throw new UnsupportedOperationException("Type not supported: " + item.type);
            }
        });
    }

    private static void delegateOne(ChildOne childOne) {
        System.out.println("child one: x=" + childOne.x);
    }

    private static void delegateTwo(ChildTwo childTwo) {
        System.out.println("child two: abc=" + childTwo.abc);
    }

}

public class Parent {
    public final Type type;

    public Parent(Type type) {
        this.type = type;
    }
}

public enum Type {
    ONE, TWO
}

public class ChildOne extends Parent {
    public final int x;

    public ChildOne(int x) {
        super(Type.ONE);
        this.x = x;
    }
}

public class ChildTwo extends Parent {
    public final int abc;

    public ChildTwo(int abc) {
        super(Type.TWO);
        this.abc = abc;
    }
}

此解决方案的最大缺陷是,子级必须通过enum指定其类型,enum应与switch语句中的强制转换相对应,因此每当您更改这两个位置中的一个时,都必须记住更改另一个位置,因为编译器不会告诉您这一点。只有通过运行代码并执行特定的分支才能发现这样的错误,因此建议进行测试驱动开发。

xpcnnkqh

xpcnnkqh3#

有这样的吗?我读过c++中的可变模板,但在java中找不到类似的模板。有这种东西吗?
不,此功能在java中不可用。

相关问题