java中的堆栈溢出错误

java中的堆栈溢出错误,java,Java,我是java的新手。我正在编写一个类,其中构造函数必须检查price参数并确保它不是负数。如果是负值,它必须将价格设置为零。当我检查价格时,会出现堆栈溢出错误。我做错了什么能得到帮助吗 public class Book { private String title; private String author; private String isbn; private int pages; private boolean pback; priva

我是java的新手。我正在编写一个类,其中构造函数必须检查price参数并确保它不是负数。如果是负值,它必须将价格设置为零。当我检查价格时,会出现堆栈溢出错误。我做错了什么能得到帮助吗

public class Book
{
    private String title;
    private String author;
    private String isbn;
    private int pages;
    private boolean pback;
    private double price;

    /**
     * Constructor for objects of class Book
     */
    public Book(String bookTitle, String bookAuthor, String bookCode, int bookPages, boolean paperback, double bookRetail)
    {
        title = bookTitle;
        author = bookAuthor;
        isbn = bookCode;
        pages = bookPages;
        pback = paperback;
        price = bookRetail;
    }

    /**
     * @returns title
     */

    public String gettitle()
    {
        return title;
    }

   /**
    * @returns author
    */

    public String getauthor()
    {
        return author;
    }

   /**
    * @returns ISBN#
    */

   public String getisbn()
    {
        return isbn; 
    }

   /**
    * @return number of pages
    */ 

   public int getpages()
    {
        return pages;
    }

   /**
    * @return is book paperback
    */ 

   public boolean getpback()
    {
        return pback;
    }

   /**
    * @return retail price
    */ 

   public double getprice() 
   {
       if(getprice() < 0)
       {
           return 0;
       } 
       else
       {
           return price;
       }

    }
}
公共课堂教材
{
私有字符串标题;
私有字符串作者;
专用字符串isbn;
私人网页;
专用布尔pback;
私人双价;
/**
*类Book对象的构造函数
*/
公共图书(String bookTitle、String bookAuthor、String bookCode、int bookPages、布尔平装书、double bookRetail)
{
书名=书名;
作者=书籍作者;
isbn=图书编码;
页数=书页;
pback=平装本;
价格=书籍零售;
}
/**
*@返回标题
*/
公共字符串gettitle()
{
返回标题;
}
/**
*@returns作者
*/
公共字符串getauthor()
{
返回作者;
}
/**
*@ISBN#
*/
公共字符串getisbn()
{
返回isbn;
}
/**
*@返回页数
*/ 
公共int getpages()
{
返回页面;
}
/**
*@return是一本平装书
*/ 
公共布尔getpback()
{
返回pback;
}
/**
*@退货零售价
*/ 
公开双价
{
if(getprice()<0)
{
返回0;
} 
其他的
{
退货价格;
}
}
}

您的
getprice()
方法调用自身,而不是检查
price
。在这种情况下,这将导致无限递归。

Ignacio解释了原因和解决方案:

换线

if(getprice() < 0)
if(getprice()<0)
为此:

if(price < 0)
if(价格<0)

你得到无限递归,因为你的
if
条件检查你的
getprice()
方法,而不是你的
price
变量

当您编写了导致无限递归的代码时,许多现代编译器都会发出警告

我有时也会遇到这个错误,尤其是对于具有intellisense的IDE


祝你学习Java好运!:)

> P>当你写一个bean时,通常要检查所设置的价格是否为0,而不是每次尝试获取变量时进行计算。

< P>不是递归问题的解决方法,但是你也应该考虑在建设时检查价格。 有时(大多数情况下?)最好是构造函数出现异常而失败,而不是允许构造不一致的对象。这样更容易定位此类错误。
例如:

public Book(String bookTitle, String bookAuthor, String bookCode, int bookPages, boolean paperback, double bookRetail)
{
    if (bookRetail < 0.0)
        throw new IllegalArgumentException("negative bookRetail: " + bookRetail);
    ...
}


您的
getprice
应该简单地写为:

return price < 0 ? 0 : price;
退货价格<0?0:价格;

顺便说一句,很高兴看到stackoverflow.com解决了stackoverflow错误,并评论了Ignacio的回答:现代IDE会注意到无限递归并实时警告您(我使用IntelliJ,它会警告您此类错误,我相信其他IDE也会这样做)。您也可以这样重写:if(price<0){return 0;}return price;不需要else。如果您想变得非常挑剔,可以将其写成
return Math.max(price,0)
@wizardofods:Findbugs在这方面也很好,它为几个大型IDE提供了插件。+1用于stackoverflow上的自参考stackoverflow!现在一些人可能意识到该站点的名称意味着什么……太好了!我想知道他是不是通过谷歌搜索“stackoverflow”来这里的.:-)新手可能难以理解“bean”的概念;)只要确保在实现IDisposable/Finalizer模式时,它可以处理部分构造的对象。@TToni;为什么是部分构造的对象?我只是考虑在构造时检查值,而不是在访问字段时。object将被完全构造,或者根本没有对象(在引发异常的情况下)。例如,想象一个对象在其构造函数中打开两个文件句柄。构造函数中的异常可能会使任何文件、一个或两个文件处于打开状态。因此,如果发生构造函数异常,运行时将调用终结器(如果有)它必须处理这种情况。@TToni:Imagine?filehandles(在Java中)?问题是关于一个简单的对象(一本书)只包含一些值。无论如何,这就是在做任何其他事情之前首先检查参数的原因(…)。并且,在您的示例中,在引发异常时关闭任何最终打开的文件会更好/更安全。当然,它不适用于简单示例。这就是为什么我将原始注释限制为实现IDisposable/Finalizer的类。如果您在构造函数中引发异常,运行时将调用终结器(至少在C#)中是这样的,所以你必须处理潜在的未完成构造函数。你知道如果其中一个抛出异常,虚拟构造函数链会发生什么吗?我必须查找它。所以我要说的是:小心,特别是当你的类处理非托管资源时。
public Book(String bookTitle, String bookAuthor, String bookCode, int bookPages, boolean paperback, double bookRetail)
{
    if (bookRetail >= 0.0) {
        price = bookRetail;
    } else {
        price = 0.0;
        // display or log the "illegal argument"
        Exception ex = new IllegalArgumentException("negative bookRetail: " + bookRetail);
        ex.printStackTrace();
    }
    ...
}
return price < 0 ? 0 : price;