2010-11-13 19 views
1

Je voudrais trouver un moyen de vérifier dynamiquement si la chaîne est analysable dans un type donné. autrement dit,type de réflexion vérifiant?

public boolean canBeParsed(String type, String val) { 
    // use reflect to check if val can be parsed into type 
} 

clairement, je voudrais être en mesure contrôle différents types avec des valeurs différentes ..

types

seront chaînes comme: java.lang.Integer

- -------- ------------- plus

donc par exemple, si j'appelle cette fonction,

canBeParsed("Java.lang.Integer", "1"); //returns true 

canBeParsed("Java.lang.Integer", "HelloWorld"); //returns false 

canBeParsed("Java.lang.String", "HelloWorld"); //returns true 

canBeParsed("Java.lang.Boolean", "false"); // returns true 

canBeParsed("Java.lang.Boolean", "HelloWorld"); //returns false 
+0

Pouvez-vous donner un meilleur exemple? Ce n'est pas clair ce que vous demandez. – skaffman

+0

est ce devoir? Si c'est le cas, veuillez le marquer comme tel. –

Répondre

1

Cette méthode fonctionne avec les classes qui déclarent une méthode staticOf statique. Toute classe sans cela retournera false. Plusieurs exceptions ont été omises pour garder le code court.

Class<?> cls = Class.forName(type); 
//Get a converter method, String to type 
//Requires static method valueOf 
Method converter; 
try{ 
converter = cls.getDeclaredMethod("valueOf",new Class[]{String.class}); 
}catch(NoSuchMethodError ex){ 
    //No conversion method found 
    return false; 
} 
if(!Modifier.isStatic(converter.getModifiers()){ 
    //the method has to be static in order to be called by us 
    return false; 
} 
if(!cls.isAssignableFrom(converter.getReturnType()) 
    //The conversion method has the wrong return type 
    return false; 
try{ 
    //try to parse the value 
    Object o = converter.invoke(null,new Object[]{value}; 
    if(o == null)return false;//false if method returned null 
    else return true;//success 
}catch(Exception ex) 
{ 
    //could not parse value 
    return false; 
} 

La méthode valueOf (String) est présent dans les classes wrapper Short, Long, Integer, Float, Double, Boolean il prend en charge ces derniers et toute autre classe qui a cette méthode.

+0

merci! a bien fonctionné. bien sûr, a dû mettre le cas évident: "if (type.equals (" java.lang.String ")) return true;" pour les personnes qui peuvent trouver ce code utile. –

1

Une vérification de type dynamique est quelque chose de différent de ce que vous demandez. Avec une vérification dynamique, vous vérifiez si un obet est une instance d'un type spécifique (fondamentalement, le type sametype ou le type plus étroit sera autorisé) et vous pouvez le faire avec l'opérateur instanceof. Mais cela implique la hiérarchie des objets et non le concept "peut être converti en" que vous aimeriez avoir. Vous pouvez essayer avec string instanceof Integer mais ce sera toujours faux.

Dans votre situation, vous voulez vérifier si une chaîne rapresents un nombre entier et vous devez le faire d'une manière différente:

try { 
    int number = Integer.parseInt(string); 
} 
catch (NumberFormatException e) { 
    System.out.println("String is not an integer string!"); 
} 

Sinon, vous pouvez définir un regex pour chaque type et vérifier ce que la chaîne contient à travers elle:

if (string.matches("[1-9][0-9]*")) 
    ... 

anycase en, puisqu'une String est juste un type de chaîne et rien d'autre, le RTTI ne vous aidera pas ici. La chaîne elle-même est orthogonale avec tous les autres types (int, float, any), même si elle représente la version textuelle d'un autre type.

Une solution peut être trouvée si vous pouvez modifier les types de chaîne source, dans ce cas, vous pouvez définir par exemple un

class IntString extends String { 
    IntString(int i) { 
    super(Integer.toString(i)); 
    } 
} 

vous pouvez alors vérifier si string instanceof IntString mais cela ne peut fonctionner que si les chaînes sont construites avec leur type spécifique, par exemple String s = new IntString(20).

+0

Devrait être 'Integer.parseInt() '(méthode statique). –

+0

fonction que je voulais était un qui non seulement limité à l'analyse de nombres entiers, mais de nombreux autres types. en d'autres termes, en tant que paramètre, je peux avoir Java.lang.String, Java.lang.Integer, Java.lang.Float, Java.lang.Boolean et ainsi de suite –

0

Votre solution la plus simple est probablement une instruction switch, avec une case pour chaque type que vous voulez prendre en charge.

public boolean canBeParsed(String type, String val) 
{ 
    switch(type) { 
     case "Java.lang.Integer" : return(tryParseInteger(val) != null); 
     case ... 
} 


public static Integer tryParseInteger(String text) { 
    try { 
    return new Integer(text); 
    } catch (NumberFormatException e) { 
    return null; 
    } 
} 

En C# ce serait plus facile, car il existe une méthode réelle TryParse() pour chaque type numérique, et il est nécessaire de ne pas attraper une exception pour le tester.

+1

Cela fonctionnera uniquement avec Java SE7 (activation d'une chaîne) . – helpermethod

+0

Utilisez un commutateur pour une énumération de types, qui fonctionnera dans JDK6. – TheWolf