Understanding Java's flow of execution