The compiler can easily and unequivocally prove that the first expression always results in an infinite loop, but it's not as easy for the second. In your toy example it's simple, but what if:
- the variable's contents were read from a file?
- the variable wasn't local and could be modified by another thread?
- the variable relied on some user input?
The compiler is clearly not checking for your simpler case because it's forgoing that road altogether. Why? Because it's much harder forbidden by the spec. See section 14.21:
- http://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.21-300-M
(By the way, my compiler does complain when the variable is declared final.)
Java: Infinite Loop Convention - Stack Overflow
Having issues with infinite loops in Java
[Java] Unsure how to fix infinite loop
Is there something equivalent to C/Java's for(;;){} infinite for-loop syntax?
What problems can arise from infinite loops in a Java program?
How can I terminate or break out of an infinite loop in Java?
How can I handle intentional infinite loops to prevent unwanted consequences?
Videos
The compiler can easily and unequivocally prove that the first expression always results in an infinite loop, but it's not as easy for the second. In your toy example it's simple, but what if:
- the variable's contents were read from a file?
- the variable wasn't local and could be modified by another thread?
- the variable relied on some user input?
The compiler is clearly not checking for your simpler case because it's forgoing that road altogether. Why? Because it's much harder forbidden by the spec. See section 14.21:
- http://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.21-300-M
(By the way, my compiler does complain when the variable is declared final.)
According the specifications, the following is said about while statements.
A while statement can complete normally iff at least one of the following is true:
- The while statement is reachable and the condition expression is not a constant expression with value true.
- There is a reachable break statement that exits the while statement.\
So, the compiler will only say that the code following a while statement is unreachable if the while condition is a constant with a true value, or there is a break statement within the while. In the second case, since the value of b is not a constant, it doesn't consider the code following it to be unreachable. There's a whole lot more information behind that link to give you more details on just what is and what isn't considered unreachable.
There is no difference in bytecode between while(true) and for(;;) but I prefer while(true) since it is less confusing (especially for someone new to Java).
You can check it with this code example
void test1(){
for (;;){
System.out.println("hello");
}
}
void test2(){
while(true){
System.out.println("world");
}
}
When you use command javap -c ClassWithThoseMethods you will get
void test1();
Code:
0: getstatic #15 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #21 // String hello
5: invokevirtual #23 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: goto 0
void test2();
Code:
0: getstatic #15 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #31 // String world
5: invokevirtual #23 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: goto 0
which shows same structure (except "hello" vs "world" strings) .
I prefer while(true), because I use while loops less often than for loops. For loops have better uses and while(true) is much cleaner and easy to read than for(;;)
Hello I am a high school student making a wordle program for my assignment, I've used an infinite loop for the method of my game but I'm having issues while using if statements in this loop. I've used "continue;" everywhere I think I can but it still prevents my code from repeating. I'm sorry if my code looks messy, things worked even less when I had methods because you can use "continue;" in a method that goes into a loop. The loop just refuses to continue even with "continue;" in my if statements me, my teacher and my classmates cannot think of a solution.
import java.util.; import java.io.; public class MyProgram{ //create default text colour public static final String ANSI_RESET = "\u001B[0m"; //create green text public static final String ANSI_GREEN = "\033[0;32m"; //create yellow tenxt public static final String ANSI_YELLOW = "\033[0;33m"; //create black backgound public static final String BLACK_BACKGROUND = "\033[40m"; //create yellow background public static final String YELLOW_BACKGROUND = "\033[43m"; //create scanner class object Scanner s = new Scanner(System.in); public static void main(String[] args){ //create array of 5 letter words String[] wordBank = {"storm","green","glass","mould","sweet", "stamp"}; //invoke user prompt userPromt(); //will store a random number from rng method int rng = rng(); //will store index of the word bannk with the same value of the RNG number String wordle = wordBank[rng]; //invoke game method game(wordle); } //will prompt user and tell them the rules static void userPromt(){ System.out.println("Welcome to Wordle! The goal of the game is"); System.out.println("to guess a randomly chosen 5 by guessing with "); System.out.println("5 letter words. For your guesses you"); System.out.println("recieve hints on your letters. Yellow means that the letter is"); System.out.println("in the word but not in the right place, green"); System.out.println("means that the letter you guessed is in the"); System.out.println("right place! Just keep trying your guesses."); System.out.println("Good luck and have fun!!," + YELLOW_BACKGROUND + ":)" + ANSI_RESET); } //wll generate a random number static int rng(){ //max for rng int max = 5; //minimum for rng int min = 0; //will generate the random number int randomNumber = (int)(Math.random() * (max - min + 1) + min); //will return the random number return randomNumber; } //will have game static void game(String wordle){ //create scanner class object Scanner s = new Scanner(System.in); //while tru will run methods for the game //counter int i = 0; System.out.println("Enter a word: "); //never use an infinite loop again... while(true){ //scan for user input String guessRaw = s.nextLine(); //convert to lowercase String guess = guessRaw.toLowerCase(); //counter increments after guess i++;
//if guess is less than 5 letters or more than 5 letter print invalid guess message
if (guess.length() < 5 || guess.length() > 5){
//error message for user
errorMessage();
i--;
//tell loop to continue
continue;
}//This is about where my code gets loopy with all the continue statements and stuff, //will print hints //create for loop which will loop the if statments and their checks for (int o = 0; o < 5; o++){ //create variables to make if staments look neater and easier to read char guessChar = guess.charAt(o); char wordleChar = wordle.charAt(o); //will print g letters if character from i index on guess and wordle are the same if (guessChar == wordleChar){ System.out.print(ANSI_GREEN + guessChar + ANSI_RESET); //tell loop to continue continue; } //Will check for yellow letters if above condition is not true else if (guessChar != wordleChar){ //create for loop which will loop for staments and their checks for (int n = 1; n < 5; n++){ //create vaiable to make if statment look better char wordleCheck = wordle.charAt(n); //this loop will print one yellow character regardless of the number of matches found while(true){ //if guess character is found with a match it will print a yellow character if (guessChar == wordleCheck){ System.out.print(ANSI_YELLOW + guessChar + ANSI_RESET); break; } else{ continue; } } } continue; }
//Issue ends here
//will print black letters if all other conditions false
else {
System.out.print(guessChar);
continue;
}
}
//will print win message if conditions prove true
//loop will check for letters guessed correctly add and to counter n
for (int l = 0; l < 5; l++){
int n = 0;
char guessChar = guess.charAt(l);
char wordleChar = wordle.charAt(l);
if (guessChar == wordleChar){
n++;
//just for good measure
continue;
}
//if the value of counter n reaches 5 the user wins the game.
if(n == 5){
System.out.println("You win! " + YELLOW_BACKGROUND + ":)" + ANSI_RESET);
break;
}
}
//will lose the gamne if user does not win after 6 guesses
//THIS ACTIVATES IF YOU WIN FOR SOME REASON?!?!?!?!
if (i >= 6){
lose(wordle);
break;
}
}
}
//error message for if guess word has wrong lenght
static void errorMessage(){
System.out.println("Word length invalid.");
}
//method
static void printHints(String guessString, String wordleString){
//create for loop which will loop the if statments and their checks
for (int i = 0; i < 5; i++){
//create variables to make if staments look neater and easier to read
char guess = guessString.charAt(i);
char wordle = wordleString.charAt(i);
//will print g letters if character from i index on guess and wordle are the same
if (guess == wordle){
System.out.print(ANSI_GREEN + guess + ANSI_RESET);
}
//Will check for yellow letters if above condition is not true
else if (guess != wordle){
//create for loop which will loop for staments and their checks
for (int n = 1; n < 5; n++){
//create vaiable to make if statment look better
char wordleCheck = wordleString.charAt(n);
//this loop will print one yellow character regardless of the number of matches found
while(true){
//if guess character is found with a match it will print a yellow character
if (guess == wordleCheck){
System.out.print(ANSI_YELLOW + guess + ANSI_RESET);
break;
}
}
}
}
//will print a black letter if all other conditions are false
else {
System.out.print(guess);
}
}
//will move cursor to the next line to make things look more organized
System.out.println("");
}
//Will print losing message
static void lose(String wordle){
System.out.println("You lose, the wordle was " + wordle);
}
//Will check for win conditions then print out win message
static void win(String guessString, String wordleString){
//loop will check for letters guessed correctly add and to counter n
for (int l = 0; l < 5; l++){
int n = 0;
char guess = guessString.charAt(l);
char wordle = wordleString.charAt(l);
if (guess == wordle){
n++;
}
//if the value of counter n reaches 5 the user wins the game.
if(n == 5){
System.out.println("You win! " + YELLOW_BACKGROUND + ":)" + ANSI_RESET);
}
}
}
static void infiniteLoopie(char guessChar, char wordleChar, char wordleCheck){
//this loop will print one yellow character regardless of the number of matches found
while(true){
//if guess character is found with a match it will print a yellow character
if (guessChar == wordleCheck){
System.out.print(ANSI_YELLOW + guessChar + ANSI_RESET);
break;
}
else{
continue;
}
}
}}
Here is a Pastebin with my code: https://pastebin.com/SPmTJJyj
Honestly I cannot think of a solution other than use a for loop instead but I would rather like to keep as infinite it and I just came here to see if there was something I was doing wrong or could do to fix it.
I'm making this thread on my phone so I'm sorry if things get formatted weirdly because of it, if it gets removed I will go onto my PC and try to make it proper