i0h3 i0h3 - 1 month ago 9
Java Question

What problems occur when creating static object fields?

import java.util.Scanner;

public class CreatePurchase {

public static Purchase item;
public static Scanner details;

public static void main(String[] args) {
details = new Scanner(System.in);
item = new Purchase ();

int invoice = details.nextInt();
boolean invoiceRange = ((invoice >= 1000) && (invoice <= 8000));
while (!invoiceRange)
{
invoice = details.nextInt();
}

Item.setInvoice(invoice);

double sale = details.nextDouble();
if (sale >= 0)
{
item.setSale(sale);
}
item.display();
}
}


No syntax or semantic errors appear when running this code. If you input the correct values for
invoice
and
sale
, it runs with no issues. The issue I am facing seems to be logical and I don't really understand why. After passing the first loop cycle, it keeps requesting that I input values as if it doesn't go through the checking phase anymore, which causes an infinite loop.

I don't think the Boolean logic is wrong because it works when providing the right values, but I thought I should ask here before assuming anything.

I think it has something to do with me declaring my objects as static fields. I wanted to make the
Purchase
class a part of the
CreatePurchase
class, by making it a field. Java wouldn't allow me to access it without creating an instance of the
CreatePurchase
class, which I think is recursive and would cause a stack overflow. Making them static worked, but I think the fields either stop receiving values after the first input, or the Boolean logic is just faulty.

This question comes from the same assignment that the question Java use of static fields is based on.

Answer

You should use a do-while loop here:

int invoice;
do {
    invoice = details.nextInt();
} while (invoice < 1000 || invoice > 8000);

This will repeatedly ask for an invoice value from the user until it is within the accepted range. Your code does not work because you only set the value of invoiceRange after reading in the first value given by the user, so if that value is outside of the given range, then the loop will run infinitely.

This could also be done with the addition of one line to your while loop:

int invoice = details.nextInt();
boolean invoiceRange = ((invoice >= 1000) && (invoice <= 8000));
while (!invoiceRange)
{
    invoice = details.nextInt();
    // Need this line to update the value of invoiceRange every
    // time a new invoice value is read in
    invoiceRange = ((invoice >= 1000) && (invoice <= 8000));
}

However, a do-while is preferable in the case where you want to do something (read in an invoice value from the user) before checking if you need to keep doing that action (check if invoice value is within accepted range).

One final note: Since you are only using item and details in your main method, it would be better if you declared and initialized them within the method. This makes the code more readable and helps you keep track of where changes to variables are occurring, which makes it easier to identify the cause of issues.

Comments