Reputation: 11
I have the following class structure:
public interface Incoming<P extends Processor> {
void doSomething(P p);
}
public interface Processor<I extends Incoming> {
void process(I i);
}
public class MyIncoming implements Incoming<MyProcessor>
{
public void doSomething(MyProcessor p) { .. }
}
public class MyProcessor implements Processor<MyIncoming> {
public void process(MyIncoming i) { .. }
}
Now in another class I pass an Instance of MyIncoming that is supposed to initialize the type passed for the Processor it has defined in doSomething()?
Please help.
Upvotes: 0
Views: 169
Reputation: 37665
The first problem I see with your code is that you are using the raw types Incoming
and Processor
.
public interface Incoming<P extends Processor> {
void doSomething(P p); ^^
} that is a raw type!
One way to get rid of those raw types is to make both Incoming
and Processor
have two type parameters, but it's very complicated.
public interface Incoming<I extends Incoming<I, P>, P extends Processor<I, P>> {
void doSomething(P p);
}
public interface Processor<I extends Incoming<I, P>, P extends Processor<I, P>> {
void process(I i);
}
Now to your actual question. You've said that for each concrete implementation of Incoming
you have a specific instance of Processor
, and for a variable t
of type Incoming
, you want to be able to find out that instance x
and call x.process(t);
. I'm sure that this can be done with reflection, but I can't see the point. You can just make getProcessor
a method of Incoming
.
public interface Incoming<I extends Incoming<I, P>, P extends Processor<I, P>> {
void doSomething(P p);
P getProcessor();
}
Now you can write concrete implementations.
public class MyIncoming implements Incoming<MyIncoming, MyProcessor>
{
private static final MyProcessor PROCESSOR = new MyProcessor();
@Override
public void doSomething(MyProcessor p) { }
@Override
public MyProcessor getProcessor() { return PROCESSOR; }
}
public class MyProcessor implements Processor<MyIncoming, MyProcessor> {
@Override
public void process(MyIncoming i) { }
}
Now, if you have a generic class
class A<I extends Incoming<I, P>, P extends Processor<I, P>>
and, within A
, you have a variable i
of type I
, you can do
i.getProcessor().process(i);
This works, but personally I think circular dependencies of the form TypeA<B extends TypeB>
/ TypeB<A extends TypeA>
are unnecessarily convoluted, and the generics here actually work against you. It may preserve your sanity if you just make Incoming
and Processor
non-generic interfaces and use casting where necessary.
Upvotes: 1