Got a little puzzle for a true Java Generics specialist... ;)
Let\'s say I have the following two interfaces:
interface Processor {
void process(Foo
This is uglier than I thought. My take:
interface Processor> {
void process(F foo);
}
interface Foo> {
Processor getProcessor();
}
interface SomeFoo extends Foo {
@Override
SomeProcessor getProcessor();
}
interface SomeProcessor extends Processor {
@Override
void process(SomeFoo foo);
}
Now, the following will compile:
> void process(F foo) {
foo.getProcessor().process(foo);
}
but
void process(Foo> foo) {
foo.getProcessor().process(foo);
}
doesn't, because the compiler can not know that actual type of the passed foo is a subtype of its type parameter, as somebody could write:
class Bar implements Foo { ... }
We can work around this by requiring the subtypes of foo to implement a conversion to their type parameter:
abstract class Foo> {
abstract Processor getProcessor();
abstract F getThis();
}
class SomeFoo extends Foo {
@Override
SomeFoo getThis() {
return this;
}
@Override
Processor getProcessor() {
return new SomeProcessor();
}
}
Now, we can write:
> void process(Foo foo) {
foo.getProcessor().process(foo.getThis());
}
and invoke this with
Foo> foo = ...;
process(foo);
To make it easy to use, I recommend moving the helper method into class Foo:
abstract class Foo> {
abstract Processor getProcessor();
abstract F getThis();
void processWith(Processor p) {
p.process(getThis());
}
}
Update: I think newaccts updated answer shows a more elegant solution, as it does not need the recursive type bounds.