Hôm nay, tôi phát hiện ra rằng một người có thể put
một đối tượng trong một hiện tại Map
ngay cả khi đối tượng không thể được truyền sang đúng loại.Đặt đối tượng có loại không nhất quán trong Bản đồ được khởi tạo - được mong đợi và hợp pháp?
Đầu tiên, hãy để tôi bắt đầu với một ví dụ đơn giản:
Map<Integer, String> myMap = new HashMap<>(); //plain old hashmap
myMap.put(9,"star"); //no problem
myMap.put(10, 1.2); //Incompatible type, the compiler yells
Map<Integer, Double> aMap = (Map<Integer, Double>) myMap; //Cannot cast, the compiler yells
Cho đến nay, tất cả mọi thứ được mong đợi, như bạn nên không có thể đặt một đối tượng kiểu không phù hợp vào một Bản đồ đã được xây dựng. Bây giờ chúng ta hãy xem xét điều này:
public class NoRulesForMe {
static Object theRing;
public static void main(String[] args){
Map<Integer, String> myMap = new HashMap<>();
myMap.put(9,"star");
Map<Integer, Double> myMapMorphed = castWildly(myMap);
myMapMorphed.put(99, 3.14);
System.out.println(myMapMorphed.get(9)); //"star", as we put in
System.out.println(myMapMorphed.get(99)); //3.14, as we put in
}
public static <T> T castWildly(Object value){
theRing = value;
T morphed = (T) theRing;
return morphed;
}
}
Tôi ngạc nhiên rằng điều này không gây ra một lỗi thời gian chạy - làm thế nào để đạt được điều này Bản đồ, và là hành vi này được quy định trong JLS hay API và do đó có thể được dựa trên ?
Lý do tôi hỏi là tôi thấy một phiên bản khác (có liên quan) trong mã sản xuất, và tôi tự hỏi, ngay cả khi điều này có thể bị xáo trộn và có mùi, nó có thể được đảm bảo hoạt động tốt hay không. Mội thông tin đầu vào đều sẽ được xem xét kĩ.
Bạn cần google "loại xóa". –
Đây là _inherent_ trong việc thực hiện các Generics của Java. –
@LouisWasserman Bạn có thể xây dựng trên * những gì * là vốn có trong Generics của Java? Tôi không ngạc nhiên khi trình biên dịch không phàn nàn. Nhưng câu hỏi lớn hơn, tôi nghĩ, là cách Java cho phép một 'Double' có thể được lưu trữ như một' String'. – flow2k