gpt4 book ai didi

java在泛型方法中使用this(继承)

转载 作者:行者123 更新时间:2023-11-30 06:16:44 26 4
gpt4 key购买 nike

在创建在父类中使用的 lambda 时,我试图访问子类方法和字段。代码更容易解​​释:

class Parent {
List<Processor<? extends Parent>> processors;

private void doSmth() {
for (Processor<? extends Parent> processor : processors) {
processor.doJob(this); //this lines gives compile error
}
}

public void registerListeners(Processor<? extends Parent> ... subscribers) {
this.subscriberList = Arrays.asList(subscribers);
}
}

其中处理器FunctionalInterface

public interface Processor<T extends Parent> extends BiFunction<T, Message,  Boolean> {
AtomicReference<Boolean> ok = new AtomicReference<>(false);

default void doJob(T client, Message message) {
if (apply(client, message))
ok.set(true);
}

default boolean isDone() {
return ok.get();
}
}

这些类的所需用法示例:

Child childInstance= new Child(); //where Child class extends Parent
childInstance.registerListeners((child, message) -> child.callSomeChildMethod());
childInstance.doSmth(message);

创建 lambda 而不需要像这一行那样冗余地指定参数类型,这真的很酷:

childInstance.registerListeners((Processor<Child>) (child, message) -> child.callSomeChildMethod());

(因为它始终应该是我注册监听器的类型)
问题是代码无法编译,并出现错误
不兼容的类型:父项无法转换为 capture#1 of ? extends Parent
这是非常合乎逻辑的(我理解原因)。 java中有什么方法可以让这个代码工作吗?
提前致谢!

最佳答案

您对 List<Processor<? extends Parent>> processors; 的想法在Parent类不建议。正如您所看到的,由于您没有提到列表中的进程类型;无论您调用 processor.doJob(anyObjectHere)会以一种或另一种方式抛出错误(除非您进行显式强制转换)

尝试做这样的事情;

  1. 声明 Client而不是你的Parent其中包含 List<Processor<? extends Parent>> processors 中的处理器类型;

    abstract class Client<T extends Client<T>> {
    List<Processor<T>> processors;

    public void doSmth(Message message) {
    for (Processor<T> processor : processors) {
    processor.doJob(getThis(), message);
    }
    }

    abstract T getThis();

    public void registerListeners(Processor<T> subscribers) {
    this.processors = Arrays.asList(subscribers);
    }
    }
  2. 更改您的 Processor合并的定义Client而是Parent

    interface Processor<T extends Client<T>> extends BiFunction<T, Message,  Boolean> {
    AtomicReference<Boolean> ok = new AtomicReference<>(false);

    default void doJob(T client, Message message) {
    if (apply(client, message))
    ok.set(true);
    }

    default boolean isDone() {
    return ok.get();
    }
    }
  3. 现在您可以创建您的 Child像这样;

    class Child extends Client<Child> {
    boolean callSomeChildMethod() {
    return true;
    }

    @Override
    Child getThis() {
    return this;
    }
    }
  4. 并像以前一样调用它们;

        Child childInstance= new Child(); //where Child class extends Parent
    childInstance.registerListeners((child, message) -> child.callSomeChildMethod());
    childInstance.doSmth(message);

这样你就不会出现编译错误或警告

关于java在泛型方法中使用this(继承),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49031909/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com