Java 方法返回错误值

标签 java

我正在努力学习如何在 Java 中正确编写方法。我看过很多例子,但看不出我做错了什么。我有一个名为 InvoiceApp 的主类,它使用一个名为 Validator 的类来筛选输入,然后使用一个名为 Invoice 的类来处理用户输入。当 InvoiceApp 运行时,用户输入“r”或“c”作为客户类型,并输入 double 值“小计”。该应用程序创建 Invoice 类的对象以使用 getInvoice() 方法,该方法返回格式化的发票。 返回格式化的发票,但字符串为 NULL 值,所有数字均为 ZEROES(用户在第一个位置输入的除外)。 Invoice 类显然没有为变量赋值。我已经用了很多很多不同的方法,但无法让事情发挥作用。

有人能看出我做错了什么吗?这是我的代码:

InvoiceApp 类:

import java.util.Scanner;

public class InvoiceApp
{    
public static void main(String[] args)
{
    // display a welcome message
    System.out.println("Welcome to the Invoice Total Calculator");
    System.out.println();  // print a blank line

    Scanner sc = new Scanner(System.in);
    String choice = "y";
    while(choice.equalsIgnoreCase("y"))
    {
        // get user entries
        String customerType = Validator.getString(sc,
            "Enter customer type (r/c):   ");
        double subtotal = Validator.getDouble(sc,
            "Enter subtotal:              ", 0, 10000);

        Invoice i;
        i = new Invoice(customerType, subtotal);
        System.out.println();
        System.out.println(i.getInvoice());

        System.out.println();
        System.out.print("Continue? (y/n): ");
        choice = sc.next();
        System.out.println();
    }
} 
}

发票类:

import java.text.NumberFormat;

public class Invoice {
private final String customerType;
private final double subtotal;
private double discountAmount;
private double discountPercent;
private double invoiceTotal;
private String sCustomerType;

public Invoice(String customerType, double subtotal){
    this.customerType = customerType;
    this.subtotal = subtotal;
}
public void setDiscountPercent(double discountPercent){
    if (customerType.equalsIgnoreCase("r"))
    {
        if (subtotal >= 500)
            discountPercent = .2;
        else if (subtotal >= 250 && subtotal < 500)
            discountPercent =.15;
        else if (subtotal >= 100 && subtotal < 250)
            discountPercent =.1;
        else if (subtotal < 100)
            discountPercent =.0;
    }
    else if (customerType.equalsIgnoreCase("c"))
    {
            discountPercent = .2;
    }
    else
    {
        discountPercent = .05;
    }
}
public double getDiscountPercent(){
    return discountPercent;
}
public void setDiscountAmount(double discountAmount){
    discountAmount = subtotal * (getDiscountPercent());
}
public double getDiscountAmount(){
    return discountAmount;
}
public void setInvoiceTotal(double invoiceTotal){
    invoiceTotal = subtotal - (getDiscountAmount());
}
public double getInvoiceTotal(){
    return invoiceTotal;
}
public void setCustomerType(String sCustomerType){
    sCustomerType = "Unknown";
        if (customerType.equalsIgnoreCase("r"))
            sCustomerType = "Retail";
        else if (customerType.equalsIgnoreCase("c"))
            sCustomerType = "College";
}
public String getCustomerType(){
    return sCustomerType;
}
public String getInvoice(){
    NumberFormat currency = NumberFormat.getCurrencyInstance();
    NumberFormat percent = NumberFormat.getPercentInstance();
    sCustomerType = this.getCustomerType();
    discountPercent = this.getDiscountPercent();
    discountAmount = this.getDiscountAmount();
    invoiceTotal = this.getInvoiceTotal();
    // Create a string representation of the full invoice and return
    String invoice = ("Subtotal:         " + currency.format(subtotal) + "\n"
                   + "Customer type:    " + sCustomerType + "\n"
                   + "Discount percent: " + percent.format(discountPercent)+ "\n"
                   + "Discount amount:  " + currency.format(discountAmount)+ "\n"
                   + "Total:            " + currency.format(invoiceTotal) + "\n");
    return invoice;
}
}

validator 类:

import java.util.Scanner;

