【问题标题】:What causes the "Incompatible operand types" error?什么导致“不兼容的操作数类型”错误?
【发布时间】:2011-11-05 03:56:10
【问题描述】:

我正在尝试通过一个类来实现 iSortableStack 接口。

这是我的主要功能,

public class SampleStack<E> {
    E ch;

    @SuppressWarnings("unchecked")
    public static void main(String[] args) throws IOException {
        ISortableStack<Character> s = new SortableStack<Character>();
        SampleStack demo = new SampleStack();
        while ((demo.ch == System.in.read()) != '\n')
            if (!s.isFull())
                s.push((Character) demo.ch);
        while (!s.isEmpty())
            System.out.print(s.pop());
        System.out.println();
    }
}

但我在这一行遇到一个错误,

while ((demo.ch == System.in.read()) != '\n')

错误:操作数类型 Object 和 int 不兼容

这里有什么问题?

【问题讨论】:

  • 如果你将demo声明为SampleStack&lt;Character&gt;?
  • 而不是抑制警告(就像你对@SuppressWarnings("unchecked")所做的那样),你应该听从编译器的建议。如果您不理解该建议,那么您应该阅读直到您理解为止(这是您在此处询问所做的事情,这是一个很好的选择。)一般来说:除非您知道什么,否则不要忽略警告他们的意思。
  • 除了术语上的矛盾之外,什么是可排序堆栈?

标签: java casting compiler-errors operators type-conversion


【解决方案1】:

这里有两个与泛型无关的严重问题。

首先,demo.ch == System.in.read() 是一个 boolean 表达式。 read()int)的结果将被自动装箱为Integer,并且该对象的身份将针对demo.ch(即null)进行测试。

我认为你想要的是赋值运算符=。这会将read() 结果分配给demo.ch

下一个问题是,您似乎希望 demo.ch 成为 Character(基于您使用的演员表)。但是,您正在尝试为其分配一个intread() 的结果)。原始类型在必要时可以“自动装箱”,即可以将它们转换为像CharacterInteger 这样的包装对象,但前提是要转换的值是可以由目标类型。这里的值是可变的,所以不能隐式进行转换。

您可以通过将read() 结果显式转换为char,然后让自动装箱将其转换为Character 来解决此问题,但这会隐藏EOF,它由值表示-1。我建议改用这样的东西:

while (true) {
  int ch = System.in.read();
  if ((ch < 0) || (ch == '\n'))
    break;
  if (!s.isFull())
    s.push((char) ch);
 }

请注意,我们这里根本没有使用demo,所以它的类型参数的问题是无关紧要的。

【讨论】:

  • 请注意,Character c; c = (int) 3; 确实已定义并且运行良好。但是,您所说的其余内容是合理的,尤其是关于将 read() 的结果自动装箱到 Character 的危险。
  • @Ernest Friedman-Hill:这很有趣,我没有意识到这一点,我仍然不完全理解那里发生了什么。看来,该分配仅在 int 右值可以静态确定以适合 char 而不会缩小时才有效。例如,c = (int) -1c = (int) 65536 不起作用。此外,分析是局部的; int i = 3; c = i; 在这种情况下不起作用。你知道这在 JLS 中的什么地方吗?
  • 我认为这在第 5.2 节 赋值转换 的讨论中有所涉及:“如果变量的类型是 byte、short 或char,和常量表达式的值可以用变量的类型来表示。"
  • @Ernest:这绝对涵盖了它!感谢您的参考。
【解决方案2】:

SampleStack.ch 的类型为 EE 是由您的类型参数指定的对象。由于您没有指定类型参数,因此编译器会为您输入Object。如果您希望 ch 成为 Character,您将希望 SampleStack&lt;Character&gt; demo = new SampleStack&lt;Character&gt;(); 或在 Java 7 中 SampleStack&lt;Character&gt; demo = new SampleStack&lt;&gt;();

【讨论】:

    【解决方案3】:

    您在实例化SampleStack 时没有提供类型参数,因此demo.ch 的类型为Object。这显然无法与来自System.inint 进行比较(或分配,这是我怀疑你实际上想要做的事情)。

    【讨论】:

      【解决方案4】:

      当你想要=(赋值)时,你有==(平等测试)。你从来没有真正分配给demo.ch。相等性测试返回布尔值,而不是字符,因此返回错误消息。

      您还需要将结果从 System.in.read() 转换为整数中的字符(或者使用 SampleStack&lt;Integer&gt; 或类似的东西。)

      【讨论】:

      • 井铸是一种选择,但还有更好的选择,例如 Scanner 类。
      【解决方案5】:

      这段代码有几个错误:

      • 正如人们指出的那样,您正在创建一个泛型类,但您没有对其进行泛化并直接使用它,您需要:

        SampleStack&lt;Character&gt;

      • 即使你改变它,它也不会像你拥有的那样运行 == 而不是 =

      • 即使您更改上述两个,它也不会工作,因为 System.in.read() 返回一个 int,而不是一个字符,您需要制作一个整数堆栈或从输入中读取值到变量然后施放它,但这不是一个好习惯。我会使用扫描仪或类似的东西来读取用户输入的内容,如下所示:

        Scanner sc = new Scanner(System.in); char c = sc.nextChar();

      【讨论】:

        猜你喜欢
        • 2012-07-09
        • 2013-05-23
        • 2013-12-16
        • 1970-01-01
        • 2020-06-02
        • 2021-04-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多