我刚刚开始研究一种名为XScript的编程语言。它的设计使我可以从Java应用程序运行它,但也可以通过Java应用程序重新编程它。我的想法是,我可以在游戏中创建虚拟计算机,或者随着时间的推移自行开发的程序。到目前为止,我有以下代码。据我所知,由于专有软件,可能需要对名称进行更改,但现在还可以。
人工主类:
import com.x.lang.XLoader;
public class Main {
public static void main(String[] args) {
XLoader xl = new XLoader();
xl.exec("/Users/Nathan/Desktop/XScript/test.xls");
}
}
XLoader(加载并执行XScript):
package com.x.lang;
import java.io.File;
import com.x.lang.object.XObject;
public class XLoader {
XObject xo;
public String fileLocation;
public void exec(String fl) {
fileLocation = fl;
XObject xo = new XObject(new File(fileLocation));
xo.exec();
}
}
存储语言键功能的XCommandHub:
package com.x.lang;
import com.x.lang.keyword.Print;
import com.x.lang.keyword.Set;
import com.x.lang.object.XCommand;
import com.x.lang.object.XObject;
public class XCommandHub {
public XCommand xc[] = new XCommand[2];
public XCommandHub(XObject x) {
xc[0] = new Print(x);
xc[1] = new Set(x);
}
public XCommand getCommand(String s) {
for (int i = 0; i < 2; i++) {
if (xc[i].getCommandName() == s) {
return xc[i];
}
}
return null;
}
}
定义关键字的XCommand类:
package com.x.lang.object;
public abstract class XCommand {
private String commandName;
public XObject xobject;
public XCommand (String cn, XObject x) {
commandName = cn;
commandName += ": ";
xobject = x;
}
public abstract void exec(XVar xv);
public String getCommandName() {
return commandName;
}
}
XVar类定义所有变量:
package com.x.lang.object;
public class XVar {
private String var1;
public String name;
public XVar(String s) {
var1 = s;
}
public String getStringValue() {
if (this.var1 != null) {
return var1;
}
return " ";
}
public int getIntValue() {
if (this.var1 != null) {
return Integer.parseInt(var1);
}
return 0;
}
public void setName(String s) {
name = s;
}
}
XObject类实际执行命令:
package com.x.lang.object;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import com.x.lang.XCommandHub;
public class XObject {
public XVar xvars[] = new XVar[150];
public int varCount = 0;
public File f;
XCommandHub x;
public XObject (File file) {
f = file;
x = new XCommandHub(this);
}
public void addVar(XVar var, String name) {
xvars[varCount] = var;
xvars[varCount].setName(name);
varCount++;
}
public XVar getVar(String varName) {
for (int i = 0; i < varCount; i++) {
if (xvars[i].name == varName) {
return xvars[i];
}
}
return null;
}
public void exec() {
try (BufferedReader br = new BufferedReader(new FileReader(f))) {
String sCurrentLine;
while ((sCurrentLine = br.readLine()) != null) {
for (int i = 0; i < 2; i++) {
if (sCurrentLine.startsWith(x.xc[i].getCommandName()))
try {
x.getCommand(x.xc[i].getCommandName()).exec(new XVar(sCurrentLine.split(": ")[1]));
} catch (ArrayIndexOutOfBoundsException e) {
x.getCommand(x.xc[i].getCommandName()).exec(new XVar(" "));
}
}
}
}
catch (IOException e) {
e.printStackTrace();
}
}
}
定义我迄今为止编程的命令的两个类:
package com.x.lang.keyword;
import com.x.lang.object.XCommand;
import com.x.lang.object.XObject;
import com.x.lang.object.XVar;
public class Print extends XCommand {
public Print(XObject x) {
super("print", x);
}
@Override
public void exec(XVar xv) {
if (xv.getStringValue().startsWith("%")) {
try {
System.out.println(xobject.getVar(xv.getStringValue().substring(1)).getStringValue());
} catch (NullPointerException e) {
System.out.println(xv.getStringValue());
}
}
else {
System.out.println(xv.getStringValue());
}
}
}
package com.x.lang.keyword;
import com.x.lang.object.XCommand;
import com.x.lang.object.XObject;
import com.x.lang.object.XVar;
public class Set extends XCommand {
public Set(XObject x) {
super("set", x);
}
@Override
public void exec(XVar xv) {
String[] add = xv.getStringValue().split("=");
xobject.addVar(new XVar(add[1]), add[0]);
}
}
到目前为止,我已经编程了,我试图让用户能够打印他们在代码中声明的变量。一个基本的.xls(X语言脚本)可能看起来像这样:
set: x=Hello StackOverflow
print: This was programmed in XScript!
print:
print: %x
但是,当我尝试从数组中检索变量x时,print类中存在NullPointerException。该程序返回“%x”而不是“Hello StackOverflow”,因为我故意抓住了异常,但我不知道它是如何产生的。
由于 Doctor_N
答案 0 :(得分:1)
您的代码永远找不到它要查找的变量:
public XVar getVar(String varName) {
for (int i = 0; i < varCount; i++) {
if (xvars[i].name == varName) {
return xvars[i];
}
}
return null;
}
此功能几乎总是返回null
,因为您使用==
比较字符串而不使用.equals
。 ==
比较引用(内存地址),并且您要比较的参数和字符串极不可能指向同一位置。因此,您几乎总是返回null
。
因此,此行始终会生成NullPointerException
:
System.out.println(xobject.getVar(xv.getStringValue().substring(1)).getStringValue());
这是因为您有效地在getStringValue()
上致电null
。
我建议将if
更改为:
if(xvars[i] != null && xvars[i].name.equals(varName)) {
...
}