Il existe des situations où il est pratique d'avoir une valeur de type null renvoyée par une distribution de type au lieu de lancer une exception ClassCastException. C# a l'opérateur as
pour ce faire. Y at-il quelque chose d'équivalent disponible en Java, donc vous n'avez pas à vérifier explicitement l'exception ClassCastException?Comment émuler C# en tant qu'opérateur dans Java
Répondre
est ici une mise en œuvre comme, comme le suggère @Omar Kooheji:
public static <T> T as(Class<T> clazz, Object o){
if(clazz.isInstance(o)){
return clazz.cast(o);
}
return null;
}
as(A.class, new Object()) --> null
as(B.class, new B()) --> B
Vous pouvez utiliser le mot-clé instanceof
à la place du is
de C#, mais il n'y a rien comme as
.
Exemple:
if(myThing instanceof Foo) {
Foo myFoo = (Foo)myThing; //Never throws ClassCastException
...
}
Oui, le vieux double casting. Honte Java n'a pas quelque chose d'aussi élégant que l'opérateur 'as'. –
'comme' est une chose très utile. –
Je pense que vous auriez à rouler votre propre:
return (x instanceof Foo) ? (Foo) x : null;
EDIT: Si vous ne voulez pas que votre code client pour traiter les valeurs NULL, puis vous pouvez introduire un Null Object
interface Foo {
public void doBar();
}
class NullFoo implements Foo {
public void doBar() {} // do nothing
}
class FooUtils {
public static Foo asFoo(Object o) {
return (o instanceof Foo) ? (Foo) o : new NullFoo();
}
}
class Client {
public void process() {
Object o = ...;
Foo foo = FooUtils.asFoo(o);
foo.doBar(); // don't need to check for null in client
}
}
je spécule, vous pouvez créas propably un opérateur comme
quelque chose comme
as<T,Type> (left, right)
which evaluates to
if (typeof(left) == right)
return (right)left
else
return null
Je ne sais pas comment vous le faites, je suis C# au moment et mon chapeau de Java a obtenu un peu poussiéreux depuis que je quitté l'université.
Comparaison de type concret, c'est-à-dire 'typeof (left) == right' n'est pas ce que fait 'as'. – weston
Vous pouvez écrire une méthode d'utilitaire statique comme celle-ci. Je ne pense pas que ce soit terriblement lisible, mais c'est la meilleure approximation de ce que vous essayez de faire. Et si vous utilisez des importations statiques, ce ne serait pas trop mal en termes de lisibilité.
package com.stackoverflow.examples;
public class Utils {
@SuppressWarnings("unchecked")
public static <T> T safeCast(Object obj, Class<T> type) {
if (type.isInstance(obj)) {
return (T) obj;
}
return null;
}
}
Voici un test qui montre comment cela fonctionne (et qu'il fonctionne.)
package com.stackoverflow.examples;
import static com.stackoverflow.examples.Utils.safeCast;
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertNull;
import org.junit.Test;
public class UtilsTest {
@Test
public void happyPath() {
Object x = "abc";
String y = safeCast(x, String.class);
assertNotNull(y);
}
@Test
public void castToSubclassShouldFail() {
Object x = new Object();
String y = safeCast(x, String.class);
assertNull(y);
}
@Test
public void castToUnrelatedTypeShouldFail() {
Object x = "abc";
Integer y = safeCast(x, Integer.class);
assertNull(y);
}
}
Cela ne fonctionne pas réellement. isAssignableFrom teste si obj est une instance d'une super-classe de T. Ainsi, safeCast (new Object(), A.class) .doA() renverra une exception de cast de classe, plutôt qu'une NPE. –
vous avez raison. J'ai eu les deux objets de classe à l'envers. J'ai édité la réponse et cela devrait être correct maintenant. –
Y a-t-il une raison particulière pour utiliser type.isAssignableFrom (obj.getClass() au lieu de type.isInstance (obj)? – VoidPointer
En Java 8, vous pouvez également utiliser la syntaxe de flux avec facultatif:
Object o = new Integer(1);
Optional.ofNullable(o)
.filter(Number.class::isInstance)
.map(Number.class::cast)
.ifPresent(n -> System.out.print("o is a number"));
- 1. Java: exécuté en tant qu'administrateur
- 2. Comment émuler le comportement 'include' dans MATLAB?
- 3. .NET en tant que client, Java en tant que serveur
- 4. Comment émuler "AppendDataBoundItems" dans ComboBox de Silverlight?
- 5. comment émuler un bon motif
- 6. Comment lancer une interface en tant que type dans C#?
- 7. Jython: Instanciation de la classe java dans un script en tant qu'objet Java, pas en tant qu'objet Python
- 8. Calcul d'un mois en tant que période "entre" dans java
- 9. Comment émuler le mécanisme d'édition/mise à jour d'ADO pour SQLite en C++?
- 10. C# - Émuler le périphérique - Parallèle au port série
- 11. Comment puis-je émuler ErrorProvider dans .NET Compact Framework?
- 12. Comment émuler l'opérateur de complément de langage dans .hgignore?
- 13. Comment émuler les paramètres printf de Python dans Ruby?
- 14. YAML en tant que DSL de données dans .NET (C#)
- 15. Comment faire pour émuler ScriptManager.RegisterStartupScript() dans le projet ASP.NET MVC
- 16. Interprète Python en tant que classe C++
- 17. Émuler un serveur radius dans .NET
- 18. Peut-on émuler StringBuilder dans XSLT?
- 19. Obtenir optarg en tant qu'objet chaîne C++
- 20. Activer l'application C en tant que Webservice
- 21. C# SQL Top en tant que paramètre
- 22. Convertisseur Java en C#
- 23. Convertisseur Java en C#
- 24. Panneau C# en tant que conteneur MDI
- 25. Execute PowerShell en tant qu'administrateur de C#
- 26. Conversion de Java en C#
- 27. Comment accepter n'importe quel type de nombre dans une fonction en tant qu'argument en C#?
- 28. Comment passer des références en tant qu'arguments dans une méthode en C#
- 29. délégué en tant que classe externe en Objective-C
- 30. Comment apprendre des procédures stockées dans SQL Server en tant que programmeur Java?
Aaron, que se passe-t-il si je veux passer un type générique comme le paramètre clazz à votre fonction "as"? – mfalto
self answer ... que je ne peux pas faire en Java à cause de l'effacement de type – mfalto
J'aime la conception de la fonction ci-dessus 'as', mais cela me dérange le fait que la méthode' isInstance' sera invoquée deux fois, en raison de l'utilisation de la méthode 'cast' de la classe' Classe »En interne, cette méthode utilise la méthode 'IsIsntance' pour vérifier la compatibilité entre les types. Néanmoins, nous pouvons nous attendre à ce que la JVM puisse aligner le code 'cast' dans la fonction' as' donnée et après que le Jitter puisse supprimer les appels redondants à la méthode 'IsInstance', mais nous ne pouvons en être sûrs. –