处理 - 将变量作为参数传递 - 获取 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",则您可以完全消除该参数。
我已经用将变量传递给 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",则您可以完全消除该参数。