尝试将变量添加到新对象时发生InvocationTargetException

时间:2014-01-24 15:10:08

标签: java processing osc

我正在尝试将两个变量从一个草图发送到另一个草图,使用oscP5库进行处理。 我发送的消息是这样创建的:

 OscMessage myMessage = new OscMessage("/test");
 myMessage.add(title);
 myMessage.add("Zeit");
 oscP5.send(myMessage, remoteLocation);

在第二个草图中,我收到了类似的数据:

 void oscEvent(OscMessage theOscMessage) {
   if(theOscMessage.checkAddrPattern("/test")) {
     String title = theOscMessage.get(0).stringValue();
     String layoutType = theOscMessage.get(1).stringValue();

     addToQueue(title, layoutType);
   }
 }

这里是我简化的addToQueue函数:

 void addToQueue(String title, String layoutType) {
   if(!existsInQueues(title)) {
     upcomingHeadlines.add(new Headline(title, printAxis, scrollSpeed, layoutType));
   } 
 }

每次我开始草图时,都会收到错误:

  

ERROR @ OscP5错误。将OscMessage转发到程序中的方法时发生错误。请检查您的代码,以了解解析传入的OscMessages的方法中可能出现的任何错误,例如检查铸造错误,可能的无效指针,数组溢出....   负责方法:oscEvent java.lang.reflect.InvocationTargetException

我已经能够将问题追踪到layoutType - 变量。如果我改变

  String layoutType = theOscMessage.get(1).stringValue();

  String layoutType = "Zeit";

没有错误发生。 这很令人困惑,因为两个版本都应该有相同的结果。 错误消息对我没有任何帮助。


修改

我比较了两个可能的变量:

String layoutType = theOscMessage.get(1).stringValue();
String layoutTypeB = "Zeit";
if(layoutType.equals(layoutTypeB)) println("Same String!");

由于打印到控制台,两者都必须相同......我真的不知道在哪里搜索错误。


编辑2

我已将{2}中的第二个草图包裹起来:

try {...} catch(Exception ex) {ex.printStackTrace();}

结果给出了这个错误:

void oscEvent(OscMessage theOscMessage) {
  try {  
    if(theOscMessage.checkAddrPattern("/test")) {
      if(debug && debugFeed) println("Received message from other sketch.");

      String title = theOscMessage.get(0).stringValue();
      String layoutTypeO = (String)theOscMessage.get(1).stringValue();
      String layoutType = "Zeit";
      if(debug && debugTemp) {
        if(layoutType.equals(layoutTypeO)) println("IS DOCH GLEICH!");
      }
      if(debug && debugFeed) println("Parsed Information.");
      if(debug && debugFeed) println("-----");
      addToQueue(title, layoutTypeO);
    }
  } catch(Exception ex) {ex.printStackTrace();}
}

编辑4

java.lang.IndexOutOfBoundsException: Index: 0, Size: 0 at java.util.ArrayList.rangeCheck(ArrayList.java:635) at java.util.ArrayList.get(ArrayList.java:411) at printer$Headline.useLayout(printer.java:260) at printer$Headline.<init>(printer.java:188) at printer.addToQueue(printer.java:407) at printer.oscEvent(printer.java:395) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at oscP5.OscP5.invoke(Unknown Source) at oscP5.OscP5.callMethod(Unknown Source) at oscP5.OscP5.process(Unknown Source) at oscP5.OscNetManager.process(Unknown Source) at netP5.AbstractUdpServer.run(Unknown Source) at java.lang.Thread.run(Thread.java:744) 的构造函数 - 类:

Headline

您可能也想知道class Headline { //Define Variables Layout layout; String title, lastHeadline; float yPos, speed; float transparency = 255; boolean fullyPrinted = false; int boundingBoxHeight; // Initialize Class Function Headline(String t, float y, float s, String lay) { title = t; yPos = y; speed = s; layout = useLayout(lay); boundingBoxHeight = calculateTextHeight(title); } ,所以这里是:

useLayout()

1 个答案:

答案 0 :(得分:2)

您的代码存在两个问题,而且这两个问题都在您的useLayout方法中。

第一个问题是你没有在这一行上正确地比较Strings

    if(currentLayout.layoutType == name) {

nameString,我认为currentLayout.layoutType也是String。两个相等但不相同的==layoutVariants下不会相等。因此,在for循环结束时,您的 if(currentLayout.layoutType.equals(name)) { 列表很可能为空。

这一行应为:

layoutVariants

See also this question

第二个问题是您没有正确处理 if(layoutVariants != null) { 列表为空的情况。问题出在这一行:

layoutVariants

else永远不会为null,因此if语句的layoutVariants.size()分支将永远不会执行。由于rand将为零,IndexOutOfBoundsException将始终为零。尝试在空ArrayList中获取索引0处的元素将精确地为您提供所见的else

我想如果无法识别给定的布局名称,换句话说,如果layoutVariants列表为空,而不是 if(!layoutVariants.isEmpty()) { 块,则需要执行!块空值。在这种情况下,请将此行更改为

layoutVariants

请注意if之前的layoutVariants(非操作符)。如果null元素为空,您希望null语句下的代码运行。

编辑以回应您的评论:null ArrayList与空的ArrayList非常不同。 String是一个特殊值,意味着变量没有给定类型的对象。

让我们尝试一个现实世界的比喻:一个购物袋。如果你有一个空袋子,或者根本没有袋子,那么你无论如何都没有购物。但是,您可以将物品放入空袋中,并计算它包含的物品数量。如果你没有一个包,那么将一个物品放入其中是没有意义的,因为没有包放入物品。 isEmpty()表示您没有行李的情况。

同样,isEmpty是一个字符集合,即使字符集不包含任何字符,也可以存在。

ArrayList arr;可用于any collection,如果您使用的是Java 6或更高版本,则Strings as well。在我的头脑中,我无法命名任何其他具有ArrayList方法的类。您只需查阅这些类的文档即可查找。

我没有使用Processing,但我知道Processing是基于Java构建的,所以我希望任何标准的Java方法都可以工作。另外,我不担心'清除'变量:JVM通常非常善于在您之后清理。在这方面,我的代码当然没有任何问题。

编辑2 以回复您的进一步评论:arr声明了null类型的变量。但是,变量ArrayList arr; System.out.println(arr); // compiler error: arr might not have been initialised. 未初始化:它没有值(甚至不是null)并且在您尝试读取此变量的值之前是错误的为其分配了一个值:

ArrayList arr = null;
System.out.println(arr);     // prints 'null'.

分配if然后编译代码:

int y = getMeSomeInteger();   // assume this function exists
if (y == 4) {
    int x = 2;
} else {
    int x = 5;
}
System.out.println(x);        // compiler error: cannot find symbol x

通常不需要声明变量而不给它命名,但是一个常见的情况是你想要在x语句的两边为同一个变量分配不同的值。以下代码无法编译:

{

它不编译的原因是每个变量}仅在包含它的大括号xx中可用。在底部,变量int y = getMeSomeInteger(); // assume this function exists int x = 0; if (y == 4) { x = 2; } else { x = 5; } System.out.println(x); 都不可用,因此您得到编译器错误。

我们需要进一步宣布0。我们可以写下以下内容;

x

此代码编译并运行,但最初分配给int y = getMeSomeInteger(); // assume this function exists int x; if (y == 4) { x = 2; } else { x = 5; } System.out.println(x); 的值{{1}}从未使用过。这样做没有太多意义,我们可以通过声明变量但不立即给它一个值来摆脱这个未使用的值。

{{1}}