2010-02-06 16 views
6

Sono un novizio in java. Sto scrivendo una classe in cui il costruttore deve controllare il parametro del prezzo e assicurarsi che non sia un numero negativo. E se è negativo, deve impostare il prezzo a zero. Ottengo un errore StackOverflow quando controllo il prezzo. Posso avere aiuto con quello che ho fatto di sbagliato?errore stackoverflow 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 per stackoverflow autoreferenziale su stackoverflow! – trashgod

+0

ora alcuni potrebbero capire che cosa significa il nome del sito ... –

+0

Quindi meta! Mi chiedo se sia arrivato qui googling per "stackoverflow".:-) – ibz

risposta

14

Il tuo metodo getprice() si definisce invece di controllare price. Questo sta portando a una ricorsione infinita in questo caso.

+1

+1, e per commentare la risposta di Ignacio: gli IDE moderni noteranno la ricorsione infinita e ti avvertiranno in tempo reale (io uso IntelliJ e ti avvisa di tali errori, sono sicuro che altri IDE fanno lo stesso). – SyntaxT3rr0r

+1

potresti anche riscriverlo in questo modo: if (price <0) {return 0; } prezzo di ritorno; Il resto non è necessario. – Woot4Moo

+3

Se si desidera ottenere * VERAMENTE * schizzinoso, è possibile scriverlo come 'return Math.max (price, 0);'. –

1

Ignacio ha spiegato la causa e la soluzione:

Modificare la linea

if(getprice() < 0) 

a questo:

if(price < 0) 
1

vostro ottenere ricorsione infinita, perché la sua condizione if controlla il vostro getprice() metodo, non la tua variabile price.

Molti compilatori moderni ti avviseranno quando hai codificato qualcosa che si traduce in ricorsione infinita.

Ancora a volte mi imbatto anche in questo errore, specialmente con IDE che hanno intellisense.

Buona fortuna per imparare Java! :)

1

Quando si scrive un bean in genere si desidera verificare se il prezzo impostato è < 0, invece di effettuare questo calcolo ogni volta che si tenta di ottenere la variabile.

+1

Un principiante potrebbe avere difficoltà a comprendere il concetto di 'bean';) –

1

Non è un cure per il problema di ricorsione, ma si dovrebbe anche considerare di controllare il prezzo al momento della costruzione.
A volte (la maggior parte delle volte?) È meglio che il costruttore non riesca a eseguire con un'eccezione anziché consentire la costruzione di un oggetto incoerente. In questo modo è più facile localizzare un tale errore.
Esempio:

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

Il rischio è che l'applicazione può riuscire quando nell'ambiente di produzione, che può essere un pasticcio. Per evitare questo, è possibile utilizzare uno assert o, almeno, dare o registrare l'errore e utilizzare qualche alternativa. Il controllo assert deve essere attivato per lo sviluppo e può essere disattivato in fase di produzione. Per i dettagli vedi Programming With Assertions

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

o

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

Assicurati che quando stai implementando un pattern IDisposable/Finalizer, possa gestire un oggetto parzialmente costruito. – TToni

+0

@TToni; perché oggetto parzialmente costruito? Sto solo considerando di controllare il valore in fase di costruzione invece di accedere al campo. L'oggetto sarà completamente costruito o non ci sarà alcun oggetto (in caso di lancio di un'eccezione). –

+0

Immaginate per esempio un oggetto che apre due filehandle nel suo costruttore. Un'eccezione nel costruttore potrebbe non lasciare nessuno, uno o due file aperti. Quindi, se si verifica un'eccezione costruttore, il runtime chiama il finalizzatore (se ne hai uno) che deve gestire questa situazione. – TToni

0

tuo getprice dovrebbe semplicemente essere scritto come:

return price < 0 ? 0 : price; 

Btw, bello vedere che un errore di StackOverflow è risolto stackoverflow.com

+1

'reurn' non è una parola chiave Java valida ... –

+0

Corretta, grazie. – fastcodejava

Problemi correlati