处理 - 将变量作为参数传递 - 获取 NullPointerException

processing - passing variables as parameters - getting NullPointerException

我已经用将变量传递给 Lsystem 的构造函数编写了代码。

这应该允许我创建大量 'Trees',每次都在乱搞参数。

但是,我得到了一个 NullPointerException 行

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

我知道我需要使用它。某处(尽我所能阅读),但我对如何使我的代码工作感到困惑。

如果有人能告诉我正确的代码应该是什么样子,我将不胜感激。

提前致谢。

class Tree {

  // member variables
  int    m_lineLength;       // turtle line length
  int    m_x;                // initial x position
  int    m_y;                // initial y position
  float  m_branchAngle;      // turtle rotation at branch
  float  m_initOrientation;  // initial orientation
  String m_state;            // initial state
  float  m_scaleFactor;      // branch scale factor
  String m_F_rule;           // F-rule substitution
  String m_H_rule;           // H-rule substitution
  String m_f_rule;           // f-rule substitution
  int    m_numIterations;    // number of times to substitute

  // constructor
  // (d = line length, x & y = start position of drawing)
  Tree(int d, int x, int y, float m_branchAngle, float m_initOrientation, String m_state, float m_scaleFactor, String m_F_rule, String m_H_rule, String m_f_rule, int m_numIterations) {
    m_lineLength = d;
    m_x = x;
    m_y = y; 
    m_branchAngle = (25.7/180.0)*PI;
    m_initOrientation = -HALF_PI;
    m_scaleFactor = 1;
    m_state = "F";
    m_F_rule = "F[+F]F[-F]F";
    m_H_rule = "";
    m_f_rule = "";
    m_numIterations = 5;

    // Perform L rounds of substitutions on the initial state
    for (int k=0; k < m_numIterations; k++) {
      m_state = substitute(m_state);
    }
  }

  void draw() {
    pushMatrix();
    pushStyle();

    stroke(0);
    translate(m_x, m_y);        // initial position
    rotate(m_initOrientation);  // initial rotation

    // now walk along the state string, executing the
    // corresponding turtle command for each character
    for (int i=0; i < m_state.length(); i++) {
      turtle(m_state.charAt(i));
    }

    popStyle();
    popMatrix();
  }

  // Turtle command definitions for each character in our alphabet
  void turtle(char c) {
    switch(c) {
    case 'F': // drop through to next case
    case 'H':
      line(0, 0, m_lineLength, 0);
      translate(m_lineLength, 0);
      break;
    case 'f':
      translate(m_lineLength, 0);
      break;
    case 's':
      scale(m_scaleFactor);
      break;
    case '-':
      rotate(m_branchAngle);
      break;
    case '+':
      rotate(-m_branchAngle);
      break;
    case '[':
      pushMatrix();
      break;
    case ']':
      popMatrix();
      break;
    default:
      println("Bad character: " + c);
      exit();
    }
  }

  // apply substitution rules to string s and return the resulting string
  String substitute(String s) {
    String newState = new String();
    for (int j=0; j < s.length(); j++) {
      switch (s.charAt(j)) {
      case 'F':
        newState += m_F_rule;
        break;
      case 'H':
        newState += m_F_rule;
        break;
      case 'f':
        newState += m_f_rule;
        break;
      default:
        newState += s.charAt(j);
      }
    }
    return newState;
  }

}

Tree tree;

void setup() {
  int SZ = 512;  // screen size

  int d = 2;
  int x = SZ/2;
  int y = SZ;

  float m_branchAngle = (25.7/180.0)*PI;
  float m_initOrientation = -HALF_PI; 
  String m_state = "F";
  float m_scaleFactor = 1;
  String m_F_rule = "F[+F]F[-F]F";
  String m_H_rule = ""; 
  String m_f_rule = "";
  int m_numIterations = 5;

  size(SZ,SZ);
  background(255);
  noLoop();

  tree = new Tree(d, x, y, m_branchAngle, m_initOrientation, m_state, m_scaleFactor, m_F_rule, m_H_rule, m_f_rule, m_numIterations);  
}

void draw() {
  tree.draw();
}

让我们看一下 Tree 构造函数的简化版本:

String m_state;

Tree(String m_state) {
    m_state = "F";
    for (int k=0; k < m_numIterations; k++) {
      m_state = substitute(m_state);
    }
}

请注意,您有两个名为 m_state 的变量:一个 class 级实例变量和一个构造函数参数。这意味着构造函数级变量 隐藏 class 级变量。您在构造函数中对 m_state 变量所做的任何操作都指的是构造函数级别的变量,而不是 class 级别的变量。

然后您使用从未真正初始化过的 class 级变量。这就是导致 NullPointerException 的原因。

解决该问题的一种方法是使用this关键字专门引用class级变量:

String m_state;

Tree(String m_state) {
    this.m_state = "F";
    for (int k=0; k < m_numIterations; k++) {
      this.m_state = substitute(this.m_state);
    }
}

但是,如果您不使用构造函数级别的 m_state 变量来做任何事情,您为什么要费心呢?因此,如果您只是打算将其设置为等于 "F",则您可以完全消除该参数。