Truyền trong Java không phải là phép thuật, đó là bạn nói với trình biên dịch rằng một Đối tượng của loại A thực sự thuộc loại B cụ thể hơn, và do đó có được quyền truy cập vào tất cả các phương thức trên B mà bạn sẽ không có. Bạn không thực hiện bất kỳ loại phép thuật hoặc chuyển đổi nào khi thực hiện truyền, về cơ bản bạn đang nói với trình biên dịch "tin tôi đi, tôi biết tôi đang làm gì và tôi có thể đảm bảo với bạn rằng Đối tượng ở dòng này thực sự là một <Chèn ép gõ vào đây>. " Ví dụ:
Object o = "str";
String str = (String)o;
Ở trên là tốt, không phải phép thuật và tất cả đều tốt. Đối tượng đang được lưu trữ trong o thực sự là một chuỗi, và do đó chúng ta có thể ép kiểu thành một chuỗi mà không gặp bất kỳ vấn đề gì.
Có hai cách điều này có thể xảy ra sai. Thứ nhất, nếu bạn đang truyền giữa hai loại trong các phân cấp kế thừa hoàn toàn khác nhau thì trình biên dịch sẽ biết bạn đang ngớ ngẩn và ngăn bạn lại:
String o = "str";
Integer str = (Integer)o;
Thứ hai, nếu chúng ở trong cùng một hệ thống phân cấp nhưng vẫn là một cast không hợp lệ thì a ClassCastException
sẽ được ném vào thời gian chạy:
Number o = new Integer(5);
Double n = (Double)o;
Về cơ bản, điều này có nghĩa là bạn đã vi phạm sự tin cậy của trình biên dịch. Bạn đã nói với nó, bạn có thể đảm bảo đối tượng thuộc một loại cụ thể, và nó không phải.
Tại sao bạn cần đúc? Vâng, để bắt đầu, bạn chỉ cần nó khi đi từ một loại tổng quát hơn sang một loại cụ thể hơn. Ví dụ: Integer
kế thừa từ Number
, vì vậy nếu bạn muốn lưu trữ Integer
dưới dạng một Number
thì không sao (vì tất cả các Số nguyên đều là Số.) Tuy nhiên, nếu bạn muốn đi theo hướng khác, bạn cần ép kiểu - không phải tất cả các Số đều là Số nguyên (cũng như như Integer chúng tôi có Double
, Float
, Byte
, Long
, vv) và ngay cả khi chỉ có một phân lớp trong dự án của bạn hoặc JDK, ai đó có thể dễ dàng tạo ra khác và phân phối đó, vì vậy bạn đã có gì đảm bảo ngay cả khi bạn nghĩ rằng đó là một duy nhất, sự lựa chọn rõ ràng !
Về việc sử dụng để truyền, bạn vẫn thấy sự cần thiết của nó trong một số thư viện. Trước Java-5, nó được sử dụng nhiều trong các bộ sưu tập và nhiều lớp khác, vì tất cả các bộ sưu tập đều hoạt động trên việc thêm các đối tượng và sau đó truyền kết quả mà bạn nhận được từ bộ sưu tập. Tuy nhiên, với sự ra đời của generic, phần lớn việc sử dụng để truyền đã không còn - nó đã được thay thế bằng generic cung cấp một giải pháp thay thế an toàn hơn nhiều, không có tiềm năng cho ClassCastExceptions (thực tế là nếu bạn sử dụng generic rõ ràng và nó biên dịch không có cảnh báo, bạn có một đảm bảo rằng bạn sẽ không bao giờ nhận được ClassCastException.)