public class Validator
{
public static String getString(Scanner sc, String prompt)
{
    System.out.print(prompt);
    String s = sc.next();  // read user entry
    sc.nextLine();  // discard any other data entered on the line
    return s;
}

public static int getInt(Scanner sc, String prompt)
{
    int i = 0;
    boolean isValid = false;
    while (isValid == false)
    {
        System.out.print(prompt);
        if (sc.hasNextInt())
        {
            i = sc.nextInt();
            isValid = true;
        }
        else
        {
            System.out.println("Error! Invalid integer value. Try again.");
        }
        sc.nextLine();  // discard any other data entered on the line
    }
    return i;
}

public static int getInt(Scanner sc, String prompt,
int min, int max)
{
    int i = 0;
    boolean isValid = false;
    while (isValid == false)
    {
        i = getInt(sc, prompt);
        if (i <= min)
            System.out.println(
                "Error! Number must be greater than " + min + ".");
        else if (i >= max)
            System.out.println(
                "Error! Number must be less than " + max + ".");
        else
            isValid = true;
    }
    return i;
}

public static double getDouble(Scanner sc, String prompt)
{
    double d = 0;
    boolean isValid = false;
    while (isValid == false)
    {
        System.out.print(prompt);
        if (sc.hasNextDouble())
        {
            d = sc.nextDouble();
            isValid = true;
        }
        else
        {
            System.out.println("Error! Invalid decimal value. Try again.");
        }
        sc.nextLine();  // discard any other data entered on the line
    }
    return d;
}

public static double getDouble(Scanner sc, String prompt,
double min, double max)
{
    double d = 0;
    boolean isValid = false;
    while (isValid == false)
    {
        d = getDouble(sc, prompt);
        if (d <= min)
            System.out.println(
                "Error! Number must be greater than " + min + ".");
        else if (d >= max)
            System.out.println(
                "Error! Number must be less than " + max + ".");
        else
            isValid = true;
    }
    return d;
}
}

感谢任何可以提供帮助的人

<小时/>

谢谢大家。我从 setter 方法中删除了参数并添加了它。给构造函数。显然,我对两个主要领域感到困惑:

  1. set 方法中应该包含哪些参数?我尝试插入 set 方法实际使用的变量,但这也不起作用。

  2. 我认为 get 方法只是用于返回 set 方法生成的值。由于setter都是void,所以不能直接使用。我见过的工作示例的构造类似(但它们实际上是有效的)。

这是我在 Invoice 类中所做的更改。

    import java.text.NumberFormat;

public class Invoice {
private final String customerType;
private final double subtotal;
private double discountAmount;
private double discountPercent;
private double invoiceTotal;
private String sCustomerType;

public Invoice(String customerType, double subtotal){
    this.customerType = customerType;
    this.subtotal = subtotal;
}
public void setDiscountPercent(){
    if (customerType.equalsIgnoreCase("r"))
    {
        if (subtotal >= 500)
            this.discountPercent = .2;
        else if (subtotal >= 250 && subtotal < 500)
            this.discountPercent =.15;
        else if (subtotal >= 100 && subtotal < 250)
            this.discountPercent =.1;
        else if (subtotal < 100)
            this.discountPercent =.0;
    }
    else if (customerType.equalsIgnoreCase("c"))
    {
            this.discountPercent = .2;
    }
    else
    {
        this.discountPercent = .05;
    }
}
public double getDiscountPercent(){
    return this.discountPercent;
}
public void setDiscountAmount(){
    this.discountAmount = subtotal * (getDiscountPercent());
}
public double getDiscountAmount(){
    return this.discountAmount;
}
public void setInvoiceTotal(){
    this.invoiceTotal = subtotal - (getDiscountAmount());
}
public double getInvoiceTotal(){
    return this.invoiceTotal;
}
public void setCustomerType(){
    this.sCustomerType = "Unknown";
        if (customerType.equalsIgnoreCase("r"))
            this.sCustomerType = "Retail";
        else if (customerType.equalsIgnoreCase("c"))
            this.sCustomerType = "College";
}
public String getCustomerType(){
    return this.sCustomerType;
}
public String getInvoice(){
    NumberFormat currency = NumberFormat.getCurrencyInstance();
    NumberFormat percent = NumberFormat.getPercentInstance();
    sCustomerType = this.getCustomerType();
    discountPercent = this.getDiscountPercent();
    discountAmount = this.getDiscountAmount();
    invoiceTotal = this.getInvoiceTotal();
    // Create a string representation of the full invoice and return
    String invoice = ("Subtotal:         " + currency.format(subtotal) + "\n"
                   + "Customer type:    " + sCustomerType + "\n"
                   + "Discount percent: " + percent.format(discountPercent)+ "\n"
                   + "Discount amount:  " + currency.format(discountAmount)+ "\n"
                   + "Total:            " + currency.format(invoiceTotal) + "\n");
    return invoice;
}
}

我已经成功了,谢谢你们!现在我对 set 和 get 方法以及 this. 有了更多的了解。关键词。 这是工作发票类:

    import java.text.NumberFormat;

