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