2016-10-26 5 views
-1
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(); 
    } 
} 

이 코드를 실행할 때 구문이나 의미 오류가 나타나지 않습니다. invoicesale에 올바른 값을 입력하면 문제없이 실행됩니다. 내가 직면하고있는 문제는 논리적 인 것으로 보이며 그 이유를 정말로 이해하지 못합니다. 첫 번째 루프 사이클을 통과 한 후에도 계속해서 확인 단계를 거치지 않는 것처럼 입력 값을 입력하도록 요청하므로 무한 루프가 발생합니다.정적 개체 필드를 만들 때 어떤 문제가 발생합니까?

올바른 값을 제공 할 때 작동하기 때문에 부울 논리가 잘못되었다고 생각하지 않지만 무엇보다 먼저 가정해야한다고 생각했습니다.

내 개체를 정적 필드로 선언하는 것과 관련이 있다고 생각합니다. 나는 필드를 만들어 Purchase 클래스를 CreatePurchase 클래스의 일부로 만들고 싶습니다. Java는 CreatePurchase 클래스의 인스턴스를 만들지 않고 액세스 할 수 없도록되어 있습니다.이 클래스는 재귀 적이기 때문에 스택 오버플로가 발생합니다. 그 (것)들을 정체시키는, 그러나 나는 분야가 첫번째 입력 후에 가치를받는 중지하거나, 부울 논리가 다만 faulty다는 것을 생각한다.

이 질문은 Java use of static fields 질문의 대답과 동일한 질문에서 비롯된 것입니다.

+2

부울 조건'(! invoceRange)'는 루프에서 변경되지 않으므로 무한하게됩니다. –

+1

질문 제목은 오해의 소지가 있습니다. - 물체도 정적이거나 인스턴스가 아닙니다. 간단히 * are *입니다. *** 변수 ***은 정적으로 선언되거나 static으로 선언 될 수 있습니다 (소위 * 인스턴스 * 변수). 동일한 객체는 정적 필드와 인스턴스 필드에서 모두 참조 할 수 있습니다. –

+1

'main' 메소드에서만 접근 할 수 있다면, 정적 인 필드로 객체를 만드는 것은별로 중요하지 않습니다. – 4castle

답변

0

를 사용하여 루프를 중단해야합니다

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

이 반복 송장 값을 요청합니다 허용 된 범위 내에있을 때까지 사용자로부터. 사용자가 지정한 첫 번째 값을 읽은 후에 invoiceRange 값만 설정하므로 코드가 작동하지 않습니다. 따라서 해당 값이 주어진 범위를 벗어나면 루프가 무한히 실행됩니다.

은 또한 당신의 while 루프에 한 줄을 추가하여 수행 할 수 있습니다 :

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

그러나, DO-동안 당신이 뭔가를 할 경우에 바람직하다 (송장 값 읽기 사용자가 해당 작업을 계속 수행해야하는지 확인하기 전에 (송장 값이 허용 범위 내에 있는지 확인하십시오).

마지막주의 사항 : main 메서드에서 itemdetails 만 사용하고 있으므로 메서드에서 선언하고 초기화하면 더 좋을 것입니다. 이렇게하면 코드를보다 쉽게 ​​읽을 수 있으며 변수의 변경 사항을 추적 할 수 있으므로 문제의 원인을 쉽게 식별 할 수 있습니다.

+0

제안 해 주셔서 감사합니다. Java에 익숙하지 않기 때문에 부울 논리를 변경하면 도움이되는지 확인하지 않고도 Java의 고유 한 유형 시스템을 조사했습니다. 정적 참조가 괜찮습니까? 정적 키워드가 어떻게 작동하는지 생각하면 가능성은 희박합니다. – i0h3

+0

@ i0h3 예 정적 참조는 프로그램이 올바르게 실행되는 것을 방해하지 않는다는 점에서 좋습니다. 그러나 필자가 대답 한 것처럼 static 클래스 필드를 사용하지 않고 대신 main 메소드에서 선언하는 것이 낫습니다. – mapeters

0

invoiceRange는 잠시 동안 업데이트되지 않으므로 항상 동일한 값을 포함하며 while은 끝나지 않습니다.

0

invoiceRange가 while 루프에서 true로 재설정되지 않아 문제가 발생했습니다.

당신은 당신이 여기 DO-while 루프를 사용한다 루프 동안 내부 invoiceRange=true로 설정하거나 break 키워드

+1

아니요, 새 입력이 받아 들일 수 있는지 여부를 확인하기 위해 불리언 조건을 다시 평가해야합니다. –

+0

@ a-sir 나는 내가 그렇게 기본적인 것을 간과했다고 믿을 수 없다. . . – i0h3