public class Invoice {
private final String customerType;
private double subtotal;
private double discountAmount;
private double discountPercent;
private double invoiceTotal;
private String sCustomerType;

public Invoice(String customerType, double subtotal){
    this.customerType = customerType;
    this.subtotal = subtotal;
}
public void setSubtotal(double subtotal){
    this.subtotal = subtotal;
}
public double getSubtotal(){
    return subtotal;
}
public void setDiscountPercent(double discountPercent){
    this.discountPercent = discountPercent;
}
public double getDiscountPercent(){
    if (customerType.equalsIgnoreCase("r"))
    {
        if (subtotal >= 500)
            discountPercent = .2;
        else if (subtotal >= 250 && subtotal < 500)
            discountPercent =.15;
        else if (subtotal >= 100 && subtotal < 250)
            discountPercent =.1;
        else if (subtotal < 100)
            discountPercent =.0;
    }
    else if (customerType.equalsIgnoreCase("c"))
    {
            discountPercent = .2;
    }
    else
    {
        discountPercent = .05;
    }
    return discountPercent;
}
public void setDiscountAmount(double discountAmount){
    this.discountAmount = discountAmount;
}
public double getDiscountAmount(){
    discountAmount = subtotal * (getDiscountPercent());
    return discountAmount;
}
public void setInvoiceTotal(double invoiceTotal){
    this.invoiceTotal = invoiceTotal;
}
public double getInvoiceTotal(){
    invoiceTotal = subtotal - (getDiscountAmount());
    return invoiceTotal;
}
public void setCustomerType(String sCustomerType){
    this.sCustomerType = sCustomerType;
}
public String getCustomerType(){
    sCustomerType = "Unknown";
        if (customerType.equalsIgnoreCase("r"))
            sCustomerType = "Retail";
        else if (customerType.equalsIgnoreCase("c"))
            sCustomerType = "College";
    return sCustomerType;
}
public String getInvoice(){
    NumberFormat currency = NumberFormat.getCurrencyInstance();
    NumberFormat percent = NumberFormat.getPercentInstance();
    // Create a string representation of the full invoice and return
    String invoice = ("Subtotal:         " + currency.format(getSubtotal()) + "\n"
                   + "Customer type:    " + getCustomerType() + "\n"
                   + "Discount percent: " + percent.format(getDiscountPercent())+ "\n"
                   + "Discount amount:  " + currency.format(getDiscountAmount())+ "\n"
                   + "Total:            " + currency.format(getInvoiceTotal()) + "\n");
    return invoice;
}
}

再次感谢!

最佳答案

您在代码中的多个位置隐藏了带有方法参数的字段,例如:

public void setDiscountPercent(double discountPercent){
    ...
        if (subtotal >= 500)
            discountPercent = .2;
    ...

请注意,您有一个名为 discountPercent 的字段和一个名为 discountPercent 的方法参数。在那里修改的是参数变量,而不是字段。使用this,例如:

public void setDiscountPercent(double discountPercent){
    ...
        if (subtotal >= 500)
            this.discountPercent = .2;
    ...

或者重命名您的方法参数,以免与字段冲突。

你必须仔细检查你的代码并找到这些,它发生在几个地方,例如这是 setDiscountAmount() 中的另一个:

public void setDiscountAmount(double discountAmount){
    discountAmount = subtotal * (getDiscountPercent());
}

应该是:

public void setDiscountAmount(double discountAmount){
    this.discountAmount = subtotal * (getDiscountPercent());
}

此外,由于您实际上似乎并未在任何地方的方法中使用这些参数,因此 a) 您不应该传递它们,或者 b) 您本想以某种方式使用它们,但您没有。

此外,正如 MrTi 在评论中指出的那样,您似乎也没有在任何地方调用 setter。您正在(尝试)初始化 Invoice 构造函数中的一些值,但您并没有真正完成那里的工作。

正如 Erwin Bolwidt 在评论中指出的那样,一般来说,您似乎对“getters”和“setters”的概念感到困惑。特别是,您的 setter 并不是真正的“ setter ” - 而且看起来您实际上根本不需要它们,因为您的意图似乎是简单地计算构造函数中的所有值,然后稍后检索它们(例如,您可以只拥有 getter,并在 getter 或构造函数中执行计算)。查看this question有关该主题的一些好的答案和链接。通读一遍,它应该能让您更好地掌握您想要实现的目标。

关于Java 方法返回错误值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22725499/

相关文章:

java - Hibernate 延迟加载、代理和继承

java - 在我的小程序中使用 webrenderer 时出现错误

java - PreparedStatement

java - 依赖注入(inject)和测试

javascript - 如何使用 AJAX 将变量值发送到 java servlet? (没有 jQuery)

java - 静态方法的多态性

java - ManyToMany Relation 正在更新域表

java - 如何从队列中获取所有现有消息并停止消费者

java - 使用其名称调用文本字段对象并设置一些属性

java - 为什么我总是收到空指针异常?