From fb426fe6116523cdc32be3794caa0a6553bb2b93 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Wed, 10 Dec 2014 17:36:01 +0100 Subject: [PATCH] Demonstrate that the CollectionFactory API is not type-safe This commit introduces test methods in CollectionFactoryTests that demonstrate how the APIs for createApproximateCollection() and createApproximateMap() are not type-safe, specifically regarding the use of generics, raw types, and casting. --- .../core/CollectionFactoryTests.java | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/spring-core/src/test/java/org/springframework/core/CollectionFactoryTests.java b/spring-core/src/test/java/org/springframework/core/CollectionFactoryTests.java index a67da64f6ca..b3be5d4cc53 100644 --- a/spring-core/src/test/java/org/springframework/core/CollectionFactoryTests.java +++ b/spring-core/src/test/java/org/springframework/core/CollectionFactoryTests.java @@ -51,6 +51,61 @@ import static org.springframework.core.CollectionFactory.*; */ public class CollectionFactoryTests { + /** + * The test demonstrates that the generics-based API for + * {@link CollectionFactory#createApproximateCollection(Object, int)} + * is not type-safe. + *

Specifically, the parameterized type {@code E} is not bound to + * the type of elements contained in the {@code collection} argument + * passed to {@code createApproximateCollection()}. Thus casting the + * value returned by {@link EnumSet#copyOf(EnumSet)} to + * {@code (Collection)} cannot guarantee that the returned collection + * actually contains elements of type {@code E}. + */ + @Test + public void createApproximateCollectionIsNotTypeSafe() { + Collection ints = createApproximateCollection(EnumSet.of(Color.BLUE), 3); + + // Use a try-catch block to ensure that the exception is thrown as a result of the + // next line and not as a result of the previous line. + try { + // Note that ints is of type Collection, but the collection returned + // by createApproximateCollection() is of type Collection. + ints.iterator().next().intValue(); + fail("Should have thrown a ClassCastException"); + } + catch (ClassCastException e) { + /* expected */ + } + } + + /** + * The test demonstrates that the generics-based API for + * {@link CollectionFactory#createApproximateMap(Object, int)} + * is not type-safe. + *

The reasoning is similar that described in + * {@link #createApproximateCollectionIsNotTypeSafe()}. + */ + @Test + public void createApproximateMapIsNotTypeSafe() { + EnumMap enumMap = new EnumMap<>(Color.class); + enumMap.put(Color.RED, 1); + enumMap.put(Color.BLUE, 2); + Map map = createApproximateMap(enumMap, 3); + + // Use a try-catch block to ensure that the exception is thrown as a result of the + // next line and not as a result of the previous line. + try { + // Note that the 'map' key is of type String, but the keys in the map returned + // by createApproximateMap() are of type Color. + map.keySet().iterator().next().split(","); + fail("Should have thrown a ClassCastException"); + } + catch (ClassCastException e) { + /* expected */ + } + } + @Test public void createsCollectionsCorrectly() { // interfaces