The Java compiler evaluated an expression of Integer = ; to Integer = Integer.valueOf();.
Starting from JSE5.0 the compiler is caching Integer values between -128..127 (byte size). Hence, if the number is in the range mentioned above, the Integer.valueOf() method will always return an already existing object, corresponding to the requested int number, from a pre-generated Integer objects array. Since 1000 is not in the mentioned range, foo and bar are pointing to different, separately created objects
The compiler evaluates the foo <= bar; and foo >= bar; expressions to foo.intValue() <= bar.intValue() and foo.intValue() >= bar.intValue() which is equivalent to 1000 <= 1000 and 1000 >= 1000, which are both true.