java – 避免泛型的形式Foo>

前端之家收集整理的这篇文章主要介绍了java – 避免泛型的形式Foo>前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我经常发现自己想编写表单的泛型类定义
public class Foo<ActualType extends Foo<ActualType>>

例如在这样的设置中:

public interface ChangeHandler<SourceType> {
    public void onChange(SourceType source);
}


public class Foo<ActualType extends Foo<ActualType>> {

    private final List<ChangeHandler<ActualType>> handlers = new ArrayList<>();

    public void addChangeHandler(ChangeHandler<ActualType> handler) {
        handlers.add(handler);
    }

    @SuppressWarnings("unchecked")
    protected void reportChange() {
        for (ChangeHandler<ActualType> handler: handlers)
            handler.onChange((ActualType) this);
    }
}


public class Bar extends Foo<Bar> {
    // things happen in here that call super.reportChange();
}


public static void main(String[] args) throws IOException {

    Bar bar = new Bar();
    bar.addChangeHandler(new ChangeHandler<Bar>() {

        @Override
        public void onChange(Bar source) {
            // Do something with the changed object
        }
    });
}

这里的更改事件只是一个例子.这更像是一个普遍的问题,每当我想让一个超级类提供“个性化”到每个特定子类的功能(不知道如何更好地在这个例子中进行短语…)在“个性化”之上的事实是,ChangeHandler被调用的实际子类型(Bar)的对象不是调用处理程序的超类(Foo)的类型.

不知怎的,这种方法对我来说似乎有点凌乱.它实际上允许潜在的问题,因为没有什么可以阻止我从那里定义:

public class Baz extends Foo<Bar> { /* ... */ }

有没有更清洁的选择?

圣杯将是一些类型参数,它始终被定义为包含当前类,就像静态版本的this.getClass()一样,可以让我写这样的代码

public class Foo {

    private final List<ChangeHandler<this.Class>> handlers = new ArrayList<>();

    public void addChangeHandler(ChangeHandler<this.Class> handler) {
        handlers.add(handler);
    }

    protected void reportChange() {
        for (ChangeHandler<this.Class> handler: handlers)
            handler.onChange(this);
    }
}

这里的类别Bar的类别将等于Bar.

解决方法

这是一个非常抽象的问题.在我看来,“如何使这个更清洁”的简单答案是:只需要使用泛型.
public class List<T extends List<T>>

这是试图表达(取代)?只允许持有(T扩展)的其他列表本身持有Ts(List)的列表,我们以前知道的列表只允许持有…等等.那种圆形的,我看不出你会怎么样呢?

public interface ChangeHandler<SourceType> {
    public void onChange(SourceType source);
}

为什么要在这里使用泛型?如果您想要一个可以处理多种资源类型的更改处理程序,那么您可以创建一个超级类,所有实际的源都从该类继承,或者创建一个由源实现的接口.像这样,您可以准确地指定资源所暴露的内容.或者,源可以在通知时创建源对象,而不是传递“this”(然后它更像是一条消息).例如:

public interface ChangeHandler {
    public void onChange(Source source);
}

public abstract class Source {
    private List<ChangeHandler> handlers;
    protected int nr;
    public Source(int nr) {
      this.nr = nr;
    }
    public abstract Something getSomething();
    public String toString() {
        return "SRC" + nr;
    }
    ...
    private notify(int index) {
        handlers.get(i).onChange(this);
    }
}

public class Foo extends Source {
    public Foo(int nr) {
        super(nr);
    }
    public String toString() {
        return super.toString() + "Foo";
    }
    public Something getSomething() {
        return new Something();
    }
}

你不需要投下…还是你呢?我不知道我是否明白问题.

猜你在找的Java相关文章