Java – avoid generic forms foo >

I often find myself writing generic class definitions for forms

public class Foo<ActualType extends Foo<ActualType>>

For example, in such a setting:

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
        }
    });
}

The change event here is just an example This is more like a common problem. Whenever I want a superclass to provide the function of "personalization" to each specific subclass (I don't know how to better phrase...) above "personalization", the fact is that the object of the actual subtype (bar) called by changehandler is not the type of the superclass (foo) calling the handler

Somehow, this method seems a little messy to me It actually allows potential problems because nothing prevents me from defining from there:

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

Is there a cleaner option?

The Grail will be some type parameter, which is always defined to contain the current class, just like the static version of this Like getClass (), you can let me write such code:

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);
    }
}

Here, the category of bar will be equal to bar

Solution

This is a very abstract problem In my opinion, the simple answer to "how to make this cleaner" is: just use generics

public class List<T extends List<T>>

Is this an attempt to express (replace)? Other lists that are only allowed to hold (t extension) themselves hold the list of TS (list). The list we knew before is only allowed to hold... And so on I can't see what will happen to you?

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

Why use generics here? If you want a change handler that can handle multiple resource types, you can create a super class from which all actual sources inherit, or create an interface implemented by the source In this way, you can specify exactly what the resource exposes Alternatively, the source can create the source object at notification time instead of passing "this" (and then it's more like a message) For example:

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();
    }
}

You don't need to cast... Or you? I don't know if I understand the problem

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>