Instantiate one class inside another using a third

(Disclaimer: I’m not familiar with this but researched out of curiosity. What I explain is just gathered from online resources, mostly stackoverflow…)

so the first problem is that

Class<?> c = Class.forName( type.getName() );

is just a Class and not an instance. So usually you have to do this to instantiate:

c.newInstance();

but you will get InstantiationException error, which seems to happen when you don’t have a default constructor. But B does, and here comes the second problem - Processing wraps the code in PApplet, so you need to use .java extension so that the interpreter won’t wrap your code in there.

I ended up with two files, first the main pde file

void setup(){
  A a = new A();
  a.hello();
}

and abc.java

import java.lang.reflect.*;

class A {
  String s;
  B b;
  
  A(){
    C c = new C(this);
  }
  
  void hello(){
    //println("hello from A!");
    //println("s:",s);
    b.hello();
  }
}

class B {
  B(){}
  
  void hello(){
    System.out.println("hello from B!");
  }
}

class C {
  
  <T> C ( T obj ){
    
    Class someClass = obj.getClass();
    //println("setting fields for instance of class:",someClass.getSimpleName());
    
    Field[] allFields = someClass.getDeclaredFields();
    
    for (Field field : allFields){
      Class type = field.getType();
      //print("field",field.getName(),"is type:",type);
      
      switch(type.getSimpleName()){
        
        case "String"    : //println(" is a String");
                           try {
                             field.set(obj, "A happy little string");
                           } catch (Exception e) { }
                           break;
                           
        default           : //println(" is custom class:",type.getSimpleName());
                            // somehow magically instantiate A.b = new B();
                            try {
                              Class<?> c = Class.forName( type.getName() );
                              //println("c:",c.getClass());
                              field.set(obj, c.newInstance());
                            } catch (ClassNotFoundException e){ //println(e);
                            } catch (Exception e) { //println(e);
                          }
                            break;
      }
    }
  }
}

note that in .java file you cannot use Processing specific functions like println!

2 Likes