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]));
}
}
}
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);
}
}
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
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;
File > [Ljava.io.File;
Commenti
Posta un commento