2013-04-02 42 views
6

Nếu tôi sử dụng lớp này:Tại sao tôi gặp lỗi loại không thể sửa đổi?

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]; 
    } 
} 

Nó hoạt động tốt và tôi có thể gán rằng boolean không có vấn đề. Tại sao tôi không thể làm điều tương tự khi yêu cầu người dùng nhập mật khẩu?

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 

Theo như tôi có thể thấy tôi đang làm điều tương tự trong cả hai trường hợp nhưng ví dụ đầu tiên biên soạn tốt trong khi ví dụ thứ hai thì không.

+3

bạn có thể đăng lỗi bạn nhận được trong mã cuối cùng không? –

+1

@MiguelPrz nó đã được trong mã của tôi, 'loại không thể thay đổi, dự kiến ​​boolean tìm thấy Object' – Logan

+0

@LoganDam: Đây có phải là một lỗi thời gian biên dịch? Bạn đang sử dụng cùng một trình biên dịch (với các tùy chọn tương tự) trong cả hai trường hợp? –

Trả lời

8

Bạn đang sử dụng các tùy chọn trình biên dịch khác nhau. Bạn phải. Cả hai phần mã biên dịch theo quy tắc Java 7; không biên dịch theo các quy tắc Java 6. Ví dụ, lấy của bạn mảnh đầu tiên của mã (một trong đó bạn nói biên dịch cho bạn):

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 

EDIT: Tôi tin rằng sự thay đổi là ở mục 5.5 của (chuyển đổi Đúc) JLS.

Các Java 7 version bao gồm:

bối cảnh Đúc cho phép sử dụng một trong số:

  • ...
  • chuyển đổi tài liệu tham khảo hẹp (§5.1.6) tùy ý sau đó hoặc là một chuyển đổi unboxing (§5.1.8) hoặc một chuyển đổi không được kiểm soát (§5.1.9)

Các JLS 3rd edition (Java 5 và 6, về cơ bản) bao gồm:

bối cảnh Đúc cho phép sử dụng một trong số:

  • ...
  • một thu hẹp chuyển đổi tham chiếu (§5.1.6) theo sau tùy chọn chuyển đổi không được kiểm soát

Lưu ý việc thiếu "chuyển đổi unboxing" ở đó.

+0

Tôi đã quên rằng tôi đang nhắm mục tiêu Java 6 trong ví dụ thứ hai của mình và không thay đổi điều đó trong ví dụ đầu tiên của mình. Cảm ơn. – Logan

+0

Tôi biết tôi phải theo dõi sai hoàn toàn khi Jon Skeet nói với tôi rằng tôi sai rồi. Tất nhiên tôi đã tìm ra khi tôi thực sự ném cả hai đoạn mã vào Eclipse nhưng sau đó Jon đã đăng câu trả lời đúng. – durron597

+0

@ durron597: Nếu nó an ủi, tôi chỉ biết điều này bởi vì có một câu hỏi tương tự (nhưng không phải là một bản sao chính xác) cách đây vài ngày :) –

0

Cố gắng thay đổi boolean bởi Boolean, mà nó là một lớp mà inhereits từ java.lang.Object và bạn có Boolean.TRUE và Boolean.FALSE

1

Thay đổi:

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

Để:

result[1] = Boolean.valueOf(checkbox.isSelected()); 
+0

Đối với các downvoters tôi có nghĩa là để làm Boolean.valueOf thay vì 'new Boolean'. Tôi chỉ không thể gõ đủ nhanh trên iPhone của mình. –

0

Sử dụng này

Boolean pair = (Boolean)result[1]; 
+0

Điều này có thể khắc phục được sự cố nhưng câu hỏi của tôi không phải là cách khắc phục nó và đúng hơn là tại sao đây lại là vấn đề. – Logan

+0

có cùng một vấn đề trong ví dụ đầu tiên của bạn, tức là đối tượng với lỗi chuyển đổi loại nguyên thủy – Biswajit

1

Sự cố bạn có liên quan với Autoboxing trong Java 1.6

Bạn đặt loại nguyên thủy vào mảng Đối tượng. Java không thể kết hợp nguyên thủy với Object, do đó nó quấn boolean nguyên thủy vào Boolean.

Vì vậy, những gì bạn đang làm không thể được biểu diễn như:

boolean result = (boolean) Boolean.TRUE;

Các giải pháp bao gồm:

  1. Thay mảng Object với mảng boolean.
  2. Sử dụng Boolean.TRUE.equals(result[1]);
  3. Chuyển sang Java 1.7 như John đã chỉ ra trong câu trả lời của anh ấy.
+0

Điều này không giải thích tại sao ví dụ đầu tiên của tôi hoạt động mà không có lỗi. – Logan

+0

@LoganDam Nó không nên. Bạn có chắc nó hoạt động không? Chỉ cần thử lại. –

+0

Cả hai đoạn mã đều ổn dưới Java 7. Thực sự, thật sự :) –

Các vấn đề liên quan