首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Generics创建参数类

使用Generics创建参数类
EN

Stack Overflow用户
提问于 2012-11-08 05:33:10
回答 2查看 141关注 0票数 2

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

代码语言:javascript
复制
public interface Computable { 
    public Result compute(Foo foo);
}

我还想将一组参数传递给可以剥离的计算。我可以破解这个问题,但是我想知道genericsvar args是否有一个优雅的解决方案。就像..。

代码语言:javascript
复制
 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;
    }    
}

但是,我不知道如何从参数列表中遍历每个参数,我可以简单地得到键值对及其类型推断。有人能帮我吗?这不是已经内置到JDK中了吗?

用示例编辑

在一个具体的实施中我们应该..。

代码语言:javascript
复制
public Result compute(Foo foo,
                      Parameter ...parameters) {

    // Here I'd like to get each parameter, and have it know it's key type and value type
    for(Parameter p : parameters) {
        p.getKey();
        p.getValue()
        //implementers know what to do with their parameters
    }


}
EN

回答 2

Stack Overflow用户

发布于 2012-11-08 05:57:04

作为AmitD mentioned in the comments,您应该使Computable成为一个参数化类型:

代码语言:javascript
复制
public interface Computable<K, V> { 
    public Result compute(Foo foo, Parameter<K, V>... parameters);
}

然后,一个实现将解析KV,并知道其类型:

代码语言:javascript
复制
public class BarBazComputable implements Computable<Bar, Baz> {
    @Override
    public Result compute(Foo foo, Parameter<Bar, Baz>... parameters) {
        ...
    }
}

编辑:和yes,正如AmitD再次提到的,您不需要解析任何一个或所有类型参数:

代码语言:javascript
复制
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) {
        ...
    }
}

请注意,varargs对泛型不友好,在调用compute时,您将在调用站点上得到类型安全警告。相反,考虑让该方法接受一个Iterable<Parameter<K, V>>

票数 3
EN

Stack Overflow用户

发布于 2012-11-08 06:54:40

如果对于不同的参数或不同的值类型有不同的键类型,那么很可能无法用一个简单的泛型varargs函数定义来解决这个问题。那么,您唯一的类型安全选项是这样的:

代码语言:javascript
复制
public Result compute(Foo foo, Parameter<Byte, Byte> p1, Parameter<Byte, Float> p2, ...)

(在这里“.”表示以相同方式添加的进一步参数,而不是varargs椭圆)

但是,如果您需要灵活,并且您可以通过探测“参数”的其他属性来确定所处理的键和值类型,那么我有时会使用一个技巧来简化类型转换:将Parameter类中的Parameter函数更改为:

代码语言:javascript
复制
@SuppressWarnings("unchecked")
public <KeyType> KeyType getKey() {
    return (KeyType) this.key;
}

(与getValue()函数类似)

这样,您可以简单地将getKey()的结果赋值给任何(非原始)类型的变量,如下所示:

代码语言:javascript
复制
Integer key = parameter.getKey();

代码语言:javascript
复制
String key = parameter.getKey();

你不需要在计算函数中进行任何类型的转换,也不会有任何警告。

但是:您将释放编译时类型check!,因此,您必须确保在运行时(无论如何都必须这样做),您不会为一个类型错误的变量分配密钥。或者至少优雅地处理结果ClassCastException。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13283067

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档