-1

I try to instantiate class from a class name but I fail, my code is in Processing / Java Library. My first state it's find a good class, I manage that but after I find no possibility to instantiate from the class name. I need to do that because all my methods is used everywhere in my code and I need to find information from those in a single place. I hope my purpose is clear...

I make this code but it's a fail, when I pass the name by method forName() the console return Unhandled exception type ClassNotFoundException

import java.util.Iterator;
import java.lang.reflect.*; 

Target class_a = new Target() ;
Target class_b = new Target() ;
Truc class_c = new Truc() ;


void setup() {
  class_a.is(true);
  class_b.is(false);

  Field [] f = this.getClass().getDeclaredFields();
  println("field num:",f.length);
  for(int i = 0 ; i < f.length ; i++) {
    if(f[i].getType().getName().contains("Target")) {
     println("BRAVO it's a good classes");
     println("class:",f[i].getClass());
     println("name:",f[i].getName());

     // I imagine pass the name here to instantiate the class but that's don't work
     Class<?> classType = Class.forName(f[i].getName());

     // here I try to call method of the selected class
     println(classType.get_is());
   }
 }
}



class Target{
  boolean is;
  Target() {}

  void is(boolean is) {
   this.is = is;
  }

  boolean get_is() {
    return is;
  }
}


class Truc{
  Truc() {}
}
Knupel
  • 323
  • 2
  • 14
  • Why do you want to do this? Your intent isn't clear from your question. – Makoto Jun 12 '18 at 22:44
  • Even if this was all working, `get_is` is a non-static method, and you're trying to call it on a class, without an object. What are you expecting `this` to be when you call it? – Silvio Mayolo Jun 12 '18 at 22:49
  • Possible duplicate of [What is the difference between "Class.forName()" and "Class.forName().newInstance()"?](https://stackoverflow.com/questions/2092659/what-is-the-difference-between-class-forname-and-class-forname-newinstanc) – PM 77-1 Jun 12 '18 at 22:52
  • http://idownvotedbecau.se/noresearch/ e.g. web search for how to call method using reflection, which requires calling `invoke()` on a `Method` object. – Andreas Jun 12 '18 at 22:56
  • @Makoto I want do that to use a specific method of all class used in my class to know is it used or not. In my case it's for GUI to know if any Dropdown class is open or not ; and it's complicate to know in advence the quantity of class Dropdown is active. I hope it's clearest ? – Knupel Jun 13 '18 at 07:20
  • @Silvio Mayolo `this` is the PApplet processing, I use it to find which Class existe and which one is instantiate. If one is instantiate in Object I need to catch information from this Class object from method `get_is()` for example. It's the reason why I use method `Field` to know the Class Name and the name of the instantiate class. I hope it's clearer. – Knupel Jun 13 '18 at 08:54

1 Answers1

2
  1. java.lang.Class object (you get it by calling Class.forName) does not have a method get_is(). You have to use reflection to call a method.

but...

  1. As long as your get_is() is non-static you cannot call it from class even through reflection. You have to have instantiate your class and then you will be able to call needed method through reflection. You also can cast that newInstance to the desired class and then call method directly. Of course, for that you have to know your class ahead before compile.

UPD:

Your problem is in here `Class classType = Class.forName(f[i].getName());'

Field name is not its class!.

you have to use this: Class<?> classType = Class.forName(f[i].getType().getName());

in addition if you'd like to use reflection you have to declare get_is() method as public in your Target class

Please look at working code below for both options cast and reflection. (get_is method is public in Target class)

      for(int i = 0 ; i < f.length ; i++) {

     // class is field type not name!
     Class<?> classType = Class.forName(f[i].getType().getName());
     // check is it Target class type
     if (f[i].getType().equals(Target.class)) {
         System.out.println("it is Target class field!");
         // option 1: cast
         Target targetFieldValue = (Target)f[i].get(this);
         System.out.println("opt1-cast -> field:" + f[i].getName() + " result: " + targetFieldValue.get_is());   
         //option 2: reflection
         Object rawValue = f[i].get(this);
         Method getIsMtd = f[i].getType().getMethod("get_is", (Class<?>[])null);
         if (null != getIsMtd)
         {
              // invoke it
             System.out.println("opt2 -> reflection result: " + getIsMtd.invoke(rawValue, (Object[])null));
         }   
     } 
   }
Vadim
  • 4,027
  • 2
  • 10
  • 26
  • Thx for the advice, I try with to instatiate, but's that's don't work ; I think the main problem in my case, it's the the name passing to `forName()` when I try to pass the instantiate class name who match with my purpose like `f[i].getName()` or directly `class_a` the console return `Unhandled exception type ClassNotFoundException` thus I cannot try to instantiate with `newInstance()` – Knupel Jun 13 '18 at 07:25
  • I looked closer to your code, please look at updated full answer. – Vadim Jun 13 '18 at 14:41