2010-02-06 9 views
6

Ich bin ein Neuling in Java. Ich schreibe eine Klasse, in der der Konstruktor den Preisparameter überprüfen und sicherstellen muss, dass es keine negative Zahl ist. Und wenn es negativ ist, muss es den Preis auf Null setzen. Ich bekomme einen Stackoverflow-Fehler, wenn ich den Preis überprüfe. Kann ich Hilfe bekommen mit dem, was ich falsch gemacht habe?stackoverflow Fehler in 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 für selbstreferentiellen Stackoverflow auf Stackoverflow! – trashgod

+0

jetzt vielleicht einige erkennen, was der Name der Website bedeutet ... –

+0

So meta! Ich frage mich, ob er hierher gekommen ist, indem er nach "stackoverflow" gegoogelt hat.:-) – ibz

Antwort

14

Ihre getprice() Methode nennt sich stattdessen price zu prüfen. Dies führt in diesem Fall zu einer unendlichen Rekursion.

+1

+1, und um Ignacios Antwort zu kommentieren: Moderne IDEs werden die unendliche Rekursion bemerken und dich davor in Echtzeit warnen (Ich benutze IntelliJ und warnt dich vor solchen Fehlern, ich bin sicher, dass andere IDEs dasselbe tun). – SyntaxT3rr0r

+1

könnte man es auch so umschreiben: if (price <0) {return 0; } Rückgabepreis; Das Else wird nicht benötigt. – Woot4Moo

+3

Wenn du * WIRKLICH * wählerisch werden willst, könntest du es als 'return Math.max (price, 0);'. –

1

Ignacio hat erklärt, die Ursache und die Lösung:

Ändern Sie die Zeile

if(getprice() < 0) 

dazu:

if(price < 0) 
1

Ihr immer eine unendliche Rekursion, weil Ihr if Zustand Ihrer getprice() prüft Methode, nicht Ihre price Variable.

Viele moderne Compiler warnen Sie, wenn Sie etwas codiert haben, das zu einer unendlichen Rekursion führt.

Ich bin immer noch manchmal auf diesen Fehler, vor allem mit IDEs, die Intellisense haben.

Viel Glück beim Lernen von Java! :)

1

Wenn Sie eine Bean schreiben, möchten Sie im Allgemeinen überprüfen, ob der Preis < 0 ist, anstatt diese Berechnung jedes Mal vorzunehmen, wenn Sie versuchen, die Variable zu erhalten.

+1

Ein Neuling könnte Schwierigkeiten haben, das 'Bean' Konzept zu verstehen;) –

1

Nicht ein Heilung für das Rekursionsproblem, aber Sie sollten auch in Betracht ziehen, den Preis zur Bauzeit zu überprüfen.
Manchmal (am häufigsten?) Ist es besser, dass Ihr Konstruktor mit einer Ausnahme fehlschlägt, anstatt die Konstruktion eines inkonsistenten Objekts zuzulassen. Auf diese Weise ist es einfacher, einen solchen Fehler zu lokalisieren.
Beispiel:

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

Das Risiko besteht darin, dass Ihre Anwendung, wenn in der Produktionsumgebung scheitern kann, was für ein Chaos sein kann. Um dies zu vermeiden, können Sie einen assert verwenden oder zumindest den Fehler ausgeben oder protokollieren und eine Alternative verwenden. Die Prüfung assert muss für die Entwicklung aktiviert und möglicherweise bei der Produktion deaktiviert werden. siehe Details Programming With Assertions

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

oder

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

Stellen Sie nur sicher, dass wenn Sie ein IDisposable/Finalizer-Muster implementieren, kann es ein teilweise konstruiertes Objekt behandeln. – TToni

+0

@TToni; Warum teilweise konstruiertes Objekt? Ich überlege gerade, den Wert zur Bauzeit zu überprüfen, anstatt auf das Feld zuzugreifen. Das Objekt wird vollständig konstruiert sein oder es wird überhaupt kein Objekt geben (falls eine Ausnahme ausgelöst wird). –

+0

Stellen Sie sich zum Beispiel ein Objekt vor, das zwei Dateihandles in seinem Konstruktor öffnet. Eine Ausnahme im Konstruktor kann keine, eine oder zwei Dateien offen lassen. Wenn also eine Konstruktor-Exception auftritt, ruft die Runtime Ihren Finalizer auf (falls Sie einen haben), der sich mit dieser Situation befassen muss. – TToni

0

Ihre getprice sollte einfach geschrieben werden als:

return price < 0 ? 0 : price; 

Btw, schön zu sehen, dass ein Fehler von Stackoverflow stackoverflow.com gelöst

+1

'reurn' ist kein gültiges Java-Schlüsselwort ... –

+0

Korrigiert, danke. – fastcodejava