Just Java IT

西门町学士关于Java的随便一说而已……

2006年3月16日 #

Tiger pitfall

在SDN踩到一个Tiger的pitfall:
package sdn;

import java.util.ArrayList;

public class BoxingEquality {
   
    /** Creates a new instance of BoxingEquality */
    public BoxingEquality() {
    }
   
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
        int i = 1;
        int j = 1;
        ArrayList<Integer> list = new ArrayList<Integer>();
        list.add(i);
        list.add(j);
        System.out.printf("It is %b that i == j.\n", (i==j));
        System.out.printf("It is %b that list.get(0) == list.get(1).\n", (list.get(0)==list.get(1)));
        System.out.printf("It is %b that list.get(0).equals(list.get(1)).",            list.get(0).equals(list.get(1)));
    } 
}

输出结果出乎意料:
It is true that i == j.
It is true that list.get(0) == list.get(1).    // WHY???
It is true that list.get(0).equals(list.get(1)).

然而,仅仅将 i 和 j 的值改成1000:
int i = 1000;
int j = 1000;
就这一个改动后输出结果虽然符合了java的思维方式,但在这个context中却更显得怪异:
It is true that i == j.
It is false that list.get(0) == list.get(1). // Oops
It is true that list.get(0).equals(list.get(1)).

Sun给出的解释:
The primitives are equal and the values of the boxed ints are equal. But this time the ints point to different objects. What you have discovered is that for small integral values, the objects are cached in a pool much like Strings. When i and j are 2, a single object is referenced from two different locations. When i and j are 2000, two separate objects are referenced. Autoboxing is guaranteed to return the same object for integral values in the range [-128, 127], but an implementation may, at its discretion, cache values outside of that range. It would be bad style to rely on this caching in your code.

呵呵,要不注意说不定还真中招了!

posted @ 2006-03-16 22:03 西门町学士 阅读(177) | 评论 (5)编辑 收藏