Wie kann ich eine Class dynamisch laden?



  • Im will eine Classe ( MyClass ) dynamisch Laden, der Problem aber ist die Classe besitzt einen Constructor der ein Paar String Parameter erwartet ( MyClass(String s1, String s2) )
    Wie muss ich den Constructor aufrufen das alles klappt.

    Habe schon probiert ohne Parameter es funkt ...
    ... aber wie muss ich den Constructor mit dem Parameter aufrufen/ Initialisieren das es auch klappt.

    String className = "myProjekt.test.MyClass";
    
        try {
          Class c = Class.forName(className);
          Object o = c.newInstance();
        }
        catch(Exception e) {
          System.err.println(e);
        }
    

    mfg.

    christine





  • hier noch ein kleiner minimalsversuch, weil ich es mal ausprobieren wollte...

    import java.lang.reflect.*;
    
    class MyClass{
    	public String Str1;
    	public String Str2;
    	public MyClass (String str1, String str2){
    
    		Str1=str1;
    		Str2=str2;
    	}
    }
    
    public class Test{
    
    	public static void main( String args[]) {
    
    		String className = "MyClass";
    		Constructor MyClassConstructor;
    		Object[] paramValues;
    
        	try {
    
          		Class c = Class.forName(className);
          		Class[] paramTypes = new Class[]{java.lang.String.class,java.lang.String.class};
    
    			MyClassConstructor=c.getConstructor(paramTypes);
    			paramValues = new Object[] {"hallo", "world"};
          		MyClass o = (MyClass)MyClassConstructor.newInstance(paramValues);
          		System.out.println(o.Str1+o.Str2);
        	}catch(Exception e) {
    
          		System.err.println(e);
        	}
        }
    }
    

    die parameter müssen als array übergeben werden, der getConstruktoraufruf verlangt es so.



  • Wie kann ich eine Class dynamisch laden?

    So weit funkt auch alles DANKE!

    Ich habe dennoch noch ein Problem die Class Name bzw. Class Package wird aus einer Config Datei gelesen und als String ("myProjekt.test.MyClass";) gespeichert:

    String className = config.getProperty(“loadClass”, “myProjekt.test.Default”) ;
    

    Um jetzt aber eine Funktion der geladener Klasse aufzurufen brauche ich wieder die Class Name die aber zur Kompilierungszeit nicht Bekannt ist –

    **also die Frage lautet wie komme ich auf die Name der geladener Klasse (MyClass) wenn in der PropDatei nur eine Stringzeile steht:
    loadClass= myProjekt.test.MyClass
    **

    (  ( ????????)obj  ).setInhalt( “BlaBla” );
    

    mfg.
    christine



  • meinst du folgendes:

    du kannst überprüfen ob ein objekt eine instanz einer klasse oder eines interfaces ist mit dem schlüsselwort instanceof

    zB

    Object o = getAnyObject();
    if(o instanceof MyClass){
        MyClass m = (MyClass)o;
    }
    

    ich bin etwas verwirrt und mir nicht sicher ob es das ist was du willst



  • oder meinst du das

    Mit der Methode getClass(), die in der Klasse Object definiert ist, kann zu jedem Objekt das zugehörige Class-Objekt abgerufen werden.

    aber wo das ..hmm



  • Vielleicht kann man dir weiterhelfen, wenn man genauer weiss, warum du die Klasse überhaupt dynamisch laden willst.

    Üblicherweise wird das gemacht, um verschiedene Implementierungen auf einfache Art und Weise austauschen zu können.
    Das heisst auch, dass du genaue Vorstellungen von dem hast, was du von der Klasse willst. Das kannst du dann über ein Interface fetsthalten, in dem alle Methoden beschrieben sind, die die zu ladende Klasse implementieren muss.

    Dann brauchst du nur noch, wie auch schon oben gesagt, auf dieses Interface zu casten.

    Deine Klasse muss natürlich dieses Interface implementieren, damit es keinen Laufzeitfehler gibt.

    /Dirk



  • Class dynamisch laden habe es immer noch nicht gebacken!!!

    Ich glaube mein Problem lässt sich besser/ einfacher anhand Beispielen erklären ...
    Also es sind zwei Klassen A, B diese beiden sind gleich mit gleichen Parametrisierten Konstruktoren s. unten.

    package test;
    
    public class A {
      String s;
    
      public A(String s) {
        this.s = s;
      }
    
      void setValue(int i) {
        System.out.println("Class A" + s + i);
      }
    }
    

    die Class Namen bzw. Packagen werden leider erst zur Laufzeit anhand einer Config Datei bekannt gegeben.
    Die Test Classe sollte dann die A bzw. B Class dynamisch laden und deren Funktion setValue() aufrufen

    package unbennant;
    
    public class Test {
    
      // String clazzName = test.A;
      // or
      // String clazzName = test.B;
      String clazzName = config.getProperty(“ladeClass”);
      private Object clazzObject;
    
      public Test() {
        // Formale Parameter definieren
        Class[] clazzParam = new Class[1];
        clazzParam[0] = String.class
    
        // Class Laden
        try {
          Class clazz = Class.forName(clazzName);
          Constructor cons = clazz.getConstructor(clazzParam);
          // Aktuelle Argumente definieren
          Object[] arg = new Object[] { “Irgendwas” };
          // Classe instanzieren
          clazzObject = cons.newInstance(arg);
    
          // ( ( A )clazzObject ). setValue(100);
          // or
          // ( ( B )clazzObject ). setValue(500);
          ( ( ??????????? )clazzObject ).setValue(100);
        }
        catch(Exception e) {
          System.err.println(e);
        }
      }
    }
    

    Das Problem, das ich habe ist:
    ich weiss nicht wie ich auf den Namen der geladenen Classe komme, auf die ich das Object (clazzObject) carsten muss um die setValue() Funktion aufzurufen

    ich glaube es ist jetzt alles etwas verständlicher.
    Vielleicht kann jetzt jemand helfen??

    mfg.
    christine.



  • Schreibe ein Interface

    package test;
    
    public interface LoadableClass {
       void setValue(int i);
    }
    

    Deine Klassen A und B müssen nun dieses Interface implementieren. Danach kannst du den Wert wie folgt setzen:

    clazzObject = cons.newInstance(arg); 
    LoadableClass loadable = (LoadableClass) clazzObject;
    loadable.setvalue(100);
    

    /Dirk



  • ... jetzt habe ich endlich begriffen das Interface Prinzip, es funktioniert prima
    Ich Danke Euch.

    christine. 😃


Anmelden zum Antworten