Java代码输出异常:setter/getter导致重复输出或null值问题排查
问题分析与解决方案
你遇到的问题根源有两个:
- 你的
setcustomerDiscount方法里直接包含了System.out.print语句,导致在设置折扣时提前输出了折扣值,和后续main方法里的输出连在一起,出现重复内容; - 当你去掉print语句后,如果消费金额不满足任何折扣条件,
customerDiscount字段会被赋值为空字符串,或者如果调用逻辑有疏漏的话会返回null——不过更合理的做法是把折扣计算逻辑移到getter中,因为折扣是基于消费金额动态计算的派生属性,不需要单独存储。
下面是修正后的完整代码,我会标注关键修改点:
修正后的代码
Person类(仅修正拼写细节,核心逻辑不变)
package driver2; import java.util.Scanner; import java.text.DecimalFormat; class Person{ private String name; private String address; private String number; private double customerPurchase = 0; //////// Constructors ///////// public Person(String name, String address, String number, int customerPurchase){ this.name = name; this.address = address; this.number = number; this.customerPurchase = customerPurchase; } public Person(){} //////// Accessors ///////// public String getName(){ return this.name; } public String getAddress(){ return this.address; } public String getNumber(){ return this.number; } public double getcustomerPurchase(){ return this.customerPurchase; } //////// Mutators ///////// public void setName(String n){ this.name = n; } public void setAddress(String a){ this.address = a; } public void setNumber(String n){ this.number = n; } public void setcustomerPurchase(int a){ this.customerPurchase = a; } // 父类的空setter可以保留,也可以直接移除 public void setcustomerDiscount(int r) {} }
Customer类(核心修改部分)
class Customer extends Person{ private String customerNumber; private boolean recieveMail; // 移除单独存储的customerDiscount字段,折扣无需持久化,动态计算即可 //////// Constructors ///////// public Customer(String name, String address, String number, String customerN, boolean rm, int customerPurchase) { super(name, address, number, customerPurchase); this.customerNumber = customerN; this.recieveMail = rm; } public Customer(){} //////// Accessors ///////// public String getCustomerNumber(){ return this.customerNumber; } public boolean getRecieveMail(){ return this.recieveMail; } // 核心修改:把折扣计算逻辑移到getter中,每次调用时动态计算 public String getcustomerDiscount(){ double purchaseAmount = getcustomerPurchase(); if (purchaseAmount >= 2000){ return "10%"; }else if (purchaseAmount >= 1500){ return "7%"; }else if (purchaseAmount >= 1000){ return "6%"; }else if (purchaseAmount > 500){ return "5%"; }else{ return "0%"; // 也可以返回空字符串,根据业务需求调整 } } //////// Mutators ///////// public void setCustomerNumber(String c){ this.customerNumber = c; } public void setRecieveMail(boolean r){ this.recieveMail = r; } // 移除原setter的逻辑,现在不需要手动设置折扣 @Override public void setcustomerDiscount(int r){ // 留空或直接删除这个方法都可以 } }
Driver2主类(简化调用流程)
public class Driver2{ public static void main(String args[]){ Scanner scanner = new Scanner(System.in); System.out.print("Enter name of customer:"); String name1 = scanner.nextLine(); System.out.print("Enter address of customer:"); String address1 = scanner.nextLine(); System.out.print("Enter phone number of customer:"); String number1 = scanner.nextLine(); System.out.print("Enter customer number:"); String customerNumber = scanner.nextLine(); System.out.print("Enter yes/no -- does the customer want to recieve mail?:"); String answer = scanner.nextLine(); boolean recieveMail = (answer.equals("yes")); System.out.print("Enter amount customer has spent:"); int customerPurchase = scanner.nextInt(); scanner.close(); Customer customer = new Customer(name1, address1, number1, customerNumber, recieveMail, customerPurchase); System.out.println("\nCustomer: "); System.out.println("Name: "+customer.getName()); System.out.println("Address: "+customer.getAddress()); System.out.println("Phone Number: "+customer.getNumber()); System.out.println("Customer Number: "+customer.getCustomerNumber()); System.out.println("Recieve Mail?: "+customer.getRecieveMail()); DecimalFormat ft = new DecimalFormat("####"); ft = new DecimalFormat("$0.00"); System.out.println("Amount Purchased: "+ft.format(customer.getcustomerPurchase())); // 不再需要调用setcustomerDiscount,直接调用getter获取折扣 System.out.println("Percent off: " + customer.getcustomerDiscount()); } }
关键修改说明
- 移除冗余字段:删除了Customer类中
customerDiscount成员变量,因为折扣是基于消费金额动态计算的,不需要持久存储。 - 逻辑迁移到getter:把原来setter里的折扣判断逻辑移到
getcustomerDiscount()方法中,每次调用都会根据当前消费金额计算最新折扣,彻底避免了字段未初始化的问题。 - 清理输出逻辑:移除了setter中的
System.out.print,统一在main方法中输出结果,解决了重复输出的问题。 - 简化调用流程:main方法中不再需要手动调用
setcustomerDiscount,直接调用getter就能获取正确的折扣值。
这样修改后,无论消费金额是多少,都能输出符合预期的Percent off: X%格式,不会出现重复或null的问题。
内容的提问来源于stack exchange,提问作者PROJ3CT2501
相关产品推荐
相关产品推荐

