一个亟待解决的问题,希望有大神来帮忙解释一下原因
•发布于   •作者 姜岩  •501 次浏览  •来自 问答

先上代码:

public class DemoCheck{
	public static void main(String[] args) {
		//直接定义
		Integer i=1;
		Integer j=1;
		System.out.println(i==j);//true
		System.out.println(i.equals(j));//true
		System.out.println("--------------");
		
		Double ui=1.0;
		Double iu=1.0;
		System.out.println(ui==iu);//false
		System.out.println(ui.equals(iu));//true
		System.out.println("--------------");
		
		Float yh=1.0f;
		Float hy=1.0f;
		System.out.println(yh==hy);//false
		System.out.println(yh.equals(hy));//true
		System.out.println("--------------");
		
		String x = "123";
		String y = "123";
		System.out.println(x==y);//true
		System.out.println(x.equals(y));//true
		System.out.println("--------------");
		
		System.out.println();
		System.out.println();
		
		//使用new创建对象
		Integer yb = new Integer(111);
		Integer by = new Integer(111);
		System.out.println(yb==by);//false
		System.out.println(yb.equals(by));//true
		System.out.println("--------------");
		
		Double d1 = new Double(1.0);
		Double d2 = new Double(1.0);
		System.out.println(d1==d2);//false
		System.out.println(d1.equals(d2));//true
		System.out.println("--------------");
		
		Float f1 = new Float(1.0);
		Float f2 = new Float(1.0);
		System.out.println(f1==f2);//false
		System.out.println(f1.equals(f2));//true
		System.out.println("--------------");
		
		String a = new String("abc");
		String b = new String("abc");
		System.out.println(a==b);//false
		System.out.println(a.equals(b));//true
		System.out.println("--------------");
	
		//为什么还会出现这种情况?
		Integer x1;
		Integer x2;
		x1=127;
		x2=127;
		System.out.println(x1==x2);//true
		x1=128;
		x2=128;
		System.out.println(x1==x2);//false
	}
}

运行的结果都在上面的注释上,但是不理解为什么同是为基本类型,Integer却是得出了不一样的结果,还有为什么使用Integer定义的x1和x2等于127相等,但是等于128却不相等了,希望有了解java内存原理的人从内存的角度给予合理的解释,非常感谢!

9 回复
fly唐朝的天空(唐秋果)

同求大神给答案@全体

=.=

        JVM会自动维护八种基本类型的常量池,int常量池中初始化-128~127的范围,所以当为Integer i=127时,在自动装箱过程中是取自常量池中的数值,而当Integer i=128时,128不在常量池范围内,所以在自动装箱过程中需new 128,所以地址不一样。网上看到的.....

姜岩

@胡瑞 我明白了! 谢谢解答!


Desolation

integer是有范围的,就像之前我在群里传的那个题目一样,就是

public static void main(String[] args) {
		Integer x;
		Integer y;
		x=127;
		y=127;
		System.out.println(x==y);//true
		x=128;
		y=128;
		System.out.println(x==y);//false
	}

这个Integer的范围是-128--127之间


姜岩

@Desolation 你这样表述不准确,我感觉胡瑞说的比较合理

Desolation

@姜岩 int 常量池中的数值范围不是-128~127的,而integer的范围之所以是-128~127,是因为int 是基本数据类型 ,Integer是其包装类,并且integer的初始值为null,而int的初始值为0



姜岩

@Desolation 如果integer的范围是-128-127的话,那为什么程序不会报错,而是在判断的时候打印出false?

Desolation
public static Integer valueOf(String s) throws NumberFormatException
    {
	return new Integer(parseInt(s, 10));
    }

    private static class IntegerCache {
	private IntegerCache(){}

	static final Integer cache[] = new Integer[-(-128) + 127 + 1];

	static {
	    for(int i = 0; i < cache.length; i++)
		cache[i] = new Integer(i - 128);
	}
    }

    /**
     * Returns a <tt>Integer</tt> instance representing the specified
     * <tt>int</tt> value.
     * If a new <tt>Integer</tt> instance is not required, this method
     * should generally be used in preference to the constructor
     * {@link #Integer(int)}, as this method is likely to yield
     * significantly better space and time performance by caching
     * frequently requested values.
     *
     * @param  i an <code>int</code> value.
     * @return a <tt>Integer</tt> instance representing <tt>i</tt>.
     * @since  1.5
     */
    public static Integer valueOf(int i) {
	final int offset = 128;
	if (i >= -128 && i <= 127) { // must cache 
	    return IntegerCache.cache[i + offset];
	}
        return new Integer(i);
    }

这个是Integer包装类中的一个转换,我们在定义Integer i =value 的时候,其实系统是在默认给我们改成了 Integer  i  =

Integer.valueOf(value);调用了Integer中的一个方法,这就是为什么范围在-128~127中



王成龙

@Desolation 这个解释比较合理

回到顶部

©2017 Powered by 三十三行伪代码
皖ICP备17005175号-3