Java Reflection: come richiamare array di classi

DOMANDA:

Ho seguito le istruzioni dell'altro post sulla Java Reflection e stavo modificando la classe RinominaFile in modo che avesse un costruttore aggiuntivo che prende in input come parametri due array di stringhe come nell'esempio qui di seguito:


package reflection;

import java.io.File;

public class RinominaFile {

   private String[] pathFrom;
   private String[] newName;

   public RinominaFile(String pathFrom, String newName) {
      this.pathFrom[0] = pathFrom;
      this.newName[0] = newName;
   }

   public RinominaFile(String[] pathFrom, String[] newName){
      this.pathFrom = pathFrom;
      this.newName = newName;
   }

   public void rinomina() {
      for(int i=0; i<pathFrom.length; i++){
         File fromFile = new File(pathFrom[i]);
         fromFile.renameTo(new File(newName[i]));
      }
   }
}


Così ho modificato la classe di Test:


package reflection;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class TestReflection {

   public static void main(String[] args)
           throws ClassNotFoundException, SecurityException,
           NoSuchMethodException, IllegalArgumentException,
           InstantiationException, IllegalAccessException,
           InvocationTargetException {

      Class classeInvocata = Class.forName("reflection.RinominaFile");

      Class listaParametri[] = { Class.forName("java.lang.String;"), Class.forName("java.lang.String;") };
   
      // lista dei file da rinominare
      String[] listaFile = { "C:\\ciao.txt", "C:\\ciao1.txt" };
      // lista dei file rinominati
      String[] listaFileRinominati = { "C:\\ciaoRIN.txt", "C:\\ciao1RIN.txt" };

      Object[] listaValoriParametri = { listaFile, listaFileRinominati };

      Constructor costruttore = classeInvocata.getConstructor(listaParametri);
   
      // instanzio la classe invocando il costruttore
      RinominaFile rf = (RinominaFile) costruttore.newInstance(listaValoriParametri);
 
      // eseguiamo il metodo
      classeInvocata.getMethod("rinomina").invoke(rf);
   }
}

Come si nota nel Class.forName evidenziato in rosso, ho provato a passargli "java.lang.String", ma ricevo un'eccezione "java.lang.ClassNotFoundException: java/lang/String;". 


Come posso richiamare gli array di classi in Java Reflection?


RISPOSTA:

Gli array di classi hanno una sintassi leggermente differente, visualizzabile anche ispezionando con la Java Reflection la classe di interesse. Se ispezionassimo il costruttore, ci accorgeremmo infatti che i due parametri che si aspetta non sono dei semplici "java.lang.String" ma dei "[Ljava.lang.String;".

Basta quindi cambiare in TestReflection il nome della classe richiamata in questo modo: Class.forName("[Ljava.lang.String;"). Tutto funzionerà a dovere.


Elenco anche altri tipi di array di dati primitivi:

array di short > [S
array di byte > [B
array di int > [I
array di long > [J
array di char > [C
array di float > [F
array di double > [D
array di boolean > [Z

Per gli oggetti invece, esattamente come nelle String, si usa [L seguito dal nome della classe. Qualche esempio:

Object[] > [Ljava.lang.Object;
File > [Ljava.io.File;


Commenti

Post popolari in questo blog

Arrotondamento e troncamento in Java

Eclipse: Shortcuts (scorciatoie) da tastiera

Strutture dati: List, Set, Map

Creare un eseguibile Java