This is a narrow-down example of a case I came across.
Take a look at the code below:
class Holder<T> {
    private T t;
    public Holder(T t) {
        this.t = t;
    }
    public T getValue() {
        return t;
    }
}
public class FooMain {
    private static Object newHolder() {
        return new Holder<Integer>(3);
    }
    public static void main(String args[]) {
        Holder<String> hs = (Holder<String>) newHolder(); // line-18
        String s = hs.getValue();                         // line-19
    }
}
What spooked me is that the inevitable ClassCastException gets thrown on line-19 and not on line-18 !
Therefore, having an object in your code that's of type Holder<String> is not enough to guarantee that getValue will return a String. You also have to examine how this object was constructed!
I understand that Type Erasure plays a role here but I am not sure how wide the implications of the above are. In my particular case the newHolder-corresponding method is defined in an external library and returns java.lang.Object so I have to do these casts.
 
     
     
     
    