PAYATHON 2026

Java 电费程序无法打印完整 billing details

支付小周

结论

费用能够正常输出,说明输入和部分计算逻辑已经执行。name、account num 和 actual reading 没有显示,问题通常不在计算公式,而在于对应的输出语句没有执行。常见原因包括:

  • 输出语句写在了未命中的 if 或 else if 分支中。
  • 程序在打印完整账单前执行了 return、System.exit(...),或者抛出了异常。
  • 程序只调用了费用计算方法,没有调用打印账单的方法。
  • 大括号位置有误,导致输出语句被归入其他条件分支。
  • Bactual 只在 Business 方法或某个局部代码块中定义,却在错误的位置使用。

比较稳妥的处理方式是先完成所有计算,再到条件语句外统一打印账单,不要在每个费率分支中重复输出。

先检查控制流程

可以在关键位置加入临时标记,确认程序执行到了哪一步:

System.out.println("Before calculation");

int actualReading = currentReading - previousReading;

System.out.println("After calculation");
System.out.println("Before billing details");

// 打印完整账单

如果某条标记没有出现,检查它前面是否存在以下代码:

return;
System.exit(0);
throw new RuntimeException(...);

也要检查大括号的位置。在下面的写法中,只有条件成立时才会打印账单详情:

if (actualReading > 500) {
    System.out.println("The cost is " + cost);
    System.out.println("Name: " + name);
    System.out.println("Account No.: " + accountNo);
}

条件不成立时,整个代码块都会被跳过。通用输出应该放在条件语句之后:

if (actualReading <= 500) {
    cost = actualReading * RATE_1;
} else {
    cost = actualReading * RATE_2;
}

System.out.println("Name: " + name);
System.out.println("Account No.: " + accountNo);
System.out.println("The actual reading is " + actualReading);
System.out.println("The cost is " + cost);

注意条件表达式的写法

问题中展示的代码片段:

