泛型多种类型

时间:2009-12-22 05:51:05

标签: java generics

将方法定义为

myMethod(Object... obj){}

允许使用任意数量和类型的参数。

我喜欢使用泛型来严格定义参数的数量和类型。

例如,假设上面提到的myMethod(Object...)是名为MyClass的类中的方法,MyClass可以通过默认构造函数实例化。

我需要以类似于此的方式定义实例:

MyClass<Integer, Integer, String> instance1 = new MyClass<Integer, Integer, String>();
MyClass<String, String, Integer, Integer> instance2 = new MyClass<String, String, Integer, Integer>();

因此上面的类型定义将设置调用myMethod()时允许的参数数量和类型:

instance1.myMethod(1, 2, "test");
instance2.myMethod("one", "two", 1, 2);

问题是:如何以允许任何数量的类型参数的方式定义MyClass

任何建议都将受到赞赏。

6 个答案:

答案 0 :(得分:4)

你不能,每个类固定类型参数的数量。你可以玩疯狂的技巧

class Tuple
{ 
    Object[] objects() { return ...; }
}
class Tuple1 ...
class Tuple2 ...
class Tuple3<T1,T2,T3> extends Tuple
{
    static public<S1,S2,S3> Tuple3<S1,S2,S3> of(S1 o1, S2 o2, S3 o3){ return ...; }
}
class Tuple4<T1,T2,T3,T4> extends Tuple
{
    static public<S1,S2,S3,S4> Tuple4<S1,S2,S3,S4> of(S1 o1, S2 o2, S3 o3, S4 o4){ return ... ; }
}
...
class Tuple9 ...

class MyClass<TupleN extends Tuple>
{
    void myMethod(TupleN ntuple)
    {
        Object[] objects = ntuple.objects();
        // work on objects
    }
}

MyClass<Tuple3<Integer,Integer,String>> instance3 = new MyClass<Tuple3<Integer, Integer, String>>();
instance3.myMethod( Tuple3.of(1,2,"test") );

不值得。有时为了简单起见,你必须放弃无关的类型检查。

答案 1 :(得分:3)

我不认为你想要做的事情可以实现,但也许你可以说明myMethod()做了什么?

答案 2 :(得分:3)

重点是什么?我无法想象这将是有用的场景,并且是可用的最佳解决方案。我不是要贬义,但值得一提的是你应该订阅KISS principle。听起来你正在成为过度工程的牺牲品,它正在创造代码味道。

可能有用的替代设计模式是Builder pattern。维基页面示例不是很好,但您应该阅读有关构建器的Effective Java部分。构建器将通过将mutator方法链接在一起并通过构建器方法调用私有构造函数来帮助创建使用必需和/或可选参数构造的不可变对象:

public class MyClass {

    private final String string1;
    private final String string2;
    private final int int1;
    private final int int2;

    private MyClass(Builder builder) {
        this.string1 = builder.string1;
        this.string2 = builder.string2;
        this.int1 = builder.int1;
        this.int2 = builder.int2;
    }

    public String getString1() {
        return string1;
    }

    public String getString2() {
        return string2;
    }

    public int getInt1() {
        return int1;
    }

    public int getInt2() {
        return int2;
    }

    public static class Builder {
        private String string1;
        private String string2;
        private int int1;
        private int int2;

        // set required parameters in the constructor
        public Builder() { }

        public Builder string1(String string1) {
            this.string1 = string1;
            return this;
        }

        public Builder string2(String string2) {
            this.string2 = string2;
            return this;
        }

        public Builder int1(int int1) {
            this.int1 = int1;
            return this;
        }

        public Builder int2(int int2) {
            this.int2 = int2;
            return this;
        }

        public MyClass build() {
            return new MyClass(this);
        }
    }
}

您可以构建一个这样的对象:

MyClass myClass = new MyClass.Builder().string1("sample1").string2("sample2").int1(1).int2(2).build();

或(使用相同的课程)

MyClass myClass = new MyClass.Builder().string1("sample1").int1(1).build();

这些都是可怕的方法名称,但是我要离开你的假设场景。

答案 3 :(得分:3)

答案 4 :(得分:0)

你可以试试这个:

班级类型:MyClass <List<?>>

答案 5 :(得分:0)

您必须满足于myMethod(Object...)MyClass的实例甚至不知道运行时的参数类型。