2009-07-30 34 views
7

Nếu tôi có một lớp StackJava Raw Loại và Generics tương tác

class Stack<E> {} 

bây giờ nếu tôi làm:

1) Stack<Integer> s = new Stack()

2) Stack s = new Stack<Integer>()

3) Stack s = new Stack()

bất cứ ai có thể giải thích cho tôi những tương tác này ic < -> raw) gây ra?

Chủ yếu là nghi ngờ của tôi là ở điểm 1. Trên thực tế, nếu tôi thực hiện việc chuyển nhượng thì không an toàn vì ngăn xếp đó có thể lưu trữ các loại khác rồi là Số nguyên. Có, nhưng nếu tôi có một phương pháp đẩy và cố gắng để lưu trữ một giá trị khác hơn một số nguyên trình biên dịch dừng lại tôi ... vì vậy khi tôi có hoạt động không an toàn?

+0

Tôi không hiểu - bạn muốn có một ngăn xếp nơi bạn có thể đẩy những thứ khác sau đó số nguyên (ví dụ như số nguyên và đôi) hoặc bạn muốn sử dụng ngăn xếp chỉ với một loại (số nguyên) và để trình biên dịch giúp bạn? –

+1

Không, tôi muốn một ngăn xếp với một loại và muốn biết điều gì xảy ra nếu tôi làm các bài tập đó. – xdevel2000

Trả lời

6

Tất cả chúng đều không an toàn bởi vì Generics Java, theo số type erasure, chỉ là đường cú pháp. Ví dụ: đây là mã Java hoàn toàn hợp lệ:

Stack<Integer> s = new Stack<Integer>(); 
Stack<Double> s2 = (Stack<Double>)s; 
s2.push(3.3d); 

Điểm chung của Java là dừng bạn phải rõ ràng về việc truyền Đối tượng. Đó là nó. Họ không làm gì hơn thế (ngoại trừ tạo cảnh báo trình biên dịch và IDE).

Chúng vẫn hữu ích và có thể làm cho mã của bạn dễ đọc hơn và ít bị lỗi hơn nhưng cuối cùng, ở cấp mã byte, điều quan trọng là phải hiểu chúng không làm gì cả.

+0

không phải là trường hợp của OP # 2 nơi trình biên dịch đủ thông minh để suy ra các đối số kiểu chung cho s? –

+0

Có nhưng ở điểm 1 trình biên dịch khuyên tôi nếu tôi cố gắng đặt (với một hoạt động đẩy) một đối tượng khác với một số nguyên. Vì vậy, có thể Generics không chỉ là một 'cú pháp cú pháp' nhưng điểm 1 cũng thay đổi hành vi của trình biên dịch (ngữ nghĩa). Vì vậy, một lần nữa tôi không hiểu đâu là không an toàn ... Nên, xin vui lòng, cho tôi một giải thích phân tích nhiều hơn? – xdevel2000

7

Tất cả ba là hoàn toàn hợp pháp, vì không có chênh lệch thời gian chạy thực tế giữa StackStack<Integer>, nhưng cả ba sẽ dẫn đến cảnh báo trình biên dịch.

Stack<Integer> s = new Stack() 

Điều này sẽ dẫn đến cảnh báo "chuyển đổi không được kiểm tra" vì không an toàn nói chung để chuyển loại thô thành loại được tham số. Tuy nhiên, nó hoàn toàn an toàn để làm như vậy trong trường hợp này: đẩy giá trị Integer sẽ không gây ra bất kỳ lỗi nào; đẩy các giá trị không phải Integer sẽ gây ra lỗi loại.

Stack s = new Stack<Integer>() 

Đây là chuyển đổi hợp pháp từ loại được tham số thành loại thô. Bạn sẽ có thể đẩy giá trị của bất kỳ loại nào. Tuy nhiên, bất kỳ hoạt động nào như vậy sẽ dẫn đến cảnh báo "cuộc gọi không được kiểm tra".

Stack s = new Stack() 

Một lần nữa, điều này là hợp pháp, không có chuyển đổi ẩn. Bạn sẽ có thể đẩy giá trị của bất kỳ loại nào. Tuy nhiên, bất kỳ hoạt động nào như vậy sẽ dẫn đến cảnh báo "cuộc gọi không được kiểm tra".

Bạn cũng có thể nhận được cảnh báo "loại thô" bất kỳ lúc nào bạn tham chiếu đến loại Stack.