8

Tôi hiện đang viết trình biên dịch Java và đã triển khai phần 15.12.2.7. của JLS7 (http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.12.2.7), một trong những phần khó chịu nhất của thông số kỹ thuật. Tôi vẫn có một vấn đề kể từ khi spec bằng cách nào đó có vẻ không được xác định hoặc mơ hồ. Vấn đề của tôi là dòng này:Phương pháp loại suy luận trong đặc tả Java

lcta (U) =? nếu giới hạn trên của U là Object, nếu không thì sao? mở rộng lub (U, Object)

U là một biểu thức kiểu tùy ý. Giới hạn trên của biểu thức kiểu là gì? Ngoài ra, tại sao lcta luôn là một ký tự đại diện?

Các spec định nghĩa

CandidateInvocation (G) = LCI (Inv (G)).

Bây giờ, ví dụ, hãy xem xét trường hợp Inv (G) = {Liệt kê < Chuỗi >}, nghĩa là lời mời ứng viên duy nhất có thể là một kiểu tham số duy nhất. Bây giờ, do sự cai trị

LCI (G < X1, ..., Xn >) = G < lcta (X1), ..., lcta (Xn) >,

kết quả của CandidateInvocation (G) = LCI ({Danh sách < Chuỗi >}) sẽ được xác định như sau:

Danh sách < lcta (string) >

theo ý kiến ​​của tôi, lcta nên Simp ly return String ở đây, bởi vì nếu Danh sách < Chuỗi > là lời gọi duy nhất có thể, thì tốt hơn là suy ra Danh sách < Chuỗi > làm đối số. Tuy nhiên, định nghĩa của lcta (U) chỉ ra rằng kết quả là gì? hoặc là ? mở rộng lub (...), vì vậy kết quả là LUÔN LUÔN là một ký tự đại diện. Điều này có vẻ lạ. Tôi hiểu sai điều gì ở đây?

Trả lời

1

Tôi đã yêu cầu trong danh sách gửi thư của trình biên dịch-dev và nhận được câu trả lời:

Có, đặc điểm kỹ thuật ở đây sai. Quy tắc cho lcta (U) đơn giản là tổng số crap :). Ngoài ra, họ tuyên bố rằng sẽ tốt hơn nếu không gọi lcta (U) cho một đối số duy nhất và chỉ sử dụng U (vì đối số kiểu ít phổ biến nhất của một đối số U phải luôn là U).

6

Điều này giống như lỗi của thông số kỹ thuật. Điều khoản của lcta(U) không tồn tại trong JSL3. Rõ ràng định nghĩa của JLS3 là lci(e1..en) không đầy đủ khi n=1 và thông số kỹ thuật mới cố khắc phục. Nhưng sửa chữa có vẻ vô nghĩa, như bạn đã lý luận.

Javac7 tính lci({ List<String> }) làm List<String>, bỏ qua các mệnh đề đã thêm.

Vấn đề này nên được nâng lên cho người bảo trì cụ thể; không chắc cách liên hệ với họ. Bạn có thể thử openjdk compiler-dev danh sách gửi thư; có một số người hiểu biết về nó.

+0

Tôi hiện đã triển khai lcta (U) = U có vẻ hoạt động tốt. Tôi sẽ báo cáo nếu tôi tìm thấy bất kỳ trường hợp nào việc triển khai này tạo ra kết quả đáng ngạc nhiên.By the way: Không phải là lub (U, Object) luôn luôn U, vì Object luôn luôn là một lớp siêu của U và do đó giảm thiểu ứng cử viên bị xóa MEC của {U, Object} nên luôn luôn mang lại U hoặc một trong các lớp con của nó? Vì vậy, quy tắc thực sự là hoàn toàn crap. Điều duy nhất mà nó có thể là tốt cho việc chuyển đổi? mở rộng đối tượng để? Tuy nhiên, vì U là một biểu thức kiểu, nó không thể chứa các ký tự đại diện nên trường hợp này có thể không bao giờ phát sinh ... thực sự lạ. – gexicide

+0

và ý tưởng tốt với danh sách gửi thư, tôi nghĩ rằng tôi sẽ thử nó ở đó – gexicide

+0

Tôi nghĩ lub (U, Object) = Object – irreputable