2013-08-07 13 views
17

Va bene questa è una specie di domanda complicata e sono completamente perso.Java come verificare se un valore stringa è un tipo di data Classe <?>

Si supponga di avere una stringa e una classe generica. Come questo.

String string; 
Class<?> clazz; 

Come verificherebbe se la stringa rappresentasse un valore che la classe potrebbe uguagliare.

Per esempio consente di dire che:

String string = "true"; 
Class<?> clazz = Boolean.class; 

Come faccio a controllare e vedere che la stringa "vera" è infatti un valore booleano?

Ecco un altro esempio. Diciamo che:

String string = "true"; 
Class<?> clazz = Integer.class; 

Come verifico e vedo che la stringa "true" non è un intero?

+0

Vuoi eseguire il test solo per i tipi di wrapper? –

+0

Sono principalmente interessato ai primitivi tipi di wrapper, sì –

risposta

17

Dato che si desidera che questo solo per Tipi Wrapper, è possibile utilizzare un po 'di riflessione incidere qui (gestione per il codice irrilevante eccezione viene ignorata qui per brevità):

String string = "ABC"; 
Class<?> clazz = Integer.class; 

Method method = clazz.getDeclaredMethod("valueOf", String.class); 

if (method != null) { 
    try { 
     Object obj = method.invoke(null, string);  
     System.out.println("Success : " + obj); 

    } catch (InvocationTargetException ex) { 
     System.out.println("Failure : " + string + " is not of type " + 
              clazz.getName()); 
    } 
} 

che sto prendendo in considerazione la Infatti, ogni classe wrapper ha un metodo statico che accetta un parametro di tipo String e restituisce il valore di tale tipo wrapper. E genera un'eccezione, se il parametro non è convertibile nel rispettivo tipo di wrapper.

Quindi, nel caso di cui sopra, se viene lanciata un'eccezione, il valore string non è di tipo clazz.

P.S.: Si noti che per Boolean.class, qualsiasi stringa che non è "true" verrà considerata come false.

0

In javascript è possibile eval() la stringa. In Java non hai questi mezzi. Dovrai implementare la tua euristica per questo controllo.

L'unica cosa che si può fare, tuttavia, è cercare di analizzare la stringa con la classe data. Come:

Iteger.parseInt(stringValue); 

Se il parsing riesce, allora la stringa può essere utilizzato come un valore per quel tipo. Se fallisce, ottieni un'eccezione. Implementare questi controlli e quindi dedurre alcune conclusioni.

+0

Non posso semplicemente usare quel metodo perché non ho idea se la classe sarà un intero. È un tipo generico. –

+0

Non esiste una soluzione a linea singola per il tuo problema. Questo è il motivo per cui dico che devi impementare una serie di controlli e quindi dedurre una conclusione. – allprog

+0

Non mi aspetto una soluzione a linea singola. Penso solo che ci deve essere un modo migliore che controllare se uno qualsiasi dei tipi primitivi o le altre classi che aggiungo e quindi controllarlo contro ogni classe che aggiungo –

0

Non riesco a testare questa soluzione in questo momento, ma perché non qualcosa del genere? Se è possibile enumerare tutte le possibili classi da soli, è sufficiente creare alcune istruzioni switch sulla classe.

boolean isStringClass (Class clazz, String string) { 

    try { 
     if (Integer.class == clazz) { 
      Integer.valueOf(string); 
     } else if (Boolean.class = clazz) { 
      Boolean.valueOf(string); 
     } [...etc] 
    } catch (Exception e) { 
     return false; 
    } 

    return true; 
} 

Naturalmente è necessario conoscere tutte le possibili classi, e si avrà bisogno di sapere di un metodo che appartiene a quella classe che è in grado di analizzare una stringa e restituisce il suo tipo. Per i wrapper primitivi che sarebbero valueOf.

Se si prevede di convertire solo i wrapper, la soluzione di Rohit sarebbe una scelta migliore. Tuttavia, se non lo fai e non sei in grado di aggiungere un metodo valueOf a questa nuova classe, questa potrebbe essere la tua unica opzione.

1

Suppongo che stiate implementando una sorta di Specifica/Protocollo o simile.

  1. Guarda le specifiche.
  2. Definire una grammatica di input valido
  3. Analizzare tale grammatica.

Questo è simile a ciò che i linguaggi di programmazione stanno facendo con i letterali.

0

Vorrei prendere in considerazione l'utilizzo del meccanismo JavaBeans PropertyEditor per questo.

@Test 
public void testIsOfType() {   
    assertFalse(test("nope", Integer.class)); 
    assertFalse(test("nope", Boolean.class)); 

    assertTrue(test("1", Integer.class)); 
    assertTrue(test("true", Boolean.class)); 
} 

boolean test(String str, Class<?> clazz) { 
    PropertyEditor propertyEditor = PropertyEditorManager.findEditor(clazz); 
    if (propertyEditor != null) { 
     try {   
      propertyEditor.setAsText(str); 
      return true; 
     } catch (Exception ex) {} 
    } 
    return false; 
} 

Questo evita la necessità di una riflessione esplicita, e se mai deciso che si serve per testare categorie diverse dalla wrapper primitivi si potrebbe registrare un nuovo editor con PropertyEditorManager.registerEditor().

Purtroppo questo ha ancora il problema che la soluzione di Rohit ha in quello test("1", Number.class) avrà esito negativo.

Problemi correlati