Type casting is both right-to-left associative, and has a higher precedence than multiplication.
Source
Let me break it down a bit.
Like any other operator, a type cast has a certain level of priority attached to it. Certain operators have higher priority than others, and certain operators associate with their arguments in a certain way. For example, numerical operations are typically left-to-right associative; that is, with operators of an equal priority, one can parenthesize them from the left and get the same result.
Example:
5 * 5 * 5 / 3 + 5 -> (((5) * 5) * 5) / 3) + 5
Right-to-left associativity would allow you to parenthsize the operations from the right to achieve the same result.
Example:
int x;
int y;
int z;
x = y = z = 10 -> x = (y = (z = (10))
Type casting, much like assignment, is right-to-left associative, so it's going to essentially use the rightmost argument to satisfy its closest association, then progress backwards through the chain until you reach the ultimate goal.
This means that you could write this as valid syntax, although it would be very strange:
Object foo = (Object)(Number)(float)Math.random();
First, we cast our result from a double to a float, then to a Number
, then to an Object
(which is totally redundant, but possible).
The priority bit in particular is what causes the multiplication to apply last in this chain of events.
Bear in mind, in no one level of priority does the language intermingle associativity. That means an operator at level 1 priority associates in a specific way, and operators in level 2 operate in a specific way.
So, we come now to your expression:
int a = (int) Math.random() * 100;
Casting has a priority level of 3. The mathematical operator * has a priority level of 4. So, Java sees your statement like this:
int a = ((int) Math.random()) * 100;
The parentheses are there for extra clarity. (Note that parentheses have the highest priority.)
What you want to do, as explained more tersely in other answers, is use the parentheses to force your intended priority instead of letting Java decide. So, you would write this instead:
int a = (int) (Math.random() * 100);
This forces Java to evaluate the multiplication before the cast, since the parentheses have a higher priority than the cast.