if(Dactual 501 && Dactual 601 && Bactual

不是合法的 Java 条件表达式。粘贴代码时可能漏掉了比较运算符或后续内容。Java 要求每次比较都写完整,例如:

if (actualReading >= 501 && actualReading <= 600) {
    // ...
}

不能照搬数学中的连续比较写法:

// 错误
if (501 <= actualReading <= 600) {
}

各个费率区间还需要保持连续,不能重叠。例如:

if (actualReading <= 500) {
    // 0 到 500
} else if (actualReading <= 600) {
    // 501 到 600
} else {
    // 601 以上
}

程序进入第二个分支时,已经能够确定 actualReading > 500,所以不用再判断下限。

推荐的程序结构

下面的示例把输入、计算和输出分开,最后只打印一次完整账单。示例中的费率需要替换为题目规定的数值。

import java.util.Scanner;

public class MajanBilling {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        System.out.println("Welcome to Majan Electricity Billing");
        System.out.println("1. Domestic Customer");
        System.out.println("2. Business Customer");
        System.out.print("Select your choice: ");

        int choice = scanner.nextInt();
        scanner.nextLine(); // 清除输入缓冲区中的换行符

        switch (choice) {
            case 1:
                processDomesticCustomer(scanner);
                break;

            case 2:
                processBusinessCustomer(scanner);
                break;

            default:
                System.out.println("Invalid choice.");
        }

        scanner.close();
    }

    private static void processDomesticCustomer(Scanner scanner) {
        System.out.print("Enter your name: ");
        String name = scanner.nextLine();

        System.out.print("Enter your Account No.: ");
        String accountNo = scanner.nextLine();

        System.out.print("Enter your current month reading: ");
        int currentReading = scanner.nextInt();

        System.out.print("Enter your previous month reading: ");
        int previousReading = scanner.nextInt();

        int actualReading = calculateActualReading(
                currentReading,
                previousReading
        );

        double cost = calculateDomesticCost(actualReading);

        printBillingDetails(
                "Domestic",
                name,
                accountNo,
                currentReading,
                previousReading,
                actualReading,
                cost
        );
    }

    private static void processBusinessCustomer(Scanner scanner) {
        System.out.print("Enter your name: ");
        String name = scanner.nextLine();

        System.out.print("Enter your Account No.: ");
        String accountNo = scanner.nextLine();

        System.out.print("Enter your current month reading: ");
        int currentReading = scanner.nextInt();

        System.out.print("Enter your previous month reading: ");
        int previousReading = scanner.nextInt();

        int actualReading = calculateActualReading(
                currentReading,
                previousReading
        );

        double cost = calculateBusinessCost(actualReading);

        printBillingDetails(
                "Business",
                name,
                accountNo,
                currentReading,
                previousReading,
                actualReading,
                cost
        );
    }

    private static int calculateActualReading(
            int currentReading,
            int previousReading
    ) {
        if (currentReading < previousReading) {
            throw new IllegalArgumentException(
                    "Current reading cannot be less than previous reading."
            );
        }

        return currentReading - previousReading;
    }

    private static double calculateDomesticCost(int units) {
        // 示例费率,必须按题目给出的实际费率修改
        if (units <= 500) {
            return units * 0.15;
        } else if (units <= 600) {
            return 500 * 0.15
                    + (units - 500) * 0.20;
        } else {
            return 500 * 0.15
                    + 100 * 0.20
                    + (units - 600) * 0.25;
        }
    }

    private static double calculateBusinessCost(int units) {
        // 示例费率,必须按题目给出的实际费率修改
        if (units <= 500) {
            return units * 0.20;
        } else if (units <= 600) {
            return 500 * 0.20
                    + (units - 500) * 0.25;
        } else {
            return 500 * 0.20
                    + 100 * 0.25
                    + (units - 600) * 0.30;
        }
    }

    private static void printBillingDetails(
            String customerType,
            String name,
            String accountNo,
            int currentReading,
            int previousReading,
            int actualReading,
            double cost
    ) {
        System.out.println();
        System.out.println("Billing Details");
        System.out.println("-------------------------");
        System.out.println("Customer type: " + customerType);
        System.out.println("Name: " + name);
        System.out.println("Account No.: " + accountNo);
        System.out.println("Current reading: " + currentReading);
        System.out.println("Previous reading: " + previousReading);
        System.out.println("The actual reading is " + actualReading);
        System.out.printf("The cost is %.2f%n", cost);
    }
}

关于 Bactual 没有输出

如果代码是这样写的:

if (Bactual > 500) {
    System.out.println("The actual reading is " + Bactual);
}

当 Bactual 等于 200 时,条件不成立,这条输出语句不会执行。应该把它移到费率判断之外:

int Bactual = current - last;

if (Bactual <= 500) {
    cost = ...;
} else if (Bactual <= 600) {
    cost = ...;
} else {
    cost = ...;
}

System.out.println("The actual reading is " + Bactual);

还要确认变量没有混用。Domestic 客户应使用类似 Dactual 的计算结果,Business 客户则使用 Bactual。更简单的做法是让两个流程采用同一个变量名:

int actualReading = current - last;

这样复制代码时不容易误把 Dactual 写成 Bactual。

输入时容易忽略的问题

调用 nextInt() 后紧接着调用 nextLine(),可能会读取输入缓冲区中残留的换行符,最终得到空字符串:

int choice = scanner.nextInt();
scanner.nextLine(); // 必须消费换行符

String name = scanner.nextLine();

账号也适合使用 String,而不是 int:

String accountNo = scanner.nextLine();

账号可能带有前导零或字母。它是标识符,不是参与计算的数值。

另外,The cost is 30** 中的 ** 只是普通字符串内容。如果不想显示星号,检查代码中是否写了:

System.out.println("The cost is " + cost + "**");

将其改成:

System.out.println("The cost is " + cost);

修正时只需让各个费率分支负责给 cost 赋值,然后在所有分支结束后统一调用账单打印逻辑。只要计算方法正常返回,客户信息和实际用电量就会一起输出。

备注:内容仅供参考。