【问题标题】:Java generics error in Linux but not in WindowsLinux 中的 Java 泛型错误,但 Windows 中没有
【发布时间】:2017-04-02 15:44:49
【问题描述】:

我有一个类可以在 Windows 中编译,但不能在 Linux 中编译。 不编译的方法是mapA。 我得到的错误是:“错误:类型参数 B 不在类型变量 B 的范围内”。 为什么 Windows 接受我的代码而 Linux 不接受? 我可以以某种方式禁用此错误吗?

这是课程:

/** Either an A or a B. C is some common supertype of A and B. */
public class EitherOr<C, A extends C, B extends C>
{
    private final boolean isA;
    private final A a;
    private final B b;

    protected EitherOr(boolean isA, A a, B b)
    {
        this.isA = isA;
        this.a = a;
        this.b = b;
    }

    /**
     * If f(A) is of type D,
     * maps an EitherOr<C, A, B> to an EitherOr<E, f(A), B>,
     * where E is some common supertype of D and B.
     */
    public<E, D extends E> EitherOr<E, D, B> mapA(Function<A, D> f)
    {
        return (EitherOr<E, D, B>)(isA ? ofA(f.apply(a)) : ofB(b));
    }

    /** Creates an EitherOr<C, A, B> which is actually an A */
    public static<C, A extends C, B extends C> EitherOr<C, A, B> ofA(A a) {...}

    /** Creates an EitherOr<C, A, B> which is actually a B */
    public static<C, A extends C, B extends C> EitherOr<C, A, B> ofB(B b) {...}

    /** If is A, returns a, else throws an exception. */
    public A getA() {...}

    /** If is B, returns b, else throws an exception. */
    public B getB() {...}

    public C getValue() {return isA ? a : b;}

    ...
}

【问题讨论】:

  • 错误在哪里?在方法签名上,还是在方法中?
  • 我高度怀疑 Windows 和 Linux 中的代码不一样。
  • 注意:最好将条件表达式写成显式的if/else。那里的类​​型推断很可能有点麻烦(正如演员表所证明的那样)。
  • @m0skit0: 或者编译器生成或设置不同
  • 我怀疑C 的价值。我看到它被用作getValue() 方法的返回值;但是与静态方法static &lt;C&gt; C getValue(EitherOr&lt;? extends C, ? extends C&gt; eo) 方法相比,它需要携带很多额外的语法包袱(见我的回答here)。

标签: java generics


【解决方案1】:

所以(在添加import java.util.function.*; 后,用return null;s 替换...s 的空白行)错误是:

Main.java:22: error: type argument B is not within bounds of type-variable B
    public<E, D extends E> EitherOr<E, D, B> mapA(Function<A, D> f)
                                      ^
  where B,C are type-variables:
    B extends C declared in class EitherOr
    C extends Object declared in class EitherOr

这听起来很合理。 B 不一定扩展 E,这是必需的。它确实扩展了C,但这不相关。

演员表是另一个问题的迹象。

如果此代码在任何编译器上编译,则该编译器存在重大问题。

【讨论】:

  • 另一方面,总是可以将Object 替换为E 作为BD 的公共超类。在这种情况下,您可能会认为此代码是有效的,这就是我认为 Windows 编译器所做的。我在想javac 可能有一些命令行选项来明确指定如何解释这种代码。
  • @roel 调用者可能但不限于此。我不认为你正在编译你认为你在那个平台上的代码。
猜你喜欢
  • 2019-07-14
  • 1970-01-01
  • 2018-02-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-13
  • 1970-01-01
相关资源
最近更新 更多