Integer,new String 判断相等,值传递,以及引用传递的关系。

墨蓝 2022-07-29 10:48 233阅读 0赞

Integer,new String 判断相等,值传递,以及引用传递的关系。

总结:

1.Integer和String,参数引用的时候都是值传递的。StringBuffer和其他对象就都是引用传递的。

2.Integer和int比较的时候,自动把Integer的值转换成int值进行比较,所以一般会相等,两个Integer对象比较,不管是new出来的还是等号赋值的,相互比较

还会比较内存地址,所以不相等,但是这里有个特殊情况,就是Integer和Long,在第一次创建内存空间的时候会执行一个静态代码块生成一个缓存数组,下次

缓存数组里的元素直接从数组取了,数组大小为 256,也就是 -128~127,所以先生成一个Integer对象,然后之后在比较这个数组范围内的两个Integer是否相等

的时候是相等。具体可以参见下面的例子。

3.如果开头的代码是Integer a = 3;Integer b = 3;System. out.println(a==b);那么是true,因为a赋值的时候,生成静态数组了,b从数组中取的。

如果开头代码是Integer a = 143;Integer b = 143; System.out.println(a==b);那么是false,因为a赋值的时候,生成静态数组了,但是b的值不在数组范围内。

4.如果Integer a = xx; Integer b = new Integer(xx); 那么System.out.println(a==b);一定是false,因为new的时候显式 指定了去新申请一块地址空间存放,

和等号赋值不同。

5.String str1=”s”;String str2= new String(“s”);两者str1和str2比较也是不相同的,原理同Integer。但是Integer的值和int比较是个特例,Long也一样。

关于Integer和Long对象在比较对象相同时很容易犯错,在本文将做一个简短的分析。看下面的代码
public static void main(String[] args) {
Integer a = new Integer(3);
Integer b = new Integer(3);
System.out.println(a==b);
Integer c = 129;
Integer d = 129;
System.out.println(c==d);
Integer e = 127;
Integer f = 127;
System.out.println(e==f);
Long h = 128L;
Long g = 128L;
System.out.println(h==g);
Long k = 127L;
Long m = 127L;
System.out.println(k==m);
}
输出结果:
false
false
true
false
true

  1. ab在堆中分别分配了两块内存区域所以二都不等很好理解,而cd不等,然后ef却相等呢?查看Integer源代码后发现Integer有个内部类IntegerCache,它维护了一个Integer数组cache\[\] ,长度为256,还有一个静态块

static {
for(int i = 0; i < cache.length; i++)
cache[i] = new Integer(i - 128);
}
很明显这个静态块已经默认认创建出了-128~127 的 Integer 数据,因此Integer在创建对象时,若值在(-128到127)范围内,则直接从缓冲区中取,若超过该范围则创建新对象,因此在-128到127范围内Integer对象值相同时,对象==返回true,Long对象同理。
package com.test;

import java.math.BigDecimal;

public class MyTest {

  1. int p1=1000;
  2. static int p2=1000;
  3. public void myTest()\{
  4. System.err.println("\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*Integer\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*");
  5. int i1=1000;
  6. int i2=1000;
  7. Integer i3=1000;
  8. Integer i4=1000;
  9. Integer i5=100;
  10. Integer i6=100;
  11. Integer i7=new Integer(1000);
  12. Integer i8=new Integer(1000);
  13. System.err.println(i1== p1); //true(输出结果) 1(编号,便于分析)
  14. System.err.println(i1== p2); //true 2
  15. System.err.println(i1==i2); //true 3
  16. System.err.println(i3==i4); //false 4
  17. System.err.println(i5==i6); //true 5
  18. System.err.println(i7==i8); //false 6
  19. System.err.println(i1==i3); //true 7
  20. System.err.println(i1==i7); //true 8
  21. System.err.println(i3==i7); //false 9
  22. System.err.println("\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*Integer\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*");
  23. BigDecimal bd = new BigDecimal(12.01);
  24. System.out.println("bd is: " + bd.floatValue());
  25. \}
  26. public static void main(String args\[\])
  27. \{
  28. new MyTest().myTest();
  29. StringBuffer sb1 = new StringBuffer( "old value");
  30. testSb(sb1);
  31. System. out.println(sb1.toString());
  32. Integer s2 = new Integer(2);
  33. testS2(s2);
  34. System. out.println(s2.toString());
  35. String s1 = new String( "test");
  36. testString(s1);
  37. System. out.println(s1.toString() );
  38. \}
  39. //luke,luke
  40. static void testSb(StringBuffer sb)
  41. \{
  42. sb.append( " change!");
  43. System. out.println(sb.toString() );
  44. \}
  45. static void testS2(Integer sb)
  46. \{
  47. sb = sb + 1;
  48. System. out.println(sb.toString() );
  49. \}
  50. static void testString(String sb)
  51. \{
  52. sb = sb + " change";
  53. System. out.println(sb.toString() );
  54. \}

}

发表评论

表情:
评论列表 (有 0 条评论,233人围观)

还没有评论,来说两句吧...

相关阅读

    相关 传递引用传递,指针传递

    一、值传递 1、特点: (1)形参是实参的拷贝,改变形参的值并不会影响外部实参的值。 (2)从被调用函数的角度来说,值传递是单向的(实参->形参),参数的值只能传入,不能

    相关 String是值传递还是引用传递

    突然想到一个比较有意思的问题。    1、我们自己定义的类的参数传入方法,并在方法内改变了引用的值。 然后他在方法外使用这个值,发现这个类的参数是改变了的但是。   2、S