真正的Java泛型专家有点困惑…;)
假设我有以下两个接口:
interface Processor {
void process(Foo foo);
}
interface Foo {
Processor getProcessor();
}
例如,以下两个实现类:
static class SomeProcessor implements Processor {
static final SomeProcessor INSTANCE = new SomeProcessor();
@Override
public void process(Foo foo) {
if (foo instanceof SomeFoo) { // <-- GET RID OF THIS ?
// process ((SomeFoo) foo)
}
}
}
class SomeFoo implements Foo {
@Override
public Processor getProcessor() {
return SomeProcessor.INSTANCE;
}
}
有什么方法可以使这两个接口通用,以至于我不需要instanceof
在process()
函数中进行标记检查,而在我的代码的其他地方仍可以进行以下构造工作?
foo.getProcessor().process(foo);
(当然,我不知道我在处理哪个Foo子类)
换句话说:我正在寻找一种在对象中定义函数的方法,使其只能返回另一个对象,该对象处理包含该函数的对象的类型。注意:我不仅在谈论处理包含该函数的对象的某些最小公分母超类(上方:Foo),而且还涉及该对象的实际类(上方:SomeFoo)。
(除非我现在真的很愚蠢,否则这听起来似乎微不足道)。
这比我想的还要丑。我的看法:
interface Processor<F extends Foo<F>> {
void process(F foo);
}
interface Foo<F extends Foo<F>> {
Processor<F> getProcessor();
}
interface SomeFoo extends Foo<SomeFoo> {
@Override
SomeProcessor getProcessor();
}
interface SomeProcessor extends Processor<SomeFoo> {
@Override
void process(SomeFoo foo);
}
现在,将编译以下内容:
<F extends Foo<F>> void process(F foo) {
foo.getProcessor().process(foo);
}
但
void process(Foo<?> foo) {
foo.getProcessor().process(foo);
}
不会,因为编译器无法知道所传递的foo的实际类型是其类型参数的子类型,就像有人可以这样写:
class Bar implements Foo<SomeFoo> { ... }
我们可以通过要求foo的子类型实现对其类型参数的转换来解决此问题:
abstract class Foo<F extends Foo<F>> {
abstract Processor<F> getProcessor();
abstract F getThis();
}
class SomeFoo extends Foo<SomeFoo> {
@Override
SomeFoo getThis() {
return this;
}
@Override
Processor<SomeFoo> getProcessor() {
return new SomeProcessor();
}
}
现在,我们可以写:
<F extends Foo<F>> void process(Foo<F> foo) {
foo.getProcessor().process(foo.getThis());
}
并用
Foo<?> foo = ...;
process(foo);
为了易于使用,我建议将helper方法移到Foo类中:
abstract class Foo<F extends Foo<F>> {
abstract Processor<F> getProcessor();
abstract F getThis();
void processWith(Processor<F> p) {
p.process(getThis());
}
}
更新:我认为newaccts更新的答案显示了一个更优雅的解决方案,因为它不需要递归类型界限。
问题内容: 这是我的代码:ExecutorImp扩展了AbstractExecutor,它提取了与实现者相同的执行逻辑(ExecutorImp是一种情况),当调用ExecutorImp的execute()方法时,它将在其父类型中调用该方法,但在父类型中调用该方法(AbstractExcutor )应该知道与实现者绑定的另一个类(在示例中,它是User类): 所以,我的代码有什么问题? 问题答案:
Kotlin编译器在这里发出警告(未检查的强制转换): 据我所知,Kotlin smart cast应该知道由检查。 Java代码和编译器给出了完全相同的结果。 为了为每个实现获得正确的util类,我在伴生对象上创建了一个函数,该函数基于泛型类型T的参数为每个实现返回正确的util类,该参数扩展了a:,因此返回类型为。 但是,当我为的每个派生类编写函数体时,使用检查参数的类型,然后使用返回正确的u
问题内容: 在关于反射的本教程中,它指出: […]因为泛型是通过类型擦除实现的,因此在编译过程中会删除有关泛型类型的所有信息 我的知识是使用泛型,以便在编译时编译器可以检查类型安全性。即失败快速方法。但是该链接提到类型擦除会在编译期间删除通用信息。 问题答案: 您引用的语句是正确的:编译器在编译过程中在内部使用通用类型信息,在处理源时会生成与类型相关的错误。然后,一旦完成验证,编译器将生成类型擦除
我在一个类中有一个方法,该方法具有使用泛型指定的返回类型。 对于通用返回类型,我假设上面示例中的返回将评估为: 相反,被正确返回和打印。 如果我将调用更改为: 我错过了什么,以帮助我理解这里发生了什么,为什么原始版本没有导致编译错误。
我想在编译时向某些类添加一个泛型字段。为了实现这个目标,我按照官方文档实现了我自己的 AST 注释和转换类,并使用 AST 注释注释了所需的类。 但是我在编译时得到了这个错误: org . codehaus . groovy . control . multiplecompilationerrorsexception:启动失败:/home/.../groovy/Sample.groovy: -1:
问题内容: 在Java中,可以具有运行时类型(即创建时的类型)和强制类型(您将其强制转换为的类型)。 我想知道这些类型的 专有 名称是什么。例如 创建为,但声明为。引用每个透视图类型的正确方法是什么? 问题答案: 我认为,区分 对象 (存在于执行时,只是具有执行时间类型)和具有编译时类型的 表达式 (例如变量)之间,这一点很重要。 因此,在这种情况下: 是类型的变量。它在执行时的值是对type对象