2010-02-06 3 views
6

Я новичок в java. Я пишу класс, где конструктор должен проверить параметр цены и убедиться, что это не отрицательное число. И если он отрицательный, он должен установить цену на ноль. Когда я проверяю цену, я получаю ошибку stackoverflow. Могу ли я получить помощь от того, что я сделал неправильно?ошибка stackoverflow в java

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; 
     } 

    } 
} 
+4

+1 для self-referential stackoverflow на stackoverflow! – trashgod

+0

теперь некоторые могут понять, что означает название сайта ... – 2010-02-06 12:05:15

+0

Итак, мета! Интересно, пришел ли он сюда по поиску в Google для «stackoverflow».:-) – ibz

ответ

14

Ваш метод getprice() называет себя вместо проверки price. В этом случае это приводит к бесконечной рекурсии.

+1

+1 и прокомментировать ответ Игнасио: современные IDE заметят бесконечную рекурсию и предупредит вас об этом в реальном времени (я использую IntelliJ, и он предупреждает вас об ошибках, я уверен, что другие IDE делают то же самое). – SyntaxT3rr0r

+1

вы также можете переписать его следующим образом: if (price <0) {return 0; } возвратная цена; Другого не нужно. – Woot4Moo

+3

Если вы хотите получить * ДЕЙСТВИТЕЛЬНО * придирчивый, вы можете написать его как 'return Math.max (price, 0);'. –

1

Игнасио объяснил причину и решение:

Изменение линии

if(getprice() < 0) 

к этому:

if(price < 0) 
1

Ваше получение бесконечной рекурсии, потому что ваш if условие проверяет getprice() метод, а не переменную price.

Многие современные компиляторы предупреждают вас, когда вы закодировали что-то, что приводит к бесконечной рекурсии.

Я до сих пор иногда сталкиваюсь с этой ошибкой, особенно с IDE, которые имеют intellisense.

Удачи в изучении Java! :)

1

Когда вы пишете фасоль, вы обычно хотите проверить, установлена ​​ли цена < 0, вместо того, чтобы делать это вычисление каждый раз, когда вы пытаетесь получить переменную.

+1

Новичкам может быть трудно понять концепцию «bean»;) –

1

Не проблема cure для проблемы рекурсии, но вы также должны рассмотреть возможность проверки цены во время строительства.
Иногда (чаще?) Лучше, чтобы ваш конструктор сменил с Исключением, вместо того чтобы разрешить конструкцию несогласованного объекта. Таким образом, легче локализовать такую ​​ошибку.
Пример:

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

Риск заключается в том, что ваше приложение может произойти сбой при в производственной среде, которая может быть беспорядок. Чтобы этого избежать, вы можете использовать assert или, по крайней мере, выдавать или регистрировать ошибку и использовать какую-либо альтернативу. Проверка assert должна быть включена для разработки и может быть отключена при производстве. Подробно см Programming With Assertions

public Book(String bookTitle, String bookAuthor, String bookCode, int bookPages, boolean paperback, double bookRetail) 
{ 
    assert bookRetail >= 0.0 : bookRetail; 
    ... 
} 

или

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(); 
    } 
    ... 
} 
+0

Просто убедитесь, что при реализации шаблона IDisposable/Finalizer он может обрабатывать частично сконструированный объект. – TToni

+0

@TToni; почему частично построенный объект? Я просто рассматриваю возможность проверки значения во время построения, а не при доступе к полю. Объект будет полностью построен или вообще не будет объекта (в случае выброса исключения). –

+0

Представьте себе, например, объект, который открывает два дескриптора файла в своем конструкторе. Исключением в конструкторе может не быть, один или два файла будут открыты. Поэтому, если возникает исключение конструктора, среда выполнения вызывает ваш финализатор (если он у вас есть), который должен иметь дело с этой ситуацией. – TToni

0

Ваш getprice нужно просто записать в виде:

return price < 0 ? 0 : price; 

Btw, приятно видеть, что ошибка StackOverflow решается

stackoverflow.com
+1

'reurn' не является допустимым ключевым словом Java ... –

+0

Исправлено, спасибо. – fastcodejava

Смежные вопросы