未处理的异常类型:processing.org 中的 InstantiationException

Thi*_*sen 5 java processing

我正在尝试在处理中执行一个简单的 Class.newInstance() ,但我失败了:(

编辑:如下所示,它不起作用的原因是处理将所有代码包装到一个类中,使所有声明的类成为内部类。java语言规范规定内部类的newInstance()应该传递容器类的引用,因此将newInstance的调用改为newInstance(this); 它按预期工作。

下面的代码示例抛出了 InstantiationException。

文档说有一个公共构造函数,一切都会好起来的,但可惜。

运行处理2.2.1

代码流:它填充实现接口的所有类的列表。然后我们通过 state.runnableTypes 并尝试(但失败)实例化该类型的新实例。

请帮忙?

(对笨重的状态变量表示歉意,这与更笨重的 ryo 单元测试系统有关;))

    State state;
/* It nicely finds the Wtf class and inserts that into its classes array, 
 * but when i try to instantiate a new one, whatever I try, it throws :(
 */
void setup() {
  size(1024, 768, P3D);
  noLoop(); 
//get all the classes
  state = new State();
  Class[] types = this.getClass().getDeclaredClasses();
  state.allTypes = types;

  //enumerate castable types
  for (int i = 0, l = types.length; i<l; i++) { 
    Class c = types[i];
    if ( !c.isInterface() && IMenuRunnable.class.isAssignableFrom(c) ) { 
      println("adding "+c.toString());
      state.runnableTypes.put(c.getSimpleName(), c);
    }
  }

  //loop through the list and create some instances //FIXME: Exception handling ;p
  for ( String s : state.runnableTypes.keySet () ) { 
    Class c = state.runnableTypes.get(s);
    IMenuRunnable u = (IMenuRunnable) c.newInstance(); // ERR: calling Class.newInstance() here throws an error??
    java.lang.reflect.Constructor[] ctors = c.getConstructors();
    for ( java.lang.reflect.Constructor ctor : ctors ) { 
      ctor.setAccessible(true);
      Object o = ctor.newInstance(); // ERR: going via constructor array, same error :(
    }
  }
}




void draw() { 
  background(0);
}




class State {
  Class[] allTypes;
  HashMap<String, Class> runnableTypes = new HashMap<String, Class>();
}



interface IMenuRunnable {
}



public class Wtf implements IMenuRunnable { 
  public Wtf() {
  }
}
Run Code Online (Sandbox Code Playgroud)

Kev*_*man 3

首先,您的代码无法编译,因为您需要包装newInstance()在 try/catch 块中。该newInstance()函数可以抛出 anInstantiationException或 an IllegalAccessException,因此您必须捕获这些异常。这就是你的错误告诉你的。

如果您发布MCVE ,您将会有更好的运气,例如:

void setup() {
  try {
    Class<Wtf> c = Wtf.class;
    IMenuRunnable u = (IMenuRunnable) c.newInstance();
    println(u.toString());
  }
  catch(Exception e) {
    e.printStackTrace();
  }
}

interface IMenuRunnable {}

public class Wtf implements IMenuRunnable{ 
  public Wtf() {
  }
}
Run Code Online (Sandbox Code Playgroud)

但即使修复了这个问题,您也会遇到运行时异常,因为在幕后,您在草图中声明的类是草图类的内部类。您不能按照您尝试的方式使用内部类的反射。

因此,您要么需要更改声明这些类的方式,要么需要更改进行反射的方式。

为了确保处理不会将这些类转换为草图的内部类,您必须在它们自己的.java选项卡中定义它们。使用类名后跟.java,这样Processing 就知道它是一个Java 类,而不是“Processing 类”,它会转换为内部类。您的设置如下所示:

偏微分方程的屏幕截图

使用这种方法,您必须将草图的实例传递给 java 类才能访问任何处理方法。相反,您可能只想改变反思的方式。由于这些类是sketch 类的内部类,因此您必须通过 sketch 类才能访问它们:

void setup() {
  try {

    Class<?> sketchClass = Class.forName("sketch_150702a");
    Class<?> innerClass = Class.forName("sketch_150702a$Wtf");

    java.lang.reflect.Constructor constructor = innerClass.getDeclaredConstructor(sketchClass);

    IMenuRunnable u = (IMenuRunnable)constructor.newInstance(this);
    println(u.toString());
  }
  catch(Exception e) {
    e.printStackTrace();
  }
}

interface IMenuRunnable {
}

public class Wtf implements IMenuRunnable { 
  public Wtf() {
  }
}
Run Code Online (Sandbox Code Playgroud)

或者,您可以将您的Wtf类声明为静态:

void setup() {
  try {
    Class<Wtf> c = Wtf.class;
    IMenuRunnable u = (IMenuRunnable) c.newInstance();
    println(u.toString());
  }
  catch(Exception e) {
    e.printStackTrace();
  }
}

interface IMenuRunnable {}

static public class Wtf implements IMenuRunnable{ 
  public Wtf() {
  }
}
Run Code Online (Sandbox Code Playgroud)

当然,那么您将无法访问草图类的非静态成员,因此您采用哪种方法实际上取决于您需要做什么。