The braces define scope. For example, if you define a local variable within the braces and assign a value to it like this:
{
int foo = 10;
}
Then foo's scope (i.e. the section of code where it is define and has a value) is limited to the area within the braces.
The same goes for your for loop. Within those braces, the counter i is defined and has meaning, but not outside. So this code would not compile:
for (int i = 0; i < 5; i++) {
// Do something with i
}
i = 10; // Won't compile. i is undefined as a variable.
The benefits of this are numerous in that you can precisely control the scope for different variables. You can also define the scope of things like exceptions in the context of exception handling, etc.
You can also do things like this:
int i = 0;
for (; i < 5; i++) {
// Do something with i.
}
for (; i < 10; i++) {
// Do something else with i
}
In this case i is defined in a larger scope space (that of the enclosing method or constructor) and the for loops are only incrementing its value. So you are sharing a variable among two different areas of scope.
Lastly you can use them outside of a method or constructor as initialization blocks in a class. They allow you to initialize member variables that, for example, cannot easily be initialized with a single line of code.