未处理的异常类型:processing.org 中的 InstantiationException
Unhandled exception type: InstantiationException in processing.org
我正在尝试从处理中做一个简单的 Class.newInstance(),但我失败了:(
EDIT: as below instructed, the reason it didn't work was that Processing wraps all
code into a class making all declared classes internal classes. The java
language specification states that newInstance() for internal classes
should be passed a reference to the container class, so after changing
the call to newInstance to newInstance(this); it worked as intended.
下面的代码示例抛出 InstantiationException。
文档说有一个 public 构造函数,一切都会好起来的,但是唉。
运行 处理 2.2.1
Codeflow:它填满了实现接口的所有 类 的列表。然后我们通过 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() {
}
}
首先,您的代码无法编译,因为您需要将 newInstance()
包装在 try/catch 块中。 newInstance()
函数可以抛出 InstantiationException
或 IllegalAccessException
,因此您必须捕获这些异常。这就是你的错误告诉你的。
如果你post一个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() {
}
}
但即使你修复了这个问题,你也会得到一个运行时异常,因为在幕后,你在草图中声明的classes是内部classes 你的草图 class。您不能像您尝试的那样在内部 classes 上使用反射。
因此,您要么需要更改声明这些 class 的方式,要么需要更改进行反射的方式。
为了确保 Processing 不会将那些 classes 变成你草图的内部 classes,你必须在它们自己的 .[=48= 中定义它们] 个选项卡。使用 class 的名称后跟 .java,因此 Processing 知道它是 Java class,而不是 "Processing class",它被转换成内部 class。您的设置将如下所示:
使用这种方法,您必须将草图实例传递给 java classes 才能访问任何 Processing 方法。相反,您可能只想改变您进行反思的方式。由于 classes 是 inner classes 你的草图 class,你必须通过草图 class 才能到达他们:
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() {
}
}
或者,您可以将 Wtf
class 声明为静态的:
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() {
}
}
当然,您将无法访问草图的非静态成员class,因此您采用哪种方法实际上取决于您需要做什么。
我正在尝试从处理中做一个简单的 Class.newInstance(),但我失败了:(
EDIT: as below instructed, the reason it didn't work was that Processing wraps all code into a class making all declared classes internal classes. The java language specification states that newInstance() for internal classes should be passed a reference to the container class, so after changing the call to newInstance to newInstance(this); it worked as intended.
下面的代码示例抛出 InstantiationException。
文档说有一个 public 构造函数,一切都会好起来的,但是唉。
运行 处理 2.2.1
Codeflow:它填满了实现接口的所有 类 的列表。然后我们通过 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() {
}
}
首先,您的代码无法编译,因为您需要将 newInstance()
包装在 try/catch 块中。 newInstance()
函数可以抛出 InstantiationException
或 IllegalAccessException
,因此您必须捕获这些异常。这就是你的错误告诉你的。
如果你post一个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() {
}
}
但即使你修复了这个问题,你也会得到一个运行时异常,因为在幕后,你在草图中声明的classes是内部classes 你的草图 class。您不能像您尝试的那样在内部 classes 上使用反射。
因此,您要么需要更改声明这些 class 的方式,要么需要更改进行反射的方式。
为了确保 Processing 不会将那些 classes 变成你草图的内部 classes,你必须在它们自己的 .[=48= 中定义它们] 个选项卡。使用 class 的名称后跟 .java,因此 Processing 知道它是 Java class,而不是 "Processing class",它被转换成内部 class。您的设置将如下所示:
使用这种方法,您必须将草图实例传递给 java classes 才能访问任何 Processing 方法。相反,您可能只想改变您进行反思的方式。由于 classes 是 inner classes 你的草图 class,你必须通过草图 class 才能到达他们:
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() {
}
}
或者,您可以将 Wtf
class 声明为静态的:
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() {
}
}
当然,您将无法访问草图的非静态成员class,因此您采用哪种方法实际上取决于您需要做什么。