首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当尝试向新对象添加变量时,InvocationTargetException

当尝试向新对象添加变量时,InvocationTargetException
EN

Stack Overflow用户
提问于 2014-01-24 15:10:08
回答 1查看 3.7K关注 0票数 0

我试图将两个变量从一个草图发送到另一个草图,使用oscP5库进行处理。我发送的信息如下所示:

代码语言:javascript
复制
 OscMessage myMessage = new OscMessage("/test");
 myMessage.add(title);
 myMessage.add("Zeit");
 oscP5.send(myMessage, remoteLocation);

在第二张草图中,我收到了这样的数据:

代码语言:javascript
复制
 void oscEvent(OscMessage theOscMessage) {
   if(theOscMessage.checkAddrPattern("/test")) {
     String title = theOscMessage.get(0).stringValue();
     String layoutType = theOscMessage.get(1).stringValue();

     addToQueue(title, layoutType);
   }
 }

在这里,我的简化addToQueue函数:

代码语言:javascript
复制
 void addToQueue(String title, String layoutType) {
   if(!existsInQueues(title)) {
     upcomingHeadlines.add(new Headline(title, printAxis, scrollSpeed, layoutType));
   } 
 }

每次我开始画草图时,我都会发现错误:

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

我一直能够追踪到layoutType-Variable的问题。如果我改变了

代码语言:javascript
复制
  String layoutType = theOscMessage.get(1).stringValue();

代码语言:javascript
复制
  String layoutType = "Zeit";

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

编辑

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

代码语言:javascript
复制
String layoutType = theOscMessage.get(1).stringValue();
String layoutTypeB = "Zeit";
if(layoutType.equals(layoutTypeB)) println("Same String!");

由于被打印到控制台,所以两者必须是同一个…。我真的不知道到哪里去找错误了。

编辑2

我用try {...} catch(Exception ex) {ex.printStackTrace();}把我的第二张素描包装成这样:

代码语言:javascript
复制
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();}
}

这给了我这个错误的结果:

代码语言:javascript
复制
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)

编辑4

为我的Headline-Class构造函数:

代码语言:javascript
复制
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()的情况,下面是:

代码语言:javascript
复制
Layout useLayout(String name) {
    ArrayList layoutVariants = new ArrayList<Layout>();
    int existingLayouts = layouts.size();
    Layout chosenLayout;

    for(int i = 0; i < existingLayouts; i++) {
      Layout currentLayout = (Layout)layouts.get(i);
      if(currentLayout.layoutType == name) {
        layoutVariants.add(currentLayout);
      }
    }

    if(layoutVariants != null) {
      int rand = (int)(Math.random() * layoutVariants.size());
      chosenLayout = (Layout)layoutVariants.get(rand);
    } else {
      chosenLayout = (Layout)layouts.get((int)(Math.random() * existingLayouts)); 
    }
  return chosenLayout;
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-01-24 20:49:45

您的代码有两个问题,它们都在您的useLayout方法中。

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

代码语言:javascript
复制
    if(currentLayout.layoutType == name) {

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

这一行应改为:

代码语言:javascript
复制
    if(currentLayout.layoutType.equals(name)) {

也见这个问题。

第二个问题是,您没有正确处理layoutVariants列表为空的情况。问题就在这条线上:

代码语言:javascript
复制
    if(layoutVariants != null) {

layoutVariants永远不会为null,因此这个if语句的else分支永远不会执行。因为layoutVariants.size()将为零,rand将始终为零。尝试在空的ArrayList中获取索引0处的元素将精确地给出您正在看到的IndexOutOfBoundsException

如果未识别给定的布局名称,即如果else列表是空的,而不是空的,那么我想要执行layoutVariants块。在这种情况下,将该行更改为

代码语言:javascript
复制
    if(!layoutVariants.isEmpty()) {

注意! (非-运算符)在layoutVariants之前。如果if元素不是空的,则希望运行layoutVariants语句下的代码。

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

让我们尝试一个现实世界的类比:购物袋。如果你有一个空包,或者根本没有包,那么你就没有购物的任何一条路。但是,您可以将东西放入一个空袋子中,并计算其中包含了多少项,例如。如果你没有一个袋子,那么把一个东西放在里面是没有意义的,因为没有袋子可以放进去。null代表没有包的情况。

类似地,String是一个字符集合,即使它不包含任何字符,也可以存在字符集合。

isEmpty()可以用于任何收藏,如果您使用的是Java6或更高版本,则可以使用字串。从我的头上看,我无法命名任何具有isEmpty方法的其他类。您只需查阅这些类的文档就可以找到答案。

我对处理的工作不多,但我知道处理是建立在Java之上的,所以我希望任何标准的Java方法都能工作。另外,我也不会担心“清除”一个变量: JVM通常非常擅长于在您之后清除。在这方面,我当然看不出您的代码有什么问题。

编辑2以回应您的进一步评论:ArrayList arr;声明了一个类型为ArrayList的变量。但是,变量arr未初始化:它没有值(甚至没有null),在分配值之前尝试读取该变量的值是错误的:

代码语言:javascript
复制
ArrayList arr;
System.out.println(arr);     // compiler error: arr might not have been initialised.

分配null,然后编译代码:

代码语言:javascript
复制
ArrayList arr = null;
System.out.println(arr);     // prints 'null'.

不经常需要声明一个变量而不给它命名,但是一个常见的情况是,您希望在if语句的两边为相同的变量分配不同的值。以下代码没有编译:

代码语言:javascript
复制
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只能在包含它的大括号{}中可用。在底部,两个变量x都不可用,因此您将得到一个编译器错误。

我们需要进一步声明x。相反,我们可以写以下内容;

代码语言:javascript
复制
int y = getMeSomeInteger();   // assume this function exists
int x = 0;
if (y == 4) {
    x = 2;
} else {
    x = 5;
}
System.out.println(x);

此代码编译并运行,但从未使用最初分配给0的值x。这样做没有什么意义,我们可以通过声明变量而不是立即给它一个值来摆脱这个未使用的值。

代码语言:javascript
复制
int y = getMeSomeInteger();   // assume this function exists
int x;
if (y == 4) {
    x = 2;
} else {
    x = 5;
}
System.out.println(x);
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21335998

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档