I'm really trying to like generics, but so far the trouble they've caused outweighs any benefits. Please, please show me I'm wrong.
I understand the necessity of adding @SuppressWarnings("unchecked") when using generic-free frameworks (Spring, Hibernate). This alone really reduces generics' value, as does requiring classes be passed into the constructor to avoid the pitfalls of erasure. However, the real thorn always seems to be casting. I usually try for a while to get the syntax right, but then give up my attempt at purity, add a @SuppressWarnings, and move on with my life.
Here's an example: I'm reflecting over a bean to look for differences between two instances. Some properties implement Comparable such that (a.equals(b) == false) but (a.compareTo(b) == 0) (e.g. BigDecimal, Date). In these cases, I want the property to be considered the same.
MyObject original = getOriginal();
MyObject updated = getUpdated();
for (PropertyDescriptor pd : BeanUtils.getPropertyDescriptors(MyObject.class)) {
// Assume I'm putting in the try/catch block
Object pOriginal = pd.getReadMethod().invoke(original, (Object[]) null);
Object pUpdated = pd.getReadMethod().invoke(updated, (Object[]) null);
boolean isPropertySame;
if (Comparable.class.isAssignableFrom(pOriginal.getClass())) {
// Type safety: The method compareTo(Object) belongs to the raw type Comparable. References to generic type Comparable<T> should be parameterized
isPropertySame = Comparable.class.cast(pOriginal).compareTo(Comparable.class.cast(pUpdated)) == 0;
// The method compareTo(capture#19-of ?) in the type Comparable<capture#19-of ?> is not applicable for the arguments (capture#21-of ? extends Comparable)
Comparable<?> comparable = Comparable.class.cast(pOriginal);
isPropertySame = comparable.compareTo(comparable.getClass().getTypeParameters()[0].getGenericDeclaration().cast(pUpdated)) == 0;
// Even if I get the generics right, I still get an error if pOriginal is java.sql.Timestamp and pUpdated is java.util.Date (happens all the time with Hibernate).
isPropertySame = (help);
} else {
isPropertySame = pOriginal.equals(pUpdated);
}
if (!isPropertySame) {
PropertyDelta delta = new PropertyDelta(pd, pOriginal, pUpdated);
dao.save(delta);
}
}
Any ideas on what I could put into (help)?