Newton-Raphson迭代Java代码修复求助:空指针异常问题
修复Newton-Raphson迭代法Java代码中的空指针异常
问题原因分析
触发NullPointerException的直接原因是ScriptEngine engine对象为null,因为调用getEngineByName("JavaScript")可能失败:
- 部分Java环境中,JavaScript引擎的识别名称为
js而非JavaScript - Java 11及以上版本移除了默认的Nashorn引擎,需手动添加依赖才能使用
此外代码还存在其他潜在问题:
- 每次调用
getUserInput都创建新的Scanner对象,易引发资源泄漏 - 循环中错误地将Java变量
x0直接嵌入JS代码,导致JS无法识别该变量 - 输出
f(x1)时误用了f(x0)的计算结果
修复步骤
1. 确保ScriptEngine正确初始化
修改引擎获取逻辑,兼容不同名称的引擎,并添加null检查:
engine = new ScriptEngineManager().getEngineByName("JavaScript"); if (engine == null) { engine = new ScriptEngineManager().getEngineByName("js"); } if (engine == null) { System.err.println("无法找到JavaScript脚本引擎,请检查Java环境"); return; }
若使用Java 11+,需添加Nashorn引擎依赖(Maven):
<dependency> <groupId>org.openjdk.nashorn</groupId> <artifactId>nashorn-core</artifactId> <version>15.4</version> </dependency>
2. 优化Scanner资源使用
将Scanner声明为类静态变量,避免重复创建:
private static ScriptEngine engine; private static Scanner scanner = new Scanner(System.in);
同时修改getUserInput方法:
private static String getUserInput(String message) { System.out.print(message); return scanner.nextLine(); }
3. 修正JS变量引用错误
移除无效的JS函数定义,直接通过字符串替换计算导数在当前x值处的结果:
// 移除原有的gFunc定义与eval调用 // String gFunc = "function(x) { return " + g + "; }"; // engine.eval(gFunc); // 直接计算导数在x0处的值 String gEval = g.replace("x", Double.toString(x0)); double gResult = (double) engine.eval(gEval); if (Double.compare(gResult, 0.0) == 0) { System.out.println("Divide by zero error!"); break; }
4. 修正f(x1)输出错误
重新计算f(x1)的值用于输出和循环条件判断:
double x1 = x0 - fResult / gResult; // 计算f(x1)的真实值 String f1Eval = f.replace("x", Double.toString(x1)); double f1Result = (double) engine.eval(f1Eval); // 输出正确的f(x1) System.out.printf("Iteration-%d, x1 = %0.6f and f(x1) = %0.6f\n", step, x1, f1Result); // 使用f(x1)的绝对值判断终止条件 condition = Math.abs(f1Result) > e;
完整修复后的代码
import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; import javax.script.ScriptException; import java.util.Scanner; public class NewtonRaphson { private static ScriptEngine engine; private static Scanner scanner = new Scanner(System.in); public static void main(String[] args) { String func = getUserInput("Enter function f(x): "); String der = getUserInput("Enter derivative of f(x): "); double guess = Double.parseDouble(getUserInput("Enter Guess: ")); double error = Double.parseDouble(getUserInput("Tolerable Error: ")); int maxSteps = Integer.parseInt(getUserInput("Maximum Step: ")); newtonRaphson(func, der, guess, error, maxSteps); scanner.close(); } public static void newtonRaphson(String f, String g, double x0, double e, int N) { try { engine = new ScriptEngineManager().getEngineByName("JavaScript"); if (engine == null) { engine = new ScriptEngineManager().getEngineByName("js"); } if (engine == null) { System.err.println("无法找到JavaScript脚本引擎,请检查Java环境"); return; } System.out.println("\n\n*** NEWTON RAPHSON METHOD IMPLEMENTATION ***"); int step = 1; int flag = 1; boolean condition = true; while (condition) { String gEval = g.replace("x", Double.toString(x0)); double gResult = (double) engine.eval(gEval); if (Double.compare(gResult, 0.0) == 0) { System.out.println("Divide by zero error!"); break; } String fEval = f.replace("x", Double.toString(x0)); double fResult = (double) engine.eval(fEval); double x1 = x0 - fResult / gResult; String f1Eval = f.replace("x", Double.toString(x1)); double f1Result = (double) engine.eval(f1Eval); System.out.printf("Iteration-%d, x1 = %0.6f and f(x1) = %0.6f\n", step, x1, f1Result); x0 = x1; step++; if (step > N) { flag = 0; break; } condition = Math.abs(f1Result) > e; } if (flag == 1) { System.out.printf("\nRequired root is: %0.8f\n", x0); } else { System.out.println("\nNot Convergent."); } } catch (ScriptException ex) { System.err.println("脚本执行错误: " + ex.getMessage()); } } private static String getUserInput(String message) { System.out.print(message); return scanner.nextLine(); } }
测试示例
运行代码后输入以下内容可验证功能:
- 函数f(x):
x*x - 4 - 导数:
2*x - 初始猜测:
3 - 误差容忍度:
0.000001 - 最大迭代次数:
10
程序会输出迭代过程,最终得到根2.00000000。
内容的提问来源于stack exchange,提问作者Renlyze
相关产品推荐
相关产品推荐

