-
Bug
-
Resolution: Fixed
-
P4
-
7
-
b43
-
x86
-
linux, windows_7
-
Verified
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8018862 | 7u45 | Alan Bateman | P4 | Closed | Fixed | b01 |
JDK-8016353 | 7u40 | Alan Bateman | P4 | Closed | Fixed | b30 |
FULL PRODUCT VERSION :
java version "1.7.0_03"
Java(TM) SE Runtime Environment (build 1.7.0_03-b04)
Java HotSpot(TM) 64-Bit Server VM (build 22.1-b02, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Linux medea 2.6.35-32-generic #67-Ubuntu SMP Mon Mar 5 19:39:49 UTC 2012 x86_64 GNU/Linux
A DESCRIPTION OF THE PROBLEM :
The EnumMap clone implementation does not clear the field entrySet. Therefore, any call to the method entrySet in a cloned map (with its entrySet initialized) ) will return a reference to the original entrySet instead of returning a new entrySet pointing to the new map instance.
This breaks the Map.entrySet contract which states " Returns a Set view of the mappings contained in this map"
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
This happens every time a EnumMap, which has its entrySet initialized, is cloned. All changes made to the new instance won't be reflected by the EntrySet returned by the entrySet() method.
Example:
import java.util.EnumMap;
import java.util.Map.Entry;
public class TestEnumMap {
public enum Test {
ONE, TWO
}
public static void main(String[] args) {
EnumMap<Test, String> map1 = new EnumMap<Test, String>(Test.class);
map1.put(Test.ONE, "1");
map1.put(Test.TWO, "2");
for (Entry<Test, String> entry : map1.entrySet()) {
System.out.println(entry);
}
System.out.println("---------------");
EnumMap<Test, String> map2 = map1.clone();
map2.remove(Test.ONE);
for (Entry<Test, String> entry : map2.entrySet()) {
System.out.println(entry);
}
}
}
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
ONE=1
TWO=2
---------------
TWO=2
ACTUAL -
ONE=1
TWO=2
---------------
ONE=1
TWO=2
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.util.EnumMap;
import java.util.Map.Entry;
public class TestEnumMap {
public enum Test {
ONE, TWO
}
public static void main(String[] args) {
EnumMap<Test, String> map1 = new EnumMap<Test, String>(Test.class);
map1.put(Test.ONE, "1");
map1.put(Test.TWO, "2");
for (Entry<Test, String> entry : map1.entrySet()) {
System.out.println(entry);
}
System.out.println("---------------");
EnumMap<Test, String> map2 = map1.clone();
map2.remove(Test.ONE);
for (Entry<Test, String> entry : map2.entrySet()) {
System.out.println(entry);
}
}
}
---------- END SOURCE ----------
java version "1.7.0_03"
Java(TM) SE Runtime Environment (build 1.7.0_03-b04)
Java HotSpot(TM) 64-Bit Server VM (build 22.1-b02, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Linux medea 2.6.35-32-generic #67-Ubuntu SMP Mon Mar 5 19:39:49 UTC 2012 x86_64 GNU/Linux
A DESCRIPTION OF THE PROBLEM :
The EnumMap clone implementation does not clear the field entrySet. Therefore, any call to the method entrySet in a cloned map (with its entrySet initialized) ) will return a reference to the original entrySet instead of returning a new entrySet pointing to the new map instance.
This breaks the Map.entrySet contract which states " Returns a Set view of the mappings contained in this map"
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
This happens every time a EnumMap, which has its entrySet initialized, is cloned. All changes made to the new instance won't be reflected by the EntrySet returned by the entrySet() method.
Example:
import java.util.EnumMap;
import java.util.Map.Entry;
public class TestEnumMap {
public enum Test {
ONE, TWO
}
public static void main(String[] args) {
EnumMap<Test, String> map1 = new EnumMap<Test, String>(Test.class);
map1.put(Test.ONE, "1");
map1.put(Test.TWO, "2");
for (Entry<Test, String> entry : map1.entrySet()) {
System.out.println(entry);
}
System.out.println("---------------");
EnumMap<Test, String> map2 = map1.clone();
map2.remove(Test.ONE);
for (Entry<Test, String> entry : map2.entrySet()) {
System.out.println(entry);
}
}
}
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
ONE=1
TWO=2
---------------
TWO=2
ACTUAL -
ONE=1
TWO=2
---------------
ONE=1
TWO=2
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.util.EnumMap;
import java.util.Map.Entry;
public class TestEnumMap {
public enum Test {
ONE, TWO
}
public static void main(String[] args) {
EnumMap<Test, String> map1 = new EnumMap<Test, String>(Test.class);
map1.put(Test.ONE, "1");
map1.put(Test.TWO, "2");
for (Entry<Test, String> entry : map1.entrySet()) {
System.out.println(entry);
}
System.out.println("---------------");
EnumMap<Test, String> map2 = map1.clone();
map2.remove(Test.ONE);
for (Entry<Test, String> entry : map2.entrySet()) {
System.out.println(entry);
}
}
}
---------- END SOURCE ----------
- backported by
-
JDK-8016353 EnumMap clone doesn't clear the entrySet keeping a reference to the original Map
-
- Closed
-
-
JDK-8018862 EnumMap clone doesn't clear the entrySet keeping a reference to the original Map
-
- Closed
-