2010-02-06 19 views
6

Soy un novato en Java. Estoy escribiendo una clase donde el constructor debe verificar el parámetro de precio y asegurarse de que no sea un número negativo. Y si es negativo, debe establecer el precio en cero. Obtengo un error de stackoverflow cuando miro el precio. ¿Puedo obtener ayuda con lo que hice mal?error stackoverflow en 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 para stackoverflow autorreferencial en stackoverflow! – trashgod

+0

ahora algunos podrían darse cuenta de lo que significa el nombre del sitio ... –

+0

Así que meta! Me pregunto si llegó aquí buscando en Google "stackoverflow".:-) – ibz

Respuesta

14

Su método getprice() llama a sí mismo en lugar de comprobar price. Esto está llevando a una recursión infinita en este caso.

+1

+1, y para comentar la respuesta de Ignacio: los IDE modernos notarán la recursividad infinita y lo advertirán al respecto en tiempo real (yo uso IntelliJ y esto lo advierte sobre esos errores, estoy seguro de que otros IDEs hacen lo mismo) – SyntaxT3rr0r

+1

también podría reescribirlo así: if (price <0) {return 0; } precio de retorno; El otro no es necesario. – Woot4Moo

+3

Si quisiera obtener * REALMENTE * exigente, podría escribirlo como 'return Math.max (price, 0);'. –

1

Ignacio ha explicado la causa y la solución:

Cambie la línea

if(getprice() < 0) 

a esto:

if(price < 0) 
1

Su conseguir una recursión infinita, porque su condición if comprueba su getprice() método, no su variable price.

Muchos compiladores modernos le advertirán cuando haya codificado algo que dé como resultado recursión infinita.

A veces me cruzo con este error también, especialmente con los IDE que tienen intellisense.

¡Buena suerte aprendiendo Java! :)

1

Cuando escribe un bean, generalmente quiere comprobar si el precio establecido es < 0, en lugar de hacer este cálculo cada vez que intenta obtener la variable.

+1

Un novato puede tener dificultades para entender el concepto 'bean';) –

1

No es cure para el problema de recursión, pero también debería considerar verificar el precio en el momento de la construcción.
A veces (¿la mayoría de las veces?) Es mejor que su constructor falle con una excepción en lugar de permitir la construcción de un objeto incoherente. De esta forma, es más fácil localizar dicho error.
Ejemplo:

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

El riesgo es que su aplicación puede fallar cuando en el entorno de producción, que puede ser un desastre. Para evitar esto, puede usar un assert o, al menos, dar o registrar el error y usar alguna alternativa. La comprobación assert se debe activar para el desarrollo y se puede desactivar en producción. Para más detalles véase 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

Solo asegúrese de que cuando implemente un patrón IDisposable/Finalizer, puede manejar un objeto parcialmente construido. – TToni

+0

@TToni; ¿por qué objeto parcialmente construido? Solo estoy considerando verificar el valor en el momento de la construcción en lugar de al acceder al campo. El objeto estará completamente construido o no habrá ningún objeto en absoluto (en caso de arrojar una excepción). –

+0

Imagine, por ejemplo, un objeto que abre dos manejadores de archivos en su constructor. Una excepción en el constructor puede dejar ninguno, uno o dos archivos abiertos. Entonces, si ocurre una excepción de constructor, el tiempo de ejecución llama a su finalizador (si tiene uno) que tiene que lidiar con esta situación. – TToni

0

Su getprice simplemente debe escribirse como:

return price < 0 ? 0 : price; 

Por cierto, bonito ver que un error de stackoverflow se resuelve por stackoverflow.com

+1

'reurn' no es una palabra clave válida de Java ... –

+0

Corregido, gracias. – fastcodejava