Existe-t-il un moyen de convertir un objet pour renvoyer la valeur d'une méthode? J'ai essayé de cette façon mais il a donné une exception de temps de compilation dans la partie "instanceof":
public static <T> T convertInstanceOfObject(Object o) {
if (o instanceof T) {
return (T) o;
} else {
return null;
}
}
J'ai aussi essayé celui-ci mais il a donné une exception d'exécution, ClassCastException:
public static <T> T convertInstanceOfObject(Object o) {
try {
T rv = (T)o;
return rv;
} catch(Java.lang.ClassCastException e) {
return null;
}
}
Est-il possible de le faire facilement:
String s = convertInstanceOfObject("string");
System.out.println(s); // should print "string"
Integer i = convertInstanceOfObject(4);
System.out.println(i); // should print "4"
String k = convertInstanceOfObject(345435.34);
System.out.println(k); // should print "null"
EDIT: J'ai écrit une copie de travail de la bonne réponse:
public static <T> T convertInstanceOfObject(Object o, Class<T> clazz) {
try {
return clazz.cast(o);
} catch(ClassCastException e) {
return null;
}
}
public static void main(String args[]) {
String s = convertInstanceOfObject("string", String.class);
System.out.println(s);
Integer i = convertInstanceOfObject(4, Integer.class);
System.out.println(i);
String k = convertInstanceOfObject(345435.34, String.class);
System.out.println(k);
}
Vous devez utiliser une instance Class
en raison de l'effacement du type générique lors de la compilation.
public static <T> T convertInstanceOfObject(Object o, Class<T> clazz) {
try {
return clazz.cast(o);
} catch(ClassCastException e) {
return null;
}
}
La déclaration de cette méthode est:
public T cast(Object o)
Ceci peut également être utilisé pour les types de tableaux. Cela ressemblerait à ceci:
final Class<int[]> intArrayType = int[].class;
final Object someObject = new int[]{1,2,3};
final int[] instance = convertInstanceOfObject(someObject, intArrayType);
Notez que lorsque someObject
est passé à convertToInstanceOfObject
, il a le type de temps de compilation Object
.
Je suis tombé sur cette question et cela a attiré mon intérêt. La réponse acceptée est tout à fait correcte, mais je pensais fournir mes conclusions au niveau du code en octets de la machine virtuelle Java pour expliquer pourquoi le PO rencontrait le ClassCastException
.
J'ai le code qui est à peu près le même que le code de l'OP:
public static <T> T convertInstanceOfObject(Object o) {
try {
return (T) o;
} catch (ClassCastException e) {
return null;
}
}
public static void main(String[] args) {
String k = convertInstanceOfObject(345435.34);
System.out.println(k);
}
et le code d'octet correspondant est:
public static <T> T convertInstanceOfObject(Java.lang.Object);
Code:
0: aload_0
1: areturn
2: astore_1
3: aconst_null
4: areturn
Exception table:
from to target type
0 1 2 Class Java/lang/ClassCastException
public static void main(Java.lang.String[]);
Code:
0: ldc2_w #3 // double 345435.34d
3: invokestatic #5 // Method Java/lang/Double.valueOf:(D)Ljava/lang/Double;
6: invokestatic #6 // Method convertInstanceOfObject:(Ljava/lang/Object;)Ljava/lang/Object;
9: checkcast #7 // class Java/lang/String
12: astore_1
13: getstatic #8 // Field Java/lang/System.out:Ljava/io/PrintStream;
16: aload_1
17: invokevirtual #9 // Method Java/io/PrintStream.println:(Ljava/lang/String;)V
20: return
Notez que l'instruction de code d'octet checkcast
se produit dans la méthode principale et que la méthode convertInstanceOfObject
et convertInstanceOfObject
ne comporte aucune instruction pouvant renvoyer ClassCastException
. Parce que la méthode principale ne récupère pas la ClassCastException
, par conséquent, lorsque vous l'exécuterez, vous obtiendrez une ClassCastException
et non l'attente de l'impression null
.
Maintenant, je modifie le code en fonction de la réponse acceptée:
public static <T> T convertInstanceOfObject(Object o, Class<T> clazz) {
try {
return clazz.cast(o);
} catch (ClassCastException e) {
return null;
}
}
public static void main(String[] args) {
String k = convertInstanceOfObject(345435.34, String.class);
System.out.println(k);
}
Le code d'octet correspondant est:
public static <T> T convertInstanceOfObject(Java.lang.Object, Java.lang.Class<T>);
Code:
0: aload_1
1: aload_0
2: invokevirtual #2 // Method Java/lang/Class.cast:(Ljava/lang/Object;)Ljava/lang/Object;
5: areturn
6: astore_2
7: aconst_null
8: areturn
Exception table:
from to target type
0 5 6 Class Java/lang/ClassCastException
public static void main(Java.lang.String[]);
Code:
0: ldc2_w #4 // double 345435.34d
3: invokestatic #6 // Method Java/lang/Double.valueOf:(D)Ljava/lang/Double;
6: ldc #7 // class Java/lang/String
8: invokestatic #8 // Method convertInstanceOfObject:(Ljava/lang/Object;Ljava/lang/Class;)Ljava/lang/Object;
11: checkcast #7 // class Java/lang/String
14: astore_1
15: getstatic #9 // Field Java/lang/System.out:Ljava/io/PrintStream;
18: aload_1
19: invokevirtual #10 // Method Java/io/PrintStream.println:(Ljava/lang/String;)V
22: return
Notez qu'il existe une instruction invokevirtual
dans la méthode convertInstanceOfObject
qui appelle la méthode Class.cast()
qui renvoie ClassCastException
qui sera interceptée par la fonction catch(ClassCastException e)
bock et renvoie null
; par conséquent, "null" est imprimé sur la console sans aucune exception.
Si vous ne voulez pas dépendre d'une exception de projection (ce que vous ne devriez probablement pas faire), vous pouvez essayer ceci:
public static <T> T cast(Object o, Class<T> clazz) {
return clazz.isInstance(o) ? clazz.cast(o) : null;
}