简体   繁体   English

Eclipse Generics问题 - 解决方法?

[英]Eclipse Generics Issue - Workaround?

Given the following type signatures, I'm able to compile and run the code under Maven with both JDK 6 and JDK 7, but Eclipse gives a "Bound mismatch: The type F is not a valid substitute for the bounded parameter <F extends Field<TP,F>> of the type Field<TP,F> " error in TupleVisitor. 给定以下类型签名,我能够使用JDK 6和JDK 7在Maven下编译和运行代码,但是Eclipse给出了“绑定不匹配:类型F不是有界参数的有效替代<F extends Field<TP,F>>类型的Field<TP,F>错误在TupleVisitor。

I believe I need these types, although I understand this is difficult to motivate given the stripped-down example. 我相信我需要这些类型,虽然我知道这很难激励给出精简的例子。 Can anyone suggest a workaround that will let me continue to work in Eclipse? 任何人都可以建议一个让我继续在Eclipse中工作的解决方法吗?

public abstract class Tuple<F extends Field<TP, F>, TP extends Tuple<F, TP>>

public class VariableTuple<F extends Field<VariableTuple<F>, F>> extends Tuple<F, VariableTuple<F>>

public class ConstantTuple<F extends Field<ConstantTuple<F>, F>> extends Tuple<F, ConstantTuple<F>>

public class Field<TP extends Tuple<F, TP>, F extends Field<TP, F>>

public class ConstantField extends Field<ConstantTuple<ConstantField>, ConstantField>

public class VariableField extends Field<VariableTuple<VariableField>, VariableField>

public interface TupleVisitor {
  public <F extends Field<VariableTuple<F>, F>> void visit(VariableTuple<F> tuple, F field); //Eclipse error

  public <F extends Field<ConstantTuple<F>, F>> void visit(ConstantTuple<F> tuple, F field); //Eclipse error
}

Filed bug at: https://bugs.eclipse.org/bugs/show_bug.cgi?id=422503 提交的错误: https//bugs.eclipse.org/bugs/show_bug.cgi? id = 422503

No simple workaround identified. 没有确定简单的解决方法。 While Rohit Jain's answer wouldn't work with a visitor pattern, I took his follow-up advice and removed F as a type parameter from Field. 虽然Rohit Jain的回答不适用于访问者模式,但我接受了他的后续建议并将F作为类型参数从Field中移除。

This seems to a be a bug with eclipse, as it is compiling fine under javac for me too. 这似乎是eclipse的一个错误,因为它在javac下编译也很好。 In fact, there are few bugs related to self-referential Java generics related to eclipse that I found, but this isn't there. 事实上,我发现与eclipse相关的自引用Java泛型相关的bug很少,但这并不存在。 So, may be you should file one. 所以,可能你应该提交一个。

As for a workaround of this, I just found one, which I doubt you would like, as you have to make your interface generic. 至于解决方法,我刚刚找到一个,我怀疑你想要,因为你必须使你的界面通用。 Yes, you heard it right. 是的,你听到了。 Declaring the type parameters with the interface itself, makes the code compile fine. 使用接口本身声明类型参数,使代码编译正常。 Here's the compiling code: 这是编译代码:

interface TupleVisitor<E extends Field<VariableTuple<E>, E>, 
                       F extends Field<ConstantTuple<F>, F>>  {
   void visit(VariableTuple<E> tuple, E field);
   void visit(ConstantTuple<F> tuple, F field);
}

Of course there are two type variables, as the bounds on both of them are different. 当然有两种类型变量,因为它们的界限是不同的。 Check if this suits your need, because this really sounds to be as weird work-around, as the number of type parameters depends on the total number of implementors of Tuple class (Actually weird, isn't it?). 检查这是否适合你的需要,因为这听起来像是奇怪的解决方法,因为类型参数的数量取决于Tuple类的实现者总数(实际上很奇怪,不是吗?)。 Or else you have to do some other changes. 否则你必须做一些其他的改变。

The problem likely is that type parameters are provided by the caller. 问题可能是调用者提供了类型参数。 Given your declarations, somebody could declare 鉴于你的声明,有人可以声明

class ReallyConstantField extends ConstantField {}

and then invoke TupleVisitor.visit while providing ReallyConstantField for F . 然后调用TupleVisitor.visit同时提供ReallyConstantFieldF The visit method's type constraint would then read 然后将读取visit方法的类型约束

ReallyConstantField extends Field<ConstantTuple<ReallyConstantField>, ReallyConstantField>

so we use a ConstantTuple<ReallyConstantField> . 所以我们使用ConstantTuple<ReallyConstantField> The type constraint for that class would then read 然后将读取该类的类型约束

ReallyConstantField extends Field<ConstantTuple<ReallyConstantField>, ReallyConstantField>

which is incorrect, as ReallyConstantField is a ConstantField which is a Field<ConstantTuple<ConstantField>, ConstantField> , which is an inconvertible type. 这是不正确的,因为ReallyConstantField是一个ConstantField ,它是一个Field<ConstantTuple<ConstantField>, ConstantField> ,这是一个不可转换的类型。

That is, even though you declare a type parameter with an extends bound, the only valid type argument is a single type. 也就是说,即使您使用extends边界声明类型参数,唯一有效的类型参数也是单一类型。 That is, you don't need a type parameter at all, but could simply declare: 也就是说,您根本不需要类型参数,但可以简单地声明:

void visit(ConstantTuple<ConstantField> tuple, ConstantField field);

Update 更新

BTW, if these are supposed to be, as the example suggests, parallel class hierarchies with a one-to-one correspondence between the classes of different hierarchies, there is a simpler way to write the generics: 顺便说一句,如果这些应该是,如示例所示,并行类层次结构与不同层次结构的类之间具有一对一的对应关系,则有一种更简单的方式来编写泛型:

abstract class Tuple<F extends Field<TP, F>, TP extends Tuple<F, TP>> {}

class VariableTuple extends Tuple<VariableField, VariableTuple> {}

class ConstantTuple extends Tuple<ConstantField, ConstantTuple> {}

class Field<TP extends Tuple<F, TP>, F extends Field<TP, F>> {}

class ConstantField extends Field<ConstantTuple, ConstantField> {}

class VariableField extends Field<VariableTuple, VariableField> {}

interface TupleVisitor {
  public void visit(VariableTuple tuple, VariableField field);

  public void visit(ConstantTuple tuple, ConstantField field);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM