在Java中,我可以指定任意数量的泛型类型参数吗?
我希望用Java创建一种特殊类型的接口(尽管这同样适用于常规类)。这个接口需要包含一些方法,比如,在Java中,我可以指定任意数量的泛型类型参数吗?,java,generics,Java,Generics,我希望用Java创建一种特殊类型的接口(尽管这同样适用于常规类)。这个接口需要包含一些方法,比如,invoke;根据提供的泛型类型参数,将使用不同数量的参数调用它 例如: public interface Foo<T...> { public void invoke(T... args); } // In some other class public static Foo<Float, String, Integer> bar = new Foo<Flo
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
}
};
公共接口Foo{
公共无效调用(T…args);
}
//在别的班
公共静态Foo bar=newfoo(){
@凌驾
公共void调用(浮点arg1、字符串arg2、整数arg3){
//做任何事
}
};
简要解释,如何使用(并提供一些上下文),考虑类<代码>委托者< /代码>:该类采取不同数量的泛型类型,并使用这些参数类型有一个单独的方法-<代码>调用< /COD>。该方法将其参数传递给列表中的对象:采用相同泛型类型的
IDelegate
实例。这允许Delegator
在多个委托方法(在IDelegate
中定义)之间进行选择,而无需为每个特定的参数类型列表创建新类
有这样的吗?我已经阅读了有关C++的内容,但是在java中找不到类似的东西。有这样的东西吗?如果不是,那么最干净的方法是什么来模拟相同的数据模型
有这样的吗?我读过关于可变模板的书
在C++中,但是在java中找不到类似的东西。有这样的事吗
有空吗
不,此功能在Java中不可用。不,没有类似的功能可以直接使用。但是,如果将库与
Tuple
类一起使用,则只需制作接口即可对其进行模拟
interface Foo<T> {
void invoke(T t);
}
通过以这种方式嵌套元组类型,可以获得无限数量的参数。但是,这些变通方法非常难看,我不会使用它们。鉴于您提供的上下文,我建议使用
列表作为参数。如果这些参数有共同点,您可以将列表限制为
,而不是使用列表
。如果不是,您可能仍然希望使用标记接口
这里有一个例子
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;
}
}
公共类主{
公共静态void main(字符串[]args){
代表(asList(新子女一(1)、新子女二(5)、新子女一(15));
}
私有静态无效委托(列表){
列表。forEach(项目->{
开关(项目类型){
案例一:委托人((ChildOne)项);中断;
案例二:授权二((ChildTwo)项;中断;
默认值:抛出新的UnsupportedOperationException(“类型不受支持:”+item.Type);
}
});
}
私有静态void delegateOne(ChildOne ChildOne){
System.out.println(“child-one:x=“+childOne.x”);
}
私有静态void delegateTwo(ChildTwo ChildTwo){
System.out.println(“child-two:abc=“+childTwo.abc”);
}
}
公共类父类{
公共最终类型;
公共父级(类型){
this.type=type;
}
}
公共枚举类型{
一,二
}
公共类ChildOne扩展了Parent{
公共最终int x;
公共儿童频道(int x){
超级(1型);
这个.x=x;
}
}
公共类ChildTwo扩展了Parent{
公开期末考试;
公共儿童2(国际abc){
超级(2型);
this.abc=abc;
}
}
此解决方案的最大缺陷是,子级必须通过enum指定其类型,该类型应与switch语句中的强制转换相对应,因此无论何时更改这两个位置之一,都必须记住更改另一个位置,因为编译器不会告诉您这一点。只有通过运行代码并执行特定的分支,您才会发现这样的错误,因此建议进行测试驱动开发。换句话说:Pair
就足够了。但是,由于没有人想要一对,
,这样的问题通常会以不同的方式解决。要么完全删除类型安全性,要么使用类似的库
Foo<Tuple<String, Integer, Date, Pair<Long, BigDecimal>>> foo = ...
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;
}
}