Java初学者项目实战:实现简易的计算器应用

用Swing因JDK 8–17默认支持、无需额外配置,组件命名直白、布局简单、单文件可运行;解析算式需过滤非法字符、用双栈法计算、捕获除零异常;按钮事件须清空输入、校验小数点、禁用无谓setEnabled;StringBuffer拼接高效且便于退格与括号校验。

为什么用Swing而不是JavaFX写这个计算器

Swing组件在JDK 8–17中默认可用,无需额外依赖;初学者能直接运行javac + java完*流程。JavaFX虽然更现代,但JDK 11+已不捆绑,需手动配置javafx.controls模块,容易卡在ClassNotFoundException: javafx.application.Application这类错误上。

  • Swing的JFrameJButtonJTextField命名直白,事件监听器写法统一(addActionListener
  • 布局用GridLayout(4, 4)就能对齐按钮,不用处理JavaFX的AnchorPane约束或CSS样式
  • 所有代码可塞进单个.java文件,避免初学者被模块划分、包路径、FXML加载等问题干扰

如何安全地解析用户输入的算式字符串

别用ScriptEngineManager执行用户输入——它会执行任意Java代码,比如System.exit(0)new java.io.File("/").listFiles(),教学项目里极易被忽略这个风险。

  • 只允许数字、+-*/.()这9种字符,其他一律过滤
  • 用双栈法(操作数栈 + 运算符栈)实现简单四则运算,避开eval()类黑盒调用
  • 除零时捕获ArithmeticException,显示"Error"而非崩溃
public static double calculate(String expr) {
    expr = expr.replaceAll("\\s+", ""); // 去空格
    if (expr.isEmpty()) return 0;
    try {
        return new CalculatorEngine().evaluate(expr);
    } catch (Exception e) {
        return Double.NaN; // 触发后续显示"Error"
    }
}

按钮点击事件里最常漏掉的三件事

很多初学者写完button.addActionListener(e -> { ... })就以为结束了,结果遇到界面卡死、按钮重复响应、小数点连按出错等问题。

  • 每次计算前清空inputField.setText(""),否则连续点击=会把上次结果当新输入
  • 禁用button.setEnabled(false)仅在耗时操作中才需要,计算器纯内存运算,**不要加**——反而导致按钮变灰无法再点
  • 小数点按钮逻辑必须检查当前输入是否已含小数点:if (!input.contains(".")) input += ".";,否则1..5这种非法串会传给解析器

为什么建议用StringBuffer而不是String拼接表达式

用户狂点按钮时,表达式字符串频繁修改(如"1+2*""1+2*3""1+2*3-"),用String每次+=都会新建对象,GC压力大且无必要。

  • StringBuffer线程安全,虽计算器单线程用不到,但它的append()deleteCharAt()substring()拼接直观得多
  • 退格键实现只需buffer.del

    eteCharAt(buffer.length()-1)
    ,不用算索引、切片、再拼接
  • 最终转toString()一次即可交给解析器,中间过程无字符串拷贝

复杂点在于括号匹配校验——用户可能输入"((1+2)",这时得遍历StringBuffer统计左右括号数量,不等就拒绝计算。这个细节初学者几乎都会跳过,直到发现"1+((2*3)"也能点等于号并返回错误结果。