代码之家  ›  专栏  ›  技术社区  ›  ldam

为什么我会出现不可转换的类型错误?

  •  6
  • ldam  · 技术社区  · 13 年前

    如果我使用这个类:

    public class BooleanTest {
        public static void main(String args[]) {
            final Object[] objarray = new Object[2];
            try {
                objarray[0] = "Hello World!";
                objarray[1] = false;
            } catch (NullPointerException e) {
            }
            boolean bool = (boolean) objarray[1];
        }
    }
    

    它很好用,我可以指定 boolean 没问题。为什么我在向用户询问密码时不能做同样的事情?

    final Object result[] = new Object[2];
    try {
        java.awt.EventQueue.invokeAndWait(new Runnable() {
            @Override
            public void run() {
                JPanel panel = new JPanel();
                panel.setLayout(new GridLayout(3,0));
                JLabel label = new JLabel();
    
                label.setHorizontalAlignment(SwingConstants.LEADING);
                JTextField input = new JTextField();
    
                input.setHorizontalAlignment(SwingConstants.CENTER);
                JCheckBox checkbox = new JCheckBox("Pair with this device");
                checkbox.setHorizontalAlignment(SwingConstants.LEADING);
                panel.add(label);
                panel.add(input);
                panel.add(checkbox);
                if (wrong) {
                    label.setText("Wrong password. Please enter the password from the other device:");
                } else {
                    label.setText("Please enter the password from the other device:");
                }
                int response = JOptionPane.showConfirmDialog(SendGUI.this, panel, "Enter password", JOptionPane.OK_CANCEL_OPTION);
                if (response == JOptionPane.OK_OPTION) {
                    result[0] = input.getText();
                    result[1] = (boolean)checkbox.isSelected();
                } else {
                    result[0] = null;
                    result[1] = false;
                }
            }
        });
    } catch (InterruptedException e) {
    } catch (InvocationTargetException e) {
    }
    boolean pair = (boolean)result[1]; //inconvertible type, expected boolean found Object
    

    据我所见,我在这两种情况下都做了同样的事情,但第一个例子编译得很好,而第二个例子则不然。

    5 回复  |  直到 8 年前
        1
  •  8
  •   Jon Skeet    12 年前

    您正在使用不同的编译器选项。这两段代码都是根据Java 7规则编译的;两者都不是根据Java 6规则编译的。例如 第一 一段代码(您说是为您编译的代码):

    c:\Users\Jon\Test>javac -source 1.7 BooleanTest.java
    
    (No console output, i.e. no errors)
    
    c:\Users\Jon\Test>javac -source 1.6 BooleanTest.java
    warning: [options] bootstrap class path not set in conjunction with -source 1.6
    BooleanTest.java:10: error: inconvertible types
            boolean bool = (boolean) objarray[1];
                                             ^
      required: boolean
      found:    Object
    1 error
    1 warning
    

    编辑:我相信JLS第5.5节(铸造转换)中有变化。

    这个 Java 7 version 包括:

    铸造上下文允许使用以下内容之一:

    • ...
    • 缩小参考转换(§5.1.6),然后可选地进行开箱转换(§5.18)或未经检查的转换(§5.1.3)

    这个 JLS 3rd edition (基本上是Java 5和6)包括:

    铸造上下文允许使用以下内容之一:

    • ...
    • 缩小参考转换(§5.1.6),可选地,后面是未检查的转换

    注意这里缺少“开箱转换”。

        2
  •  1
  •   Adam Gent    13 年前

    更改:

    result[1] = (boolean)checkbox.isSelected();
    

    收件人:

    result[1] = Boolean.valueOf(checkbox.isSelected());
    
        3
  •  1
  •   Damian Leszczyński - Vash    13 年前

    你遇到的问题与 Autoboxing 在Java 1.6中

    您将一个基元类型放入Object数组中。Java不能将基元与Object混合,因此它将该基元布尔值包装成布尔值。

    因此,您正在做的事情不能表示为:

    boolean result = (boolean) Boolean.TRUE;

    解决方案是:

    1. 将Object数组替换为布尔数组。
    2. 使用 Boolean.TRUE.equals(result[1]) ;
    3. 正如John在回答中指出的那样,切换到Java 1.7。
        4
  •  0
  •   Miguel Prz    13 年前

    尝试通过更改布尔值 Boolean ,这是一个从java.lang.Object中继承的类,您有Boolean.TRUE和Boolean.ALSE

        5
  •  0
  •   Biswajit    13 年前

    使用此

     Boolean pair = (Boolean)result[1];