具有泛型的Java Copy构造函数

jay*_*jay 13 java generics

这之前可能已经被问了一百万次,但是我在使用有界类型参数在抽象类上编写复制构造函数时遇到了麻烦.我有一些看起来像这样的代码:

public abstract class Superclass<T> {
    Set<? extends Variable<T>> vars;

    public abstract Superclass<? extends T> copy();

    class Variable<T> {
        T value;
    }
}

class Foo extends Superclass<Integer> {
    public Foo copy() {
        Foo _newFoo = Foo();
        Set<FooVariable> _newVars = new HashSet<FooVariable>();
        _newVars.addAll(this.vars);
        _newFoo.vars = _newVars;
    }

    class FooVariable extends Variable<Integer> { /* ... */ }
}

class Bar extends Superclass<String> {
    public Bar copy() {
        Bar _newBar = Bar();
        Set<BarVariable> _newVars = new HashSet<BarVariable>();
        _newVars.addAll(this.vars);
        _newBar.vars = _newVars;
    }

    class BarVariable extends Variable<String> { /* ... */ }
}
Run Code Online (Sandbox Code Playgroud)

由于copy两种方法FooBar是除了变量类型是相同的,我想能够代码移动到在超类中的具体方法.但我想不出(一)如何有具体的public Superclass<? extends T> copy方法返回一个Foo实例,如果叫上一个FooBar例如,如果叫上一个Bar和(B)填充vars组与FooVariableS或BarVariableS作为适当.

有人可以帮忙告诉我我错过了什么吗?谢谢.

rge*_*man 0

引入第二个泛型类型参数来表示Variable<T>, U

然后,Foo.FooVariable<T>Bar.BarVariable<T>满足 和 的界限U,可以从该方法返回copy

编辑

我已经更改了代码以将 的实现移至copy超类中。它依赖于一种newInstance方法(已由 @OndrejBozek 引入)。

public abstract class Superclass<T, U extends Variable<T>> {
    Set<U> vars;

    class Variable<T> {
        T value;
    }

    public Superclass<T, U> copy() {
        Superclass<T, U> _newSuperclass = newInstance();
        Set<U> _newVars = new HashSet<U>();
        _newVars.addAll(vars);
        _newSuperclass.vars = _newVars;
       return _newSuperclass;
    }

    public abstract Superclass<T, U> newInstance();
}

class Foo extends Superclass<Integer, Foo.FooVariable> {
    public Foo newInstance() { return new Foo(); }

    class FooVariable extends Variable<Integer> { /* ... */ }
}

class Bar extends Superclass<String, Bar.BarVariable> {
    public Bar newInstance() { return new Bar(); }

    class BarVariable extends Variable<String> { /* ... */ }
}
Run Code Online (Sandbox Code Playgroud)