2013-03-07 32 views
7

Có một phương pháp trong thư viện hamcrest:Đối với phương pháp loại T, loại 'suy ra' của nó là gì khi cần hai đối số <? super T>?

package org.hamcrest.core 

... 

public static <T> Matcher<T> allOf(Matcher<? super T> first, Matcher<? super T> second) { 
    List<Matcher<? super T>> matchers = new ArrayList<Matcher<? super T>>(2); 
    matchers.add(first); 
    matchers.add(second); 
    return allOf(matchers); 
} 

Trong mã của tôi, tôi gọi phương pháp này với firstMatcher<Object>secondMatcher<SomeException>.

Và bây giờ:

  • Khi tôi biên dịch nó với Eclipse với 1,6 mục tiêu, nó làm cho <T>Matcher<SomeException>.
  • Khi tôi biên dịch nó với javac 1.7 với mục tiêu 1.6, nó làm cho <T>Matcher<SomeException>.
  • Khi tôi biên dịch nó với javac 1.6 với 1.6 mục tiêu, nó làm cho <T>Matcher<Object>

Câu hỏi đặt ra là, những gì <T> phải ở trong trường hợp như vậy?

Hiểu biết của tôi là có lỗi trong javac 1.6 và phải là Matcher<SomeException>, vì đây là loại phổ biến cho đối số đầu vào (SomeException là một kiểu con của đối tượng) và sau đó, nó chắc chắn 100%. Matcher sẽ là Matcher<SomeException>.

Tôi có đúng không? Và có cách nào để buộc javac 1.6 hoạt động đúng không?

Trả lời

3

Trình biên dịch sẽ thực hiện inference based on actual arguments. Nó sẽ bắt đầu với các ràng buộc ban đầu của Matcher<Object> << Matcher<? super T>Matcher<SomeException> << Matcher<? super T>. Từ đó nó sẽ suy ra các ràng buộc T << ObjectT << SomeException. Object sẽ được loại bỏ khi minimal erased candidate set được tạo. Ứng cử viên còn lại SomeException sẽ (cuối cùng: D) được thay thế cho T.

Cho đến nay chúng tôi đã hiển thị nhật thực và JDK7 hoạt động chính xác trong trường hợp này. Tôi không nghĩ rằng có bất kỳ cách nào để buộc javac để hành xử một cách chính xác là tốt. Bạn có thể khai báo rõ ràng đối số kiểu hoặc sử dụng JDK7 (chỉ rõ nguồn và đích là 6).

1

Có hai điều bạn nên cân nhắc:

  1. Trước tiên, bạn có thể sử dụng nó như thế này: CoreMatcher.<SomeException>allOf(...) đó sẽ thiết lập một cách rõ ràng T.

  2. Thứ hai, do loại tẩy xóa, vì thời gian chạy bạn luôn có một số Matcher<Object>. Vì vậy, trong cả hai trường hợp, hành vi thời gian chạy là như nhau.

+0

Bắt kịp với CoreMatcher, nhưng đó là CoreMatchers trong hamcrest của tôi :) Về điểm thứ hai - tôi biết. Tôi đã có thể biên dịch với nhật thực và chạy thử nghiệm mvn sau đó. – Marcin

Các vấn đề liên quan