Ce que vous essayez de faire est très utile et je trouve que je dois le faire très souvent dans le code que j'écris. Un exemple de cas d'utilisation:
Disons que nous avons une interface Fooet que nous avons un zorkingpackage qui a un ZorkingFooManagerqui crée et gère des instances de package-private ZorkingFoo implements Foo. (Un scénario très courant.)  
Donc, ZorkingFooManagerdoit contenir un private Collection<ZorkingFoo> zorkingFoosmais il doit exposer un fichier public Collection<Foo> getAllFoos().
La plupart des programmeurs java ne réfléchiraient pas à deux fois avant de l'implémenter getAllFoos()en allouant un nouveau ArrayList<Foo>, en le remplissant avec tous les éléments zorkingFooset en le renvoyant. J'apprécie l'idée qu'environ 30% de tous les cycles d'horloge consommés par le code java s'exécutant sur des millions de machines partout dans le monde ne font rien d'autre que créer des copies inutiles de ArrayLists qui sont récupérées en microsecondes après leur création.
La solution à ce problème est, bien entendu, de réduire la collection. Voici la meilleure façon de le faire:
static <T,U extends T> List<T> downCastList( List<U> list )
{
    return castList( list );
}
Ce qui nous amène à la castList()fonction:
static <T,E> List<T> castList( List<E> list )
{
    @SuppressWarnings( "unchecked" )
    List<T> result = (List<T>)list;
    return result;
}
La resultvariable intermédiaire est nécessaire en raison d'une perversion du langage java:
return (List<T>)list;produit une exception "cast non vérifié"; jusqu'ici tout va bien; mais alors:
 
@SuppressWarnings( "unchecked" ) return (List<T>)list; est une utilisation illégale de l'annotation suppress-warnings.
 
Ainsi, même s'il n'est pas casher à utiliser @SuppressWarningssur une returninstruction, il est apparemment bien de l'utiliser sur une affectation, donc la variable supplémentaire "result" résout ce problème. (Il devrait être optimisé par le compilateur ou par le JIT de toute façon.)