天天看点

java编译校验,java-如何用编译时泛型验证替换运行时insta...

这比我想的还要丑.我的看法:

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

}

现在,将编译以下内容:

> void process(F foo) {

foo.getProcessor().process(foo);

}

void process(Foo> foo) {

foo.getProcessor().process(foo);

}

不会,因为编译器无法知道所传递的foo的实际类型是其type参数的子类型,就像有人可以这样写:

class Bar implements Foo { ... }

我们可以通过要求foo的子类型实现对其类型参数的转换来解决此问题:

abstract class Foo> {

abstract Processor getProcessor();

abstract F getThis();

}

class SomeFoo extends Foo {

@Override

SomeFoo getThis() {

return this;

}

@Override

Processor getProcessor() {

return new SomeProcessor();

}

}

现在,我们可以写:

> void process(Foo foo) {

foo.getProcessor().process(foo.getThis());

}

并用

Foo> foo = ...;

process(foo);

为了易于使用,我建议将helper方法移到Foo类中:

abstract class Foo> {

abstract Processor getProcessor();

abstract F getThis();

void processWith(Processor p) {

p.process(getThis());

}

}

更新:我认为newaccts更新的答案显示了一个更优雅的解决方案,因为它不需要递归类型界限.