Think of this way, after each loop, the scope is “destroyed”, and the variable is gone. In the next loop, a new scope is created, and the variable can be declared again in that scope.
You can also do this, for the similar reason
{
int someInteger = 3;
}
{
int someInteger = 13;
}
By the way, Java does not allow local variable shadowing, which might be inconvenient
int x = 3;
{
int x = 13; // error!
}
Consumer<Integer> consumer = (x)->print(x); // ERROR!
// lambda parameter is treated like local variable
Runnable r = ()->{ int x; ... } // ERROR
// lambda body is treated like local block