7

对 Java 非常陌生,所以我现在感觉自己像个孩子。我猜是学习一门新语言的乐趣。

这是我的发票类:

public class Invoice {
//member inits
private int numberOfInvoices = 0;
private String companyName;
private double amountDue;
private String chargeDate;
private static int invoiceNumber = 0;


//constructor
public Invoice(String _companyName, double _amountDue, String _chargeDate)
{
    numberOfInvoices++;
    companyName = _companyName;
    amountDue = _amountDue;
    chargeDate = _chargeDate;
    invoiceNumber = numberOfInvoices;
}

//getters
public String getCompanyName()
{
    return companyName;
}

public double getAmountDue()
{
    return amountDue;
}

public String getChargeDate()
{
    return chargeDate;
}

public int getInvoiceNumber()
{
    invoiceNumber = numberOfInvoices + 1;
    return invoiceNumber;
}

//setters
public void setCompanyName(String _companyName)
{
    companyName = _companyName;
}

public void setAmountDue(double _amountDue)
{
    amountDue = _amountDue;
}

public void setChargeDate(String _chargeDate)
{
    chargeDate = _chargeDate;
}
//helpers
public int incrementInvoices()
{
    return numberOfInvoices++;
}
}

这是我尝试创建其中三张发票的主要方法,但每次创建新发票时都会增加发票编号。

public class InvoiceCreator {

/**
 * @param args the command line arguments
 */
public static void main(String[] args) {
    Invoice invoice1 = new Invoice("Amazing Software", 5000.00, "January 18, 2009");
    System.out.println(invoice1);

    Invoice invoice2 = new Invoice("Best Programs", 4000.00, "February 18, 2009");
    System.out.println(invoice2);

    Invoice invoice3 = new Invoice("Champion Code", 3000.00, "March 18, 2009");
    System.out.println(invoice3);
}
}

我也是 IDE(netbeans)的新手,但是通过调试和查看我创建的每个类,所有字段都被正确初始化,但其中的 invoiceNumber = 1。

我在这里做错了什么?

4

9 回答 9

7

您需要使用静态字段来生成增量发票编号,而不是存储单个发票编号。

尝试这个:

public class Invoice {
//member inits
private static int nextInvoiceNumber = 0;
private String companyName;
private double amountDue;
private String chargeDate;
private int invoiceNumber = 0;


//constructor
public Invoice(String _companyName, double _amountDue, String _chargeDate)
{
    invoiceNumber = nextInvoiceNumber;
    nextInvoiceNumber++;
    companyName = _companyName;
    amountDue = _amountDue;
    chargeDate = _chargeDate;

}
....
于 2013-05-23T14:34:01.750 回答
2

将 numberOfInvoices 声明为static,以便整个类只有一个值,而不是每个实例都有一个单独的值。

 private static int numberOfInvoices = 0;
于 2013-05-23T14:32:43.150 回答
1

您声明invoiceNumber为静态,但numberOfInvoices不是静态的。在您的构造函数中,您正在增加发票的数量——它是非静态的,每次创建它的实例时都会初始化为 0。然后将此值分配给您的发票编号。

您的情况的简单解决方法是将其声明numberOfInvoices为静态和invoiceNumber非静态:

private static int numberOfInvoices = 0;
private int invoiceNumber;

然后你会得到想要的行为。

同时,值得注意的是,这个实现对于学习语言来说是可以的,但是它不适用于生产系统,因为当应用程序退出并重新启动时,数字仍然会重置为 0。在生产系统中,您可能希望将此编号保存在某个数据库或外部文件中。然后,您需要确保它以线程安全的方式递增。在生产系统中,您的逻辑将是这样的:

private int invoiceNumber;
private Object sync;

public Invoice(...) {
    synchronised(sync) {
        invoiceNumber = loadLastInvoiceNumberFromStorage();
        invoiceNumber++;
        writeLastInvoiceNumberFromStorage(invoiceNumber);
    }

    ...
}
于 2013-05-23T14:36:42.030 回答
1

numberOfInvoices应该是静态的。invoiceNumber不应该是静态的。并且您应该同步对该字段的访问。另请参阅:增加锁数量的最佳方法是什么?

于 2013-05-23T14:36:48.343 回答
0

numberOfInvoices不是静态成员。

您当前递增一个实例属性并将其设置为静态属性。

我怀疑你想要相反的。

于 2013-05-23T14:32:50.853 回答
0

您可以在类中使用静态字段numberOfInvoices,并在构造函数中递增它。然后,您可以为该字段设置一个静态吸气剂。

于 2013-05-23T14:33:04.093 回答
0

创建新对象时,numberOfInvoices 将始终为 0。因此,每次增加它并将其分配给 invoiceNumber 时, invoiceNumber 的值都会为 1。相反,为什么不直接增加 invoiceNumber 。

于 2013-05-23T14:33:23.537 回答
0

利用

private static int numberOfInvoices = 0;

原因:

静态变量与类相关,而非静态变量与对象相关。在这种情况下,您正在存储类对象的计数,因此这与类有关。因此,您必须将其存储为静态变量(也称为类变量)

有关更多详细信息,请参见此处

于 2013-05-23T14:33:42.143 回答
0

您应该将 numberOfInvoices 成员声明为静态成员:

private static int numberOfInvoices = 0;

这样所有 Invoice 实例都将共享该成员。如果您不声明它,每个 Invoice 实例都会有自己的值。

于 2013-05-23T14:33:50.883 回答