Câu hỏi liên quan

không nên code này sản xuất một ClassCastException


0 Phiếu
Đã hỏi 18/5/2016 bởi torra_4482 (280 điểm)
Sau đây code biên dịch và chạy thành công mà không có bất kỳ ngoại lệ
import java.util.ArrayList;
class SuperSample {}
class Sample extends SuperSample {
  @SuppressWarnings("unchecked")
  public static void main(String[] args) {
    try {
      ArrayList<Sample> sList = new ArrayList<Sample>();
      Object o = sList;
      ArrayList<SuperSample> ssList = (ArrayList<SuperSample>)o;
      ssList.add(new SuperSample());
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}
không nên các dòng sản phẩm ArrayList<SuperSample> ssList = (ArrayList<SuperSample>)o; một ClassCastException? trong khi code sau tạo ra một compile thời gian error error để ngăn ngừa ô nhiễm heap , không nên code đề cập ở trên tổ chức công tác phòng chống tương tự tại thời gian chạy?
ArrayList<Sample> sList = new ArrayList<Sample>();
ArrayList<SuperSample> ssList = (ArrayList<SuperSample>) sList;
EDIT: nếu loại Erasure là lý do đằng sau này, không nên có cơ chế bổ sung để ngăn chặn một object không hợp lệ được bổ sung vào danh sách? Ví dụ:
String[] iArray = new String[5];
Object[] iObject = iArray;
iObject[0]= 5.5;  // throws ArrayStoreException
sau đó tại sao,
ssList.add(new SuperSample());
không được thực hiện để ném bất kỳ trường hợp ngoại lệ?

3 Câu trả lời

0 Phiếu
Đã trả lời 01/6/2016 bởi BaoLeiba (440 điểm)
 
Câu trả lời hay nhất
Tôi nghĩ rằng điều này không thể sản xuất ClassCastException vì vấn đề tương thích trong Java. Thông tin chung chung không được bao gồm trong bytecode (biên dịch có được rids của nó trong quá trình biên soạn). Hãy tưởng tượng kịch bản mà bạn sử dụng trong dự án của bạn một số code di sản cũ (một số viết library cũ trong java 1.4) và bạn vượt qua chung danh sách một số method trong mã di sản này. Bạn có thể làm điều này. Trong thời gian trước khi generics di sản code đã được cho phép để đặt bất cứ điều gì ở tất cả (trừ nguyên thủy) vào một bộ sưu tập. Vì vậy này code kế thừa không thể nhận được ClassCastException ngay cả khi nó cố gắng đưa chuỗi vào danh sách &lt; nguyên &gt;. Từ quan điểm di sản code đó là chỉ cần danh sách. Vì vậy, hành vi lạ này là một hệ quả của type erasure, và để cho phép tương thích trong Java. EDIT: bạn nhận được ArrayStoreException cho mảng vì lúc chạy JVM KNOWS type mảng, và bạn không nhận được bất kỳ exception cho bộ sưu tập do type erasure và JVM vấn đề tương thích này không biết type collection lúc chạy. Bạn có thể đọc về chủ đề này trong "SCJP Sun® Certified Programmer for Java™ 6 nghiên cứu hướng dẫn" cuốn sách trong chương 7 "Generics và bộ sưu tập"
Đã bình luận 01/6/2016 bởi Reference (160 điểm)
thx cho phản ứng của bạn...:) câu hỏi này bugging tôi từ buổi sáng...
Đã bình luận 02/6/2016 bởi Implem (150 điểm)
Có những mẫu bao giờ castable trực tiếp vào nhau, mà không đúc lên đến một tham chiếu object lần đầu tiên?
Đã bình luận 03/6/2016 bởi onGrain (140 điểm)
Tôi cập nhật các câu trả lời của tôi để giải thích ArrayStoreException này cho mảng.
0 Phiếu
Đã trả lời 01/6/2016 bởi YouYou (1,470 điểm)
Không có nó không nên, thời gian chạy cả hai danh sách có cùng type ArrayList. Điều này được gọi là erasure . Thông số chung không phải là một phần của lớp biên dịch, tất cả đều được xoá hoàn toàn trong quá trình biên soạn. Từ quan điểm của JVM của bạn code là tương đương với:
public static void main(String[] args) {
    try {
      ArrayList sList = new ArrayList();
      Object o = sList;
      ArrayList ssList = (ArrayList)o;
      ssList.add(new SuperSample());
    } catch (Exception e) {
      e.printStackTrace();
    }
}
về cơ bản generics chỉ đơn giản hóa phát triển, bằng cách sản xuất compile thời gian lỗi và cảnh báo, nhưng họ không ảnh hưởng đến thực hiện ở tất cả. EDIT: Vâng, các khái niệm cơ bản đằng sau này là Reifiable loại . ID mạnh mẽ khuyên bạn nên đọc hướng dẫn sử dụng này:
A reifiable type là một type thông tin type mà là hoàn toàn có sẵn tại thời gian chạy. Điều này bao gồm nguyên thủy, -chung loại, loại nguyên liệu và invocations của wildcards toạc. Reifiable phòng không loại là loại nơi thông tin đã được gỡ bỏ biên dịch bởi type erasure
được ngắn: mảng đang rifiable và các bộ sưu tập chung không. Vì vậy, khi bạn lưu trữ smth trong mảng, type được kiểm tra bởi JVM, bởi vì của array type có mặt tại thời gian chạy. Mảng thể hiện chỉ là một phần của memmory, trong khi collection là một lớp học bình thường, có thể có bất kỳ loại thực hiện. Ví dụ, nó có thể lưu trữ data trong db hoặc trên đĩa dưới mui xe. Nếu bạn muốn nhận được sâu hơn, tôi khuyên bạn nên đọc cuốn sách Java Generics và bộ sưu tập .
0 Phiếu
Đã trả lời 01/6/2016 bởi jbebut (550 điểm)
Tôi nghĩ rằng điều này không thể sản xuất ClassCastException vì vấn đề tương thích trong Java. Thông tin chung chung không được bao gồm trong bytecode (biên dịch có được rids của nó trong quá trình biên soạn). Hãy tưởng tượng kịch bản mà bạn sử dụng trong dự án của bạn một số code di sản cũ (một số viết library cũ trong java 1.4) và bạn vượt qua chung danh sách một số method trong mã di sản này. Bạn có thể làm điều này. Trong thời gian trước khi generics di sản code đã được cho phép để đặt bất cứ điều gì ở tất cả (trừ nguyên thủy) vào một bộ sưu tập. Vì vậy này code kế thừa không thể nhận được ClassCastException ngay cả khi nó cố gắng đưa chuỗi vào danh sách &lt; nguyên &gt;. Từ quan điểm di sản code đó là chỉ cần danh sách. Vì vậy, hành vi lạ này là một hệ quả của type erasure, và để cho phép tương thích trong Java. EDIT: bạn nhận được ArrayStoreException cho mảng vì lúc chạy JVM KNOWS type mảng, và bạn không nhận được bất kỳ exception cho bộ sưu tập do type erasure và JVM vấn đề tương thích này không biết type collection lúc chạy. Bạn có thể đọc về chủ đề này trong "SCJP Sun® Certified Programmer for Java™ 6 nghiên cứu hướng dẫn" cuốn sách trong chương 7 "Generics và bộ sưu tập"
Đã bình luận 01/6/2016 bởi Assuming (140 điểm)
Tôi đã xóa câu trả lời của tôi vì tôi cảm thấy rằng nó đã không trả lời câu hỏi của bạn hoàn toàn và tôi không muốn một quyền bán hoặc một bán sai câu trả lời ở đây. Tôi sẽ suy nghĩ nói rằng nó có thể không thể trực tiếp để đúc (tham khảo của bạn bình luận cuối cùng về trả lời của tôi), nhưng bạn có thể làm một cái gì đó như thế này ' ArrayList ssList = (ArrayList ) ((đối tượng) sList);' và các công trình này. Tôi cảm thấy người dùng có kinh nghiệm có thể trả lời của bạn query . Hãy xem xét thêm rằng câu hỏi của bạn. Bạn đã hỏi một câu hỏi tuyệt vời ngày hôm nay (sau một thời gian dài, tôi thấy một).
Đã bình luận 02/6/2016 bởi Everylees (240 điểm)
: không có... sẽ có một thời gian biên dịch lỗi

ToughDev Q&A là gì?

Trang web hỏi đáp cho các bạn đam mê lập trình, phát triển phần mềm và các vấn đề kỹ thuật khác. Với sự giúp đỡ của bạn, chúng tôi hy vọng sẽ xây dựng thành công một thư viện đầy đủ các câu hỏi và trả lời về tất cả các vấn đề có liên quan đến lập trình!







...