You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 00:47:50