TypeUtils { public static Type[] normalizeUpperBounds(final Type[] bounds) { Validation.notNull(bounds, msg.nullSpecifiedForBounds()); if (bounds.length < 2) { return bounds; } final Set<Type> types = new HashSet<>(bounds.length); for (final Type type1 : bounds) { boolean subtypeFound = false; for (final Type type2 : bounds) { if (type1 != type2 && isAssignable(type2, type1, null)) { subtypeFound = true; break; } } if (!subtypeFound) { types.add(type1); } } return types.toArray(new Type[0]); } private  TypeUtils(); static boolean isAssignable(final Type type, final Type toType); static Type[] normalizeUpperBounds(final Type[] bounds); static boolean equals(final Type t1, final Type t2); static String toString(final Type type); static int[] add(int[] array, int element);  }
@Test public void testNormalizeUpperBounds() { final Type[] typeArray = { String.class, String.class }; final Type[] expectedArray = { String.class }; assertArrayEquals(expectedArray, TypeUtils.normalizeUpperBounds(typeArray)); }