【问题标题】:Stack returning Objects instead of Integers堆栈返回对象而不是整数
【发布时间】:2011-11-25 16:45:48
【问题描述】:

我正在尝试实现一个涉及堆栈数组的程序。每个堆栈都接受 Integer 对象,但问题是当我尝试从堆栈中获取 Integer 对象时:

import java.util.*;

public class Blocks
{
    public static void main(String[] args)
    {
        System.out.println();
        Scanner input = new Scanner(System.in);

        Stack[] blocks = new Stack[input.nextInt()];
        for (int i = 0; i < blocks.length; i++) {blocks[i] = new Stack<Integer>();} //initializing main array of stacks of blocks
        for (int i = 0; i < blocks.length; i++) {blocks[i].push(i);} //add first block to each stack
        Stack retainer = new Stack<Integer>(); //used for when moving stacks of blocks instead of one block.

        boolean m; //move or pile
        boolean on; //onto or over

        int fromBlock; //block being moved
        int toBlock; //block where the fromBlock is being moved

        String command = input.next();
        while (!command.equals("quit"))
        {
            m = command.equals("move");
            fromBlock = input.nextInt();
            on = input.next().equals("onto");
            toBlock = input.nextInt();

            if (m) //put back blocks on fromBlock
            {
                if (on) //put back blocks on toBlock
                {
                    int holder = blocks[fromBlock].pop().intValue(); //I get a compiler error here
                    moveOnto(blocks, holder, toBlock);
                }
                else //fromBlock goes on top of stack on toBlock
                {
                }
            }
            else //bring blocks on fromBlock
            {
                if (on) //put back blocks on toBlock
                {
                }
                else //fromBlock goes on top of stack on toBlock
                {
                }
            }

            command = input.next();
        }
    }

    void moveOnto(Stack[] array, int sBlock, int rBlock)
    {

    }
}

错误表示无法识别 .intValue()。显然这是 Integer 的一种方法,从那时我发现它返回的是 Object 对象而不是 Integer 类型。我怎样才能让它返回整数类型?

【问题讨论】:

    标签: java stack


    【解决方案1】:

    要定义一个泛型数组,您需要这样做。

    @SuppressWarnings("unchecked") // to avoid warnings.
    Stack<Integer>[] blocks = new Stack[n];
    

    那你就可以写了

    int holder = blocks[fromBlock].pop();
    

    是的,它确实可以编译并且工作得很好。

    编辑:为什么编译器不能让你这样做

    Stack<Integer>[] blocks = new Stack<Integer>[n];
    

    Stack<Integer>[] blocks = new Stack<>[n];
    

    意思是同样的事情超出了我的范围。

    【讨论】:

    • 令我困惑的是为什么编译器不允许你创建泛型数组但允许这样做(带有警告,你可以关闭它)我从来没有发现它的问题。跨度>
    • 警告是提醒您,当您的其余代码在数组中进行赋值时没有类型检查,这意味着您可以在运行时使用此代码获得 ClassCastException。即,警告告诉你,即使你没有施放,这仍然是有风险的。
    • 您在运行时无法在此处获得 ClassCastException。类型擦除的类型是一样的。
    【解决方案2】:

    您需要将块的类型更改为Stack&lt;Integer&gt;[]

    编辑:代码编译得很好。您会收到一条警告,提醒您在运行时仍可能发生错误的数组分配,因此如果您编写有错误的代码,编译器无法保证您不会在运行时收到 ClassCastException。但是,发布的解决方案正是 OP 想要的:

    public static void main(String[] args) throws Exception {
        Stack<Integer>[] array = new Stack[] { new Stack(7) };
        Integer result = array[0].pop();
    }
    
    class Stack<T> {
    
        private final T foo;
    
        public Stack(T foo) {
            this.foo = foo;
        }
    
        T pop() {
            return foo;
        }
    }
    

    ps。澄清一下,该警告指出即使您没有显式转换,您仍然可以在运行时获得 ClassCastException,如以下代码所示:

        public static void main(String[] args) throws Exception {
            Stack<Integer>[] array = new Stack[] { new Stack(7) };
    
            Stack notAnIntegerStack = new Stack<Object>(new Object());
            array[0] = notAnIntegerStack;
    
            Integer result = array[0].pop(); // class cast exception at runtime
        }
    

    这段代码中到处都有警告指出危险,但它会编译。希望能解决问题。

    【讨论】:

      【解决方案3】:

      (哎呀——Java 不允许泛型数组) 更改您的Stack 变量声明以使用Stack 的通用版本:

      Stack<Integer>[] blocks = new Stack<Integer>[input.nextInt()];
      

      否则,当您访问非泛型堆栈的 .pop() 方法时,它只会返回一个 Object,您需要将其转换回 Integer 才能访问 Integer 方法,如 intValue():

      int holder = ((Integer)blocks[fromBlock].pop()).intValue();
      

      (但如果您修复声明,则不需要强制转换。)

      【讨论】:

      • 第一部分不起作用,但铸造使它起作用。那并使 moveOnto 方法静态修复它。谢谢!
      • 抱歉,是的,显然 Java 出于某种原因不允许使用泛型数组。您可以尝试ArrayList&lt;Stack&lt;Integer&gt;&gt; blocks = ...,但(显然)在您的代码中进行相应的更改以使用 ArrayList 功能而不是标准数组功能。 (注意:我也没有测试过。)
      【解决方案4】:
      int holder = blocks[fromBlock].pop().intValue(); //I get a compiler error here
      

      将其更改为:

      int holder = ((Stack<Integer>blocks[fromBlock]).pop().intValue();
      

      您将收到编译器警告。

      与这里的所有错误答案相反,Java 中不能有泛型类型的数组。

      【讨论】:

      • 哦,好的。好吧,我已经在使用整数转换了,但我会记住这一点。
      【解决方案5】:

      使用 Stack Generic 版本的 Stack

      Stack<Integer>[] blocks = new Stack<Integer>[input.nextInt()];
      

      你必须在声明的类型中包含泛型参数

      Stack<Integer[] blocks;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-11-25
        • 2019-06-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多