Details
-
Bug
-
Status: Closed
-
Minor
-
Resolution: Fixed
-
4.0
-
None
Description
CollectionUtils#isEqualCollection(Collection, Collection, Equator) is defined as
public static boolean isEqualCollection(final Collection<?> a, final Collection<?> b, final Equator<?> equator) { ... }
This makes it possible to invoke it with a code like
public static class IntegerEquator implements Equator<Integer> { public boolean equate(Integer o1, Integer o2) { return o1.intValue() == o2.intValue(); } public int hash(Integer o) { return o.intValue(); } } @Test public void test() { List<Long> longList = Arrays.asList(1L, 2L); List<Integer> intList = Arrays.asList(1, 2); assertTrue(CollectionUtils.isEqualCollection(longList, intList, new IntegerEquator())); }
which compiles perfectly but throws a ClassCastException as Long cannot be cast to an Integer. However, the generics should be defined such that this is stopped at compile time itself.
If we modify the method to something like
public static <E> boolean isEqualCollection(final Collection<? extends E> a, final Collection<? extends E> b, final Equator<? super E> equator) { ... }
the above example would give a compile time error. imho we should modify this method with bounded wildcards. I don't think this change would break any existing binaries if the method is being used correctly, otherwise it is probably throwing ClassCastExceptions anyway.
Test case attached