In Java, every value is stored as a type; we've been doing htis already, though we haven't been calling that part out:
int i = 10;
double d = 24.4;
So far, we've kept these types constant: once we call something an int, we keep it an int, and don't try to make it a double.
Humans deal with types implicitly: we can tell 42 (an int or whole number) from 42.0 (a double or real number.)
Computers aren't that smart; they only see bytes, so to them, 42 and 42.0 aren't the same. In fact, to a computer, converting 42.0 to 42 is weird: it means we want it to store less information than it had been. (After all, 42.0 is more precise than 42.)
Since computers find dropping information so off-putting, we've got to tell them we really, really mean it. Casting is how we do that.
Run these math expressions, one at a time, in the Java REPL at the right.
What does 5.0/2 return?
What does (double) 5/2 return?
What about 5/2?
Why do the first two return the same answer and the third returns a different answer?
How about 3+5.0/2+5*2?
Let's change the place of the double. What does 3.0+5/2+5*2 return?
Why did changing the place of the double change the answer?
Now for an explicit cast: what does (int)(3.0 + 5)/(2 + 5 * 2) return?
Why do these last three expressions, which look similar, return different values?