int a = 1 << 32;
int b = 1 << 31 << 1;
Why does a == 1? b is 0 as I expected.
All shifts are done mod 32 for ints and mod 64 for longs.
As for why the language was designed that way - I don't know, but C# has the same design decision. Here's what the annotated ECMA C# spec says:
(There's then a list of some examples.)
This seems an entirely reasonable explanation to me. Consistency is definitely important, and if it would be impossible to implement different consistent behaviour in a performant way on some systems, I think this is a reasonable solution.
There is some difference in how processors implement shift instructions.
For instance, IIRC, ARM processors (32-bit ISA) take the least significant byte of the shifting register. (Shifts are not actually standalone instructions on ARM).
So long as the underlying processor has a vaguely sensible way to shift, it's easier to clear all but the least significant bits (one instruction usually) than to check if the shift is large and branch (actually on the ARM this only typically adds one instruction because all instructions are conditional).
BTW: This, and other potential gotchas are mentioned in Java Puzzlers (Traps, Pitfalls, and Corner Cases)