[英]java using this in generic method (inheritance)
I'm trying to get access to child class methods and fields, when creating lambda, which is used in parent class.在创建在父类中使用的 lambda 时,我试图访问子类方法和字段。 Code explains it more easily:
代码更容易解释:
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);
}
}
Where Processor
is a FunctionalInterface
.其中
Processor
是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();
}
}
The example of wanted usage of these classes:这些类的想要使用的示例:
Child childInstance= new Child(); //where Child class extends Parent
childInstance.registerListeners((child, message) -> child.callSomeChildMethod());
childInstance.doSmth(message);
It would be really cool to create lambda without redundant specifying of parameter type like in this line:在没有冗余指定参数类型的情况下创建 lambda 真的很酷,就像这一行:
childInstance.registerListeners((Processor<Child>) (child, message) -> child.callSomeChildMethod());
(because it always should be type for which I register the listeners) (因为它始终应该是我注册侦听器的类型)
The problem is that code doesn't compile with error问题是代码没有编译错误
incompatible types: Parent cannot be converted to capture#1 of ? extends Parent
Which is quite logical (I understand the reason).这是非常合乎逻辑的(我理解原因)。 Is there some way in java I can get this code working?
在java中有什么方法可以让这段代码工作吗?
Thanks in advance!提前致谢!
Your idea of having List<Processor<? extends Parent>> processors;
你有
List<Processor<? extends Parent>> processors;
List<Processor<? extends Parent>> processors;
in Parent
class is not suggestible.在
Parent
类中是不建议的。 As you see, since you have not mentioned the type of processes the list has;如您所见,由于您没有提到列表中的进程类型; wherever you call
processor.doJob(anyObjectHere)
an error gets thrown, one way or the other(unless you do explicit cast)无论您在何处调用
processor.doJob(anyObjectHere)
都会以一种或另一种方式抛出错误(除非您进行显式转换)
Try doing something like this;尝试做这样的事情;
Declare a Client
instead of your Parent
which holds the type of processors in List<Processor<? extends Parent>> processors
声明一个
Client
而不是你的Parent
,它在List<Processor<? extends Parent>> processors
List<Processor<? extends Parent>> processors
; 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); } }
Change your Processor
definition to incorporating Client
rather that Parent
将您的
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(); } }
Now you can create your Child
like this;现在你可以像这样创建你的
Child
;
class Child extends Client<Child> { boolean callSomeChildMethod() { return true; } @Override Child getThis() { return this; } }
And call them the same way you did before;并像以前一样称呼它们;
Child childInstance= new Child(); //where Child class extends Parent childInstance.registerListeners((child, message) -> child.callSomeChildMethod()); childInstance.doSmth(message);
This way you have neither compile errors nor warnings这样你既没有编译错误也没有警告
You could simply cast the processor
object to declare that you want to pass it an object of a class derived from Parent
(it could be Child
), and cast this
to the same type.你可以简单地把
processor
对象申报要经过它派生的类的对象Parent
(也可能是Child
),投this
同一类型。 It can even be generic:它甚至可以是通用的:
private <T extends Parent> void doSmth() {
for (Processor<? extends Parent> p : processors) {
Processor<T> processor = (Processor<T>) p; // explicit cast
processor.doJob((T) this); //no compile error
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.