In most cases, figuring out how many times a nested for loop will be run is just multiplication. You multiply the number of times the outer loop runs by the number of times the inner loop runs.
Here:
for (int i = 2; i <= 4; i+=2) {
    for (int j =1; j < 5; j++){
    System.out.println("2 times " + j + " = " + (i*j));
    }
}
The first loop runs for 2 times. The first time i is 2, the second time i is 4. There is no third time because i will then be 6 which is not less than or equal to 4.
The second loop is easier to figure out. You count up from 1 until it is not less than 5 anymore, so 1, 2, 3, 4, 4 times!
Now we can multiply 4 and 2 together to get 8, which is exactly how many times your System.out.println line is called.
Now, let's figure out the values of i and j. In a nested for loop, the variable in the inner loop changes at a faster rate than the one in the outer loop. It is only after the inner loop finishes, does the outer loop's variable change. So i starts off with 2, then j goes 1, 2, 3, 4 and the inner loop finishes. Now i is 4 and j goes 1, 2, 3, 4 again.
Now let's address the question of why the output says blatantly wrong things like 2 times 4 = 16. This is because of your print statement. You've made it so that it always starts with 2 times then j, then the value of i * j. So while i changes to 4 in the second iteration of the outer loop, you are still printing 2 times, when it should have been 4 times. To fix this, simply do:
System.out.println(i + " times " + j + " = " + (i*j));