Java 使用泛型创建参数类

Java 使用泛型创建参数类,java,generics,parameters,variadic-functions,Java,Generics,Parameters,Variadic Functions,我有一个接口,它定义了一个进行一些计算的方法 public interface Computable { public Result compute(Foo foo); } 我还想将一组参数传递给可以剥离的计算。我可以解决这个问题,但我想知道是否有一个优雅的解决方案,包括泛型和var args。类似于 public class Parameter<K,V> { private final K key; private final V value;

我有一个接口,它定义了一个进行一些计算的方法

public interface Computable { 
    public Result compute(Foo foo);
}
我还想将一组参数传递给可以剥离的计算。我可以解决这个问题,但我想知道是否有一个优雅的解决方案,包括
泛型
var args
。类似于

 public class Parameter<K,V> {

    private final K key;
    private final V value;

    public Parameter(K key, V value) {
        this.key = key;
        this.value = value;
    }

    public K getKey() {
        return this.key;
    }

    public V getValue() {
        return value;
    }    
}
如前所述,您应该将
Computable
设置为参数化类型:

public interface Computable<K, V> { 
    public Result compute(Foo foo, Parameter<K, V>... parameters);
}
Edit:是的,正如AmitD再次提到的,您不需要解析其中一个或所有类型参数:

public class WithStringComputable<K> implements Computable<K, String> {
    @Override
    public Result compute(Foo foo, Parameter<K, String>... parameters) {
        ...
    }
}

public class OhJustACoupleObjectsComputable<K, V> implements Computable<K, V> {
    @Override
    public Result compute(Foo foo, Parameter<K, V>... parameters) {
        ...
    }
}

public class NumbersComputable<N1 extends Number, N2 extends Number> implements Computable<N1, N2> {
    @Override
    public Result compute(Foo foo, Parameter<N1, N2>... parameters) {
        ...
    }
}
带有字符串可计算的公共类实现可计算{
@凌驾
公共结果计算(Foo-Foo,参数…参数){
...
}
}
公共类OhJustACoupleObjectsComputable实现可计算{
@凌驾
公共结果计算(Foo-Foo,参数…参数){
...
}
}
公共类NumberComputeable实现了Computeable{
@凌驾
公共结果计算(Foo-Foo,参数…参数){
...
}
}
请注意,varargs不能很好地处理泛型,当调用
compute
时,您将在调用站点收到类型安全警告。取而代之的是,考虑该方法采用<代码>可迭代< /COD> .< /P> < P> AS,您应该使<代码>可计算< /Cord>参数化类型:

public interface Computable<K, V> { 
    public Result compute(Foo foo, Parameter<K, V>... parameters);
}
Edit:是的,正如AmitD再次提到的,您不需要解析其中一个或所有类型参数:

public class WithStringComputable<K> implements Computable<K, String> {
    @Override
    public Result compute(Foo foo, Parameter<K, String>... parameters) {
        ...
    }
}

public class OhJustACoupleObjectsComputable<K, V> implements Computable<K, V> {
    @Override
    public Result compute(Foo foo, Parameter<K, V>... parameters) {
        ...
    }
}

public class NumbersComputable<N1 extends Number, N2 extends Number> implements Computable<N1, N2> {
    @Override
    public Result compute(Foo foo, Parameter<N1, N2>... parameters) {
        ...
    }
}
带有字符串可计算的公共类实现可计算{
@凌驾
公共结果计算(Foo-Foo,参数…参数){
...
}
}
公共类OhJustACoupleObjectsComputable实现可计算{
@凌驾
公共结果计算(Foo-Foo,参数…参数){
...
}
}
公共类NumberComputeable实现了Computeable{
@凌驾
公共结果计算(Foo-Foo,参数…参数){
...
}
}

请注意,varargs不能很好地处理泛型,当调用
compute
时,您将在调用站点收到类型安全警告。相反,考虑该方法采用<代码>可迭代< /代码> .< /p> 如果对于不同的参数或不同的值类型有不同的键类型,则可能无法用简单的通用VARARGS函数定义来解决此问题。您唯一的类型安全选项如下所示:

public Result compute(Foo foo, Parameter<Byte, Byte> p1, Parameter<Byte, Float> p2, ...)
Integer key = parameter.getKey();
(与getValue()函数类似)

这样,您只需将
getKey()
的结果分配给任何(非原语)类型的变量,如下所示:

public Result compute(Foo foo, Parameter<Byte, Byte> p1, Parameter<Byte, Float> p2, ...)
Integer key = parameter.getKey();

您不必在计算函数中执行任何类型转换,也不会出现任何警告


但是:您将丢失编译时类型检查因此,您必须确保在运行时(无论如何,您可能必须这样做)不会将键分配给错误类型的变量。或者至少优雅地处理生成的ClassCastException。

如果不同的参数或值类型具有不同的键类型,则可能无法通过简单的泛型varargs函数定义来解决此问题。您唯一的类型安全选项如下所示:

public Result compute(Foo foo, Parameter<Byte, Byte> p1, Parameter<Byte, Float> p2, ...)
Integer key = parameter.getKey();
(与getValue()函数类似)

这样,您只需将
getKey()
的结果分配给任何(非原语)类型的变量,如下所示:

public Result compute(Foo foo, Parameter<Byte, Byte> p1, Parameter<Byte, Float> p2, ...)
Integer key = parameter.getKey();

您不必在计算函数中执行任何类型转换,也不会出现任何警告



但是:您将丢失编译时类型检查因此,您必须确保在运行时(无论如何,您可能必须这样做)不会将键分配给错误类型的变量。或者至少要优雅地处理生成的ClassCastException。

请发布您想要/需要的方法的示例?您得到了什么异常?您可以声明接口以接受类型params
public interface computeable{
或方法以接受类型params
public void compute(对象foo,参数…参数)
我没有收到异常。getKey和getValue方法返回对象。我需要显式强制转换它们。我想我更大的问题是,这样做的最佳方法是什么?@AmitD我本来打算提供这个答案,但你应该继续并发布。请发布你想要/需要的方法的示例。什么异常n您得到了什么?您可以声明接口以接受类型params
public interface computeable{
或方法以接受类型params
public void compute(对象foo,参数…参数)
我没有收到异常。getKey和getValue方法返回对象。我需要显式强制转换它们。我想我更大的问题是,这样做的最佳方法是什么?@AmitD我本来打算提供这个答案,但你应该继续并发布它。但这不意味着我只能拥有键为B的参数吗ars和Baz的值?我很欣赏答案,我正在投票。我还不确定这就是我要找的。@AmirAfghani这是正确的,因为如果你想要不太具体的类型,那么你可以使用父类。但是这不意味着我只能有带有键的参数,这些键是条,而值是Baz的吗?我很欣赏answer和我正在投票。我不确定这是否是我正在寻找的。@AmirAfghani这是正确的,因为如果您想要不太特定的类型,那么您可以使用父类。或者如果您确实知道您的密钥是其他类型的子类型,比如您的示例中的K,您可以通过使用:public KeyType getKey()至少获得一点类型安全性{…KeyType类看起来像什么?@AmirAfghani它不是一个类。它只是一个占位符,上面写着“分配给什么”这是一个通用函数定义。例如,您可以这样做:public MyNum add(MyNum x,MyNum y)…它强制您为x和y传递相同的数字类型,并表示返回ty