Tôi đã gặp một hành vi kỳ lạ của Java có vẻ như là một lỗi. Là nó? Đúc một đối tượng cho một loại chung (ví dụ: K
) không ném ClassCastException
ngay cả khi đối tượng không phải là một phiên bản của K
. Dưới đây là một ví dụ:Việc đưa vào kiểu generic trong Java không làm tăng ClassCastException?
import java.util.*;
public final class Test {
private static<K,V> void addToMap(Map<K,V> map, Object ... vals) {
for(int i = 0; i < vals.length; i += 2)
map.put((K)vals[i], (V)vals[i+1]); //Never throws ClassCastException!
}
public static void main(String[] args) {
Map<String,Integer> m = new HashMap<String,Integer>();
addToMap(m, "hello", "world"); //No exception
System.out.println(m.get("hello")); //Prints "world", which is NOT an Integer!!
}
}
Cập nhật: Nhờ Cletus và Andrzej Doyle cho câu trả lời hữu ích của bạn. Vì tôi chỉ có thể chấp nhận một, tôi chấp nhận Andrzej Doyle's answer vì nó đã dẫn tôi đến một giải pháp mà tôi nghĩ không phải là quá xấu. Tôi nghĩ rằng đó là một cách tốt hơn để khởi tạo một Bản đồ nhỏ trong một lớp lót.
/**
* Creates a map with given keys/values.
*
* @param keysVals Must be a list of alternating key, value, key, value, etc.
* @throws ClassCastException if provided keys/values are not the proper class.
* @throws IllegalArgumentException if keysVals has odd length (more keys than values).
*/
public static<K,V> Map<K,V> build(Class<K> keyClass, Class<V> valClass, Object ... keysVals)
{
if(keysVals.length % 2 != 0)
throw new IllegalArgumentException("Number of keys is greater than number of values.");
Map<K,V> map = new HashMap<K,V>();
for(int i = 0; i < keysVals.length; i += 2)
map.put(keyClass.cast(keysVals[i]), valClass.cast(keysVals[i+1]));
return map;
}
Và sau đó bạn gọi nó là như thế này:
Map<String,Number> m = MapBuilder.build(String.class, Number.class, "L", 11, "W", 17, "H", 0.001);
Tôi chỉ hy vọng một cách an toàn để khởi tạo một bản đồ trong một lớp lót, giống như trong một số ngôn ngữ khác (ví dụ: Perl/PHP/Javascript), nơi bạn có thể làm một cái gì đó như 'map = (key1 => val1, key2 => val2, vv), ' – Kip
Đúng - bạn không thể làm điều đó, vì mảng không có thông tin kiểu thời gian biên dịch và thông số chung không có thông tin kiểu thời gian chạy. Việc truyền các tham số 'Class' là cách duy nhất để bạn có thể kết hợp thời gian biên dịch và kiểm tra thời gian chạy với nhau. –