Visualizzazione dei risultati da 1 a 10 su 10
  1. #1
    Utente di HTML.it L'avatar di bako
    Registrato dal
    Feb 2004
    Messaggi
    1,797

    Da stringa ricavare campo corrispondente

    Salve, domanda forse assurda ma magari esiste qualcosa.
    ho una funzione che prende in input il nome di un campo, questo campo ha il getter e setter, come tutti gli altri campi della classe.

    ora, i getter e setter sono costruiti così:

    setNome(param)
    getNome(param)t

    ora, io riveco in input Nome è possibile richiamare il metodo getNome in automatico?
    cioè senza fare degli if?
    in pratica, esiste un comando che permetta di chiamare un metodo da stringa? cioè dalla stringa

    getNome()

    si possa fare una specie di eval che valuta la stringa e richiama il metodo corrispondente della classe?

  2. #2
    Si può fare attraverso la Reflection (java.lang.reflect.*), facendo qualcosa tipo:

    Codice PHP:
    package reflecttest;
    import java.lang.reflect.Method;
    public class 
    Main {
        public static 
    void main(String[] argsthrows Exception {
            
    String nomeParametro "Nome";
            Class 
    classe = Class.forName("reflecttest.MyClass");
           
    Method[] methods classe.getDeclaredMethods();
           
    Method targetMethod null;
           for (
    int i 0methods.lengthi++) {
                
    Method method methods[i];
                
    String name method.getName();
                if(
    name.equals("get"+nomeParametro))
                    
    targetMethod method;
            }
           if(
    targetMethod != null)
               
    //il primo parametro passato a invoke() è un'istanza di classe, 
               //se targetMethod 'necessita' di parametri essi vanno 
               //passati a invoke(), es.: targetMethod.invoke(istanza,parametro1,...)
               
    System.out.println(targetMethod.invoke(classe.newInstance()));
           else
               
    System.out.println("Metodo non trovato");
        }
    }

    class 
    MyClass{
        private 
    String nome "myname";
        public 
    String getNome() {
            return 
    nome;
        }
        public 
    void setNome(String nome) {
            
    this.nome nome;
        }

    La java reflection permette di conoscere e invocare a run-time tutti i metodi di una classe (anche costruttori, setter e tutti gli altri) ed è particolarmente usata nello sviluppo degli IDE o della programmazione JEE.
    Ciao.

  3. #3
    Utente di HTML.it L'avatar di bako
    Registrato dal
    Feb 2004
    Messaggi
    1,797
    grazie. ora guardo.

  4. #4
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284

    Re: Da stringa ricavare campo corrispondente

    Originariamente inviato da bako
    ora, io riveco in input Nome è possibile richiamare il metodo getNome in automatico?
    Potresti anche usare la libreria BeanUtils di Apache Commons, che ti semplifica di molto l'accesso ad un "bean".
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  5. #5
    Utente di HTML.it L'avatar di bako
    Registrato dal
    Feb 2004
    Messaggi
    1,797
    probelma.
    se faccio:
    MiaClasse.getClass().getDeclaredMethod("nome");

    ho visto che ogni tanto mi dice che il metodo non esiste.

    in praticolare i metodi tipo getNome li prende, mentre quelli setNome no.
    Forse perhcè i metodi setter hanno un parametro? possibile?
    altra cosa: si può ricavare i tipi dei parametri del metodo?
    es:
    se un metodo è public void metodo(int p1, String p2) posso ricavare int e String (cioè il tipo di p1 e p2?)
    grazie

  6. #6
    MiaClasse.getClass().getDeclaredMethod("nome"); ho visto che ogni tanto mi dice che il metodo non esiste.
    Semplicemente il metodo "nome()" non esiste, semmai esistono "setNome()" e "getNome()". Nel listato che ho postato, quando viene fatta la ricerca di un metodo, al nome del metodo che cerchi viene sempre preposta la stringa "get" (perchè nel tuo primo post hai detto che ricevi in input la stringa "Nome" e ne cerchi il getter):

    Codice PHP:
    ...
    String nomeParametro "Nome"
    ...
    if(
    name.equals("get"+nomeParametro))//viene verificata l'uguaglianza con "getNome"
    .. 
    Per quanto riguarda il numero e i tipi di parametro accettati da un metodo:
    Codice PHP:
    Class[] paramTypes targetMethod.getParameterTypes();
    int numeroDiParametri paramTypes.length
    Se ti interessa anche il tipo ritornato:
    Codice PHP:
    Class returnType targetMethod.getReturnType(); 
    Se due metodi hanno lo stesso nome puoi prelevare quello che ti interessa considerando il numero di parametri e, se non è sufficiente, il tipo. Se ci sono dubbi puoi anche consultare il link che ho indicato precedentemente in cui trovi un esempio di applicazione abbastanza completa che evidenzia le principali potenzialità della Reflection.
    A seconda delle tue esigenze effettive non trascurare il suggerimento di andbin.

  7. #7
    Utente di HTML.it L'avatar di bako
    Registrato dal
    Feb 2004
    Messaggi
    1,797
    si metto bene il set e get davanti.
    ma per quanto riguarda il set non funziona.
    domani ti posto il codice.
    grazie intanto

  8. #8
    Utente di HTML.it L'avatar di bako
    Registrato dal
    Feb 2004
    Messaggi
    1,797
    come dicevo:
    codice del bean, semplice
    codice:
    public class Bean implements Serializable{
        private String field1 = "";
    
    
        public Bean() {
        }
    
        public String getField1() {
            return field1;
        }
    
        public void setField1(String field1) {
            this.field1 = field1;
        }
    }
    da un'altra classe richiamo:
    codice:
    Bean b = new Bean();
    String name = "field1";
    String realName = "set" + name.substring(0, 1).toUpperCase() + name.substring(1);
    Method method = b.getClass().getDeclaredMethod(realName);
    method.invoke(b, "ciao");
    NB: realname diventa: setField1 (quindi è giusto)

    risultato:
    codice:
    Exception in thread "main" java.lang.NoSuchMethodException: main.Bean.setField1()
            at java.lang.Class.getDeclaredMethod(Class.java:1937)
            at main.NewClass.exec(NewClass.java:49)
            at main.NewClass.main(NewClass.java:24)
    Java Result: 1
    se cambio "set" con "get" il metodo viene trovato e tutto funziona.
    se scorro l'elenco dei metodi, l'output è questo:

    codice:
    getField1
    setField1

  9. #9
    Utente di HTML.it L'avatar di bako
    Registrato dal
    Feb 2004
    Messaggi
    1,797
    trovato l'inghippo. il getDeclaredMethod(realName) vuole anche il tipo del parametro che deve essere passato

  10. #10
    Dalla documentazione risulta che, per identificare univocamente un metodo, oltre al nome deve essere indicato il tipo di parametri (giustamente), se presenti:
    Codice PHP:
    Class[] parameterTypes = ...;
    classe.getDeclaredMethod("setNome",parameterTypes); 
    se non ci sono parametri non passi niente oltre al nome, ma non è il caso di setNome().
    Nella soluzione che ho postato io, puramente illustrativa ma comunque funzionante con qualche leggera modifica nel caso dei bean che usualmente hanno un solo metodo set per ogni campo, si scorrono tutti i metodi e viene selezionato quello che serve, per assegnazione in base al solo nome e non usando il metodo getDeclaredMethod con nome e parametri:

    Codice PHP:
    Method targetMethod null;        
    for (
    int i 0methods.lengthi++) {             
       
    Method method methods[i];             
       
    String name method.getName();             
       if(
    name.equals("get"+nomeParametro))                 
          
    targetMethod method;         
    ...} 
    quindi, in questo caso, basta che corrisponde il nome.
    Io ho postato un esempio di utilizzo della reflection, poi ovviamente va adattato leggendo anche la documentazione.
    La leggera modifica che dovresti apportare per far funzionare il codice postato anche al caso dei setter è verificare nella if il nome completo del metodo senza preporre "get":

    Codice PHP:
    ... 
    String nomeParametro "setNome"
    ... 
    if(
    name.equals(nomeParametro))//viene verificata l'uguaglianza con "setNome" 
    ... 
    Inoltre per invocare correttamente il metodo bisogna passare a invoke anche i parametri corretti.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.