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

Java静态变量total累加翻倍异常问题求助(附代码)

问题:静态变量累加发票总价时出现翻倍异常

我在Java程序里用静态变量total记录发票总价,每次用户输入新商品价格后用+=累加,但总价没有正确更新,反而出现金额翻倍的情况。尝试在增强for循环里嵌套普通for循环迭代这个静态变量,问题还是没解决。

原代码:

// 主逻辑部分
while(isRunning) {
  try {
    System.out.println("Please enter the name of your item you want to add: (type quit to exit) ");
      String item = input.nextLine();

    if(item.equalsIgnoreCase("quit")) {
      break;
    }
    System.out.println("Please enter the price of the item to be added to the invoice. ");
      receipt.setTotal(input.nextDouble());
      input.nextLine();
      itemList itemlist = new itemList(item, Invoice.total);
      price.add(itemlist);

  } catch (InputMismatchException e) {
    System.out.println("Exception caught!");
  }

  for(Invoice itemization : price) {
    Invoice.total += itemization.getTotal();
    System.out.println();
    System.out.println("Item: " + itemization.getItem() + "\nPrice: " + itemization.getTotal());
    System.out.println("Subtotal: " + Math.round(receipt.getTotal() * 100.00) / 100.00);
}

// 类定义部分
import java.util.*;

public class Invoice {

  static Double total;
  public String item;
  List<Invoice> price = new ArrayList<>();

  public String getItem() {
    return item;
  }

  public double getTotal() {
    return total;
  }

  public void setTotal(Double total) {
    Invoice.total = total;
  }

  public void endBalance() {

    if (getTotal() > 0.0) {
    System.out.println();
    System.out.println("$" + getTotal() + " Will be deposited once cleared. ");
    System.out.println();
    System.out.println("Expect most transfer to deposit to your account with 3 to 5 business days. ");
    System.out.println();

    } else {
      System.out.println("Available balance too low for bank deposit. ");
    }
  }
}

class itemList extends Invoice {

  public itemList(String item, Double total) {
    this.item = item;
  }
}

问题根源:

  1. 静态变量共享导致覆盖:Invoice.total是静态变量,所有Invoice子类实例共用同一个值。每次调用setTotal都会直接覆盖全局的total,而不是存储当前商品的价格。
  2. 重复累加逻辑错误:每次添加商品后,都会遍历整个商品列表对全局total进行累加,相当于把所有商品的价格又加了一遍,导致总价多次翻倍。
  3. 类职责混乱:itemList继承Invoice完全不合理,商品不是发票的子类,而且构造函数没有存储传入的价格,所有实例的getTotal()都返回全局静态变量的值,进一步加剧重复累加。

修复方案:

拆分职责,去掉静态变量,用非静态变量维护总价,修正累加逻辑:

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.InputMismatchException;

// 发票类:管理商品列表和总价
public class Invoice {
    private List<Item> items = new ArrayList<>();
    private double total = 0.0;

    // 添加商品并更新总价
    public void addItem(Item item) {
        items.add(item);
        total += item.getPrice();
    }

    // 获取保留两位小数的总价
    public double getFormattedTotal() {
        return Math.round(total * 100.0) / 100.0;
    }

    // 打印所有商品明细和当前小计
    public void printItemization() {
        for (Item item : items) {
            System.out.println();
            System.out.println("商品: " + item.getName() + "\n价格: " + item.getPrice());
        }
        System.out.println("\n小计: " + getFormattedTotal());
    }

    // 打印最终到账信息
    public void endBalance() {
        if (total > 0.0) {
            System.out.println();
            System.out.println("确认到账金额: $" + getFormattedTotal());
            System.out.println();
            System.out.println("预计转账将在3-5个工作日内存入您的账户。");
            System.out.println();
        } else {
            System.out.println("可用余额过低,无法进行银行转账。");
        }
    }
}

// 商品类:存储单个商品的名称和价格
class Item {
    private String name;
    private double price;

    public Item(String name, double price) {
        this.name = name;
        this.price = price;
    }

    public String getName() {
        return name;
    }

    public double getPrice() {
        return price;
    }
}

// 主程序
public class InvoiceApp {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        boolean isRunning = true;
        Invoice receipt = new Invoice();

        while (isRunning) {
            try {
                System.out.println("请输入要添加的商品名称(输入quit退出): ");
                String itemName = input.nextLine();

                if (itemName.equalsIgnoreCase("quit")) {
                    break;
                }

                System.out.println("请输入该商品的价格: ");
                double itemPrice = input.nextDouble();
                input.nextLine(); // 清除输入后的换行符

                Item newItem = new Item(itemName, itemPrice);
                receipt.addItem(newItem);
                receipt.printItemization();

            } catch (InputMismatchException e) {
                System.out.println("输入错误!请输入有效的数字价格。");
                input.nextLine(); // 清除错误输入,避免死循环
            }
        }

        receipt.endBalance();
        input.close();
    }
}

修复关键点:

  • 拆分Invoice和Item的职责,逻辑更清晰,避免继承滥用。
  • 用Invoice的非静态total变量维护总价,每次添加商品时只累加当前商品价格,不会重复计算。
  • 移除静态变量,避免全局共享导致的值覆盖问题。
  • 优化输入异常处理,避免死循环。

内容的提问来源于stack exchange,提问作者dankest germ

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 14:25:26