2013-08-11 1 views
0

j'avais un code en Java (Android) qui ressemblait à ceci:Sneaky Java jeté

for (Tuple tuple : xRange) { 
    Tuple5<Integer, Integer, Double, Double, Double> t = (Tuple5<Integer, Integer, Double, Double, Double>)tuple; 
    ... 
} 

Ce qui peut être une douleur à écrire. Au fait, Tuple5 dérive de Tuple.

J'ai donc écrit cette méthode:

@SuppressWarnings("unchecked") 
public static final <U1, U2 extends U1> U2 cast(U1 inst) { 
    return (U2)inst; 
} 

Attend méchant, hein? Mais cela m'a alors permis de réécrire le code comme ceci:

for (Tuple tuple : xRange) { 
    Tuple5<Integer, Integer, Double, Double, Double> t = cast(tuple); 
    ... 
} 

Je compile sur Android en utilisant le compilateur AIDE. Je pense qu'il ne peut même pas compiler sur d'autres systèmes.

Ma question est de savoir si cela fonctionne sur tous les compilateurs? Est-ce mauvais code? Et, si c'est le cas, alors pourquoi?

Merci

+0

Comment 'xRange' est-il déclaré? – jlordo

+0

Pensez-vous qu'il ne sera pas compilé sur d'autres systèmes, ou ne compile-t-il pas sur d'autres systèmes? Ce sont deux observations très différentes. – Jeffrey

+0

Dans la plupart des cas, c'est mauvais imho. Pas pire que le premier extrait, cependant. Cependant, je vous recommande de vérifier si le casting peut effectivement réussir avant de lancer, de sorte que vous pouvez passer par-dessus les entrées de collection non supportées (par rapport aux erreurs de votre programme sur les entrées non diffusables). – dst

Répondre

1

je pense qu'il est mauvais à cause de l'effacement de type, ce n'est pas un accident que vous obtenez un compilateur d'avertissement (que vous SUPPRIMER).

Votre méthode

public static final <U1, U2> U1 cast(U2 inst) { 
    return (U1)inst; 
} 

ressemble un peu à ceci après l'effacement de type:

public static final Object cast(Object inst) { 
    return (Object)inst; 
} 

donc ce ne sera pas le type de sécurité, qui jettent fait effectivement rien. Vous pouvez en savoir plus sur l'effacement de type here.

+0

Merci. Vous dites qu'il renvoie Object, mais comment est-il géré au moment de l'appel? ('t = cast (tuple);') –

+0

@ChrisNash il sera lancé comme dans le premier extrait (comme '(Tuple5 ) cast (tuple)'). – dst

+0

@ChrisNash voir [this] (http://stackoverflow.com/questions/11353555/what-happens-to-casts-using-generics-tobject-at-run-time-in-java?rq=1) question – Katona