2011-02-10 37 views
11

Tôi đang thực hiện việc triển khai JVM của riêng mình và đi đến hướng dẫn checkcast. Tài liệu đầy đủ là on this page. Tôi tò mò vì khi liệt kê các quy tắc về cách thức hoạt động của diễn viên, một điều kiện được kiểm tra là nếu tham chiếu đối tượng được kiểm tra có thuộc loại giao diện hay không. Theo sự hiểu biết của tôi, điều này không thể thực hiện được; các giao diện không thể được khởi tạo trực tiếp, và bất kỳ đối tượng nào thực hiện một giao diện có một số loại lớp bê tông khác. Tui bỏ lỡ điều gì vậy?Lẫn lộn trên hướng dẫn bytecode checkcast?

Trả lời

20

Có vẻ như bạn không phải là chỉ có một nhầm lẫn về định nghĩa này, bài viết trên blog này có một lời giải thích: http://mbravenboer.blogspot.com/2008/12/why-jvm-spec-defines-checkcast-for.html

Nó chỉ ra rằng đây thực sự là một không thể trường hợp `'. Lý do tại sao mục này nằm ở cùng đặc điểm kỹ thuật , là bởi vì checkcast được đệ quy định nghĩa cho các mảng:

  • Nếu S là một lớp mô tả kiểu mảng SC [], có nghĩa là, một loạt các thành phần của loại SC, sau đó:
  • ...
  • Nếu T là một loại mảng TC [], có nghĩa là, một loạt các thành phần của loại TC, sau đó một trong những điều sau đây phải đúng:
    • ...
    • TC và SC là các loại tham chiếu và loại SC có thể b e truyền tới TC bằng cách áp dụng đệ quy các quy tắc này.

Vì vậy, nếu bạn có một đối tượng kiểu Danh sách [] được đúc vào một Bộ sưu tập [], sau đó các quy tắc cho checkcast được đệ quy gọi cho các loại S = Danh sách và T = Collection. Lưu ý rằng List là một giao diện, nhưng một đối tượng có thể có List list [] tại thời gian chạy. Nếu chưa xác minh điều này với các nhà bảo trì JVM Spec, nhưng theo như tôi thấy, đây là lý do duy nhất tại sao quy tắc cho các loại giao diện ở đó.

+0

Cảm ơn rất nhiều! Đó chính là loại câu trả lời tôi đang tìm kiếm. – templatetypedef

+0

+1 Brilliant. :) – biziclop

-2

Nếu S là một kiểu giao diện, sau đó:

Nếu T là một kiểu lớp, sau đó T phải Object (§2.4.7).
Nếu T là một loại giao diện, thì T phải là giao diện tương tự như S hoặc siêu bề mặt của S (§2.13.2).

Điều đó có vẻ rõ ràng đối với tôi: một giao diện có thể được truyền đến giao diện mở rộng. Trường hợp này được sử dụng ví dụ khi bạn gọi serialization trên DataInputStream: interface DataInputStream thực hiện Serializable, vì vậy chúng ta cast đối tượng Serializable mà không biết lớp thực thi của đối tượng là gì.

+1

Tôi nghĩ bạn không hiểu câu hỏi. Ngoài ra, [java.io.DataInputStream] (https://docs.oracle.com/javase/8/docs/api/java/io/DataInputStream.html) là một lớp, không phải là một giao diện. –