当前位置:首页 » 硬盘大全 » integer缓存
扩展阅读
webinf下怎么引入js 2023-08-31 21:54:13
堡垒机怎么打开web 2023-08-31 21:54:11

integer缓存

发布时间: 2022-01-31 18:45:33

⑴ java两个Integer中为什么得出的结果为false

当然是false了,因为你定义了两个Integer对象 i 和 j,“==”在用于两个对象之间比较时,比较的是两个对象的地址,而不是值。
i 和 j分别是两个Integer对象,在内存中的地址当然不一样,所以比较结果是false。
用int来定义的话,比较的就是值,结果就是true了。

⑵ JAVA中int和Integer在内存中到底存在哪里

java被执行的时候,运行的是字节码,所以 你要看它到底做了什么 最好看字节码,而不是你的程序。这个自动装箱拆箱会在后面做一些事情,从你的代码中可能看不到。

所以反汇编成字节码后,你会看到a==b到底是做了什么呢?

25: iload_1

26: aload_2

27: invokevirtual #31 // Method java/lang/Integer.intValue:()I

30: if_icmpne 37


注意,你这里的a==b其实 对于b来说 调用了b.intValue()方法。因此 只是做了 int的比较。和存在哪里没有关系。这和自动装箱拆箱有关。


⑶ java包装类的比较,Integer i1 = 40; Integer i2 = 0 + 40;

Integer是一个包装类,里面包含一个intValue,你可以看下底层代码,你的几次声明和赋值都是一个40的int结果对象,输出比较结果肯定是相同的,所以返回true

⑷ Integer中的问题

……LZ很有意思。
System.out,println(a=b);
这一句话中有两个bug,应该是
System.out.println(a==b);
另外这个问题确实是这样的,Integer会自动缓存[-128,127]之间的Integer对象。不过你如果这么写:
Integer a = new Integer(126);
Integer b = new Integer(126);
System.out.println(a==b);
输出false

⑸ Java 的Integer,int与new Integer到底怎么回事

实例分析

先看一个例子。

[java]view plain

  • publicclassTest{

  • publicstaticvoidmain(String[]args){

  • Integeri=newInteger(128);

  • Integeri2=128;

  • System.out.println(i==i2);

  • Integeri3=newInteger(127);

  • Integeri4=127;

  • System.out.println(i3==i4);

  • Integeri5=128;

  • Integeri6=128;

  • System.out.println(i5==i6);

  • Integeri7=127;

  • Integeri8=127;

  • System.out.println(i7==i8);

  • }

  • }

  • 输出的结果为
  • [java]view plain

  • false

  • false

  • false

  • true

  • 我们一个一个的进行分析。
  • 第一个情况:

    [java]view plain

  • Integeri=newInteger(128);

  • Integeri2=128;


  • i 是创建的一个Integer的对象,取值是128。

  • i2 是进行自动装箱的实例,因为这里超出了-128--127的范围,所以是创建了新的Integer对象。
  • 那么i和i2都是Integer的对象咯。存储在堆中,分配的地址不同,在使用==进行判读的时候,由于双方都是对象,所以比较对象的地址是不是相同,这里的地址是不同的,因为new的时候会在堆中重新分配存储空间。

    第二个情况:

    [java]view plain

  • Integeri3=newInteger(127);

  • Integeri4=127;

  • i3 是创建的一个Integer的对象,取值是127.
  • i4 是进行自动装箱后生成的Integer的对象,其值-128<= i4 <= 127,所以在这里会与第一种情况有所不同,这个i4对象直接取缓存IntegerCache中的对应的对象,当然了也是对象。

    那么i3和i4也都是对象咯,而且一个是缓存中的,一个自己new的,既然是对象那么==会比较其地址,因为都new出来的对象(一个是自己new出来的,一个是IntegerCache中new出来的对象),那么自然这两种情况下,在堆中分配的地址是不同的。

    第三种情况:

    [java]view plain

  • Integeri5=128;

  • Integeri6=128;


  • i5是自动装箱产生的Integer的对象,但是其大小超过了范围:-128<=A <=127,那么,这里会直接自己创建该对象即:new Integer(128);

    i6和i5类似的原理。

    显然这两个对象都是new出来,在堆中的地址值是不同的,那么==的时候判读其地址是不是相等,也就不一样了。

    第四种情况:

    [java]view plain

  • Integeri7=127;

  • Integeri8=127;

  • i7、i8是自动装箱产生的对象,其值都是127,那么这里很特殊的是127正好在-128<=i7<=127这个范围内的,那么会去IntegerCache中取,既然都是去IntegerCache中去取,那么自然该对象应该是一个对象,那么再堆中的地址应该是一样的,所以在判读两个对象是不是== 的时候,会输出true
  • 源码解析

    下面看下,Integer中的装箱的代码


⑹ java swap(Integer a ,Integer b)实现交换

public class App {
public static void main(String[] args) {
Integer a=1, b=2;
System.out.println("before:a=" + a + ", b=" + b);
swap(a,b);
System.out.println("after:a=" + a + ", b=" + b);
}
public static void swap(Integer i1, Integer i2) {
Integer tmp = i1;
i1 = i2;
i2 = tmp;
}
}
输出结果:a=1,b=2
java里两种参数传递形式:值传递,引用传递
java变量分为基本类型,引用类型,两种类型的参数传递给方法时都是按值传递
形参和实参所占的内存地址不一样
形参中的内容只是实参中存储的对象引用的一份拷贝
交换的是两个引用变量的副本,原来的a,b引用指向不变。

请查看Integer.java
private final int value;
public Integer(int value) {
this.value = value;
}
public class App {
public static void main(String[] args) {
Integer a=1; // Integer a = Integer.valueOf(1); IntegerCache.cache[1+128] == 1
Integer b=2;
System.out.println("before: a=" + a + ", b=" + b);
swap(a, b);
System.out.println("after: a=" + a +", b=" + b);
}

public static void swap(Integer i1, Integer i2) throws NoSuchFieldException {
//通过反射获得类私有不可变变量(private final int value;)
Field field = Integer.class.getDeclaredField(name:"value");
//通过setAccessible去访问私有的成员变量
field.setAccessible(true);
int tmp = i1.intValue(); //tmp值是1,
field.set(i1, i2.intValue()); // i1的值设置为Integer.valueOf(i2.intValue()).intValue(),此时i1地址是IntegerCache.cache[1+128]: 值为2
field.set(i2, tmp); //int-->Object Integer.valueOf(tmp).intValue(), tmp的值是地址IntegerCache.cache[1+128],
}


javap -v App.class 查看App的字节码
自动封装
Integer a = 1; // Integer a = Ineger.valueOf(1);
valueOf(int i) i在-128到127之间,返回缓存中的值 return IntegerCache.cache[i + (-IntegerCache.low)]
所以Integer a=1,b=1时,a == b ,两个的内存地址是同一个。

上面运行结果:
a=2, b=2

解决:
Integer tmp = new Integer(i1.intValue());
得 a=2, b=1

知识点:
1.自动装箱和拆箱
2.Integer -128到127之间的缓存
3.反射,通过反射去修改private final 变量。

https://www.cnblogs.com/doStudying/p/7851254.html 这里列出了field.setInt()方法,跟上面的set方法的区别, 应该?是参数类型不一致,是否用到IntegerCache
http://www.docin.com/p-700305321.html 这里副本的值指向a,b的地址。用this可实现,但注意static方法里不能用this。

⑺ java中Integer在JDK1.6和JDK1.7中的区别

运行下面这段代码:

System.out.println(Integer.valueOf("127")==Integer.valueOf("127"));
System.out.println(Integer.valueOf("128")==Integer.valueOf("128"));
System.out.println(Integer.parseInt("128")==Integer.valueOf("128"));

JDK1.6输出结果:

false

false

true

JDk1.7输出结果:

true

false

true

JDK1.7版本开始,Integer有了静态缓存,这点注意一下。

⑻ int 和 Integer 的区别

int是java提供的8种原始数据类型之一,Java为每个原始类型提供了封装类,Integer是java为int提供的封装类。Integer 是一个类,是int的扩展,定义了很多的转换方法。另外,Integer提供了多个与整数相关的操作方法,例如,将一个字符串转换成整数,Integer中还定义了表示整数的最大值和最小值的常量。

⑼ Long和Integer分别在什么时候用

今天使用findbugs扫描项目后发现很多高危漏洞,其中非常常见的一个是比较两个Long或Integer时直接使用的==来比较。 其实这样是错误的。
因为Long与Ineger都是包装类型,是对象。 而不是普通类型long与int , 所以它们在比较时必须都应该用equals,或者先使用longValue()或intValue()方法来得到他们的基本类型的值然后使用==比较也是可以的。
但是有一种特殊情况, 其实Long与Integer都将 -128~127 这些对象缓存了。 可以看看Long类型源码里面有一个LongCache类,代码如下:
<pre class="java">private static class LongCache { private LongCache(){} static final Long cache[] = new Long[-(-128) + 127 + 1]; static { for(int i = 0; i < cache.length; i++) cache[i] = new Long(i - 128); } } </pre>
先看看这个例子:
<pre class="java">public class Test05 { public static void main(String[] args) { Long a = 5L; Long b = 5L; System.out.println("a == b ? " + (a == b)); Long c = 129L; Long d = 129L; System.out.println("c == d ? " + (c == d)); } } </pre>
打印的结果是:
<pre class="css">a == b ? true c == d ? false </pre>
原因
首先来看看 Long a = 5L ; 它是如何将一个基本类型long包装成一个对象Long的 。
可以写一个测试类,然后反编译一下,看看java它是如何解析Long a = 5L这样一条命令的 。
测试类如下:
<pre class="java">public class Test06 { Long l = 3L; }</pre>
然后使用javap -verbose Test06 就能看到反编译的结果了, 下面是输出的部分:
<pre class="css">{ java.lang.Long l; public com.spring.test.Test06(); Code: Stack=3, Locals=1, Args_size=1 0: aload_0 1: invokespecial #10; //Method java/lang/Object."<init>":()V 4: aload_0 5: ldc2_w #12; //long 3l 8: invokestatic #14; //Method java/lang/Long.valueOf:(J)Ljava/lang/Long; 11: putfield #20; //Field l:Ljava/lang/Long; 14: return LineNumberTable: line 3: 0 line 5: 4 line 3: 14 LocalVariableTable: Start Length Slot Name Signature 0 15 0 this Lcom/spring/test/Test06; }</pre>
从Code中的8可以看出调用了Long的一个类方法Long.valueOf(Long) , 所以可以得到的结论是Long a = 5L实际上等于 Long a = Long.valueOf(5)
然后再看看Long.valueOf()方法是如何定义的:
<pre class="java"> public static Long valueOf(long l) { final int offset = 128; if (l >= -128 && l <= 127) { // will cache return LongCache.cache[(int)l + offset]; } return new Long(l); } </pre>
一目了然,会先判断基本类型的值如果在-128~127之间,就会直接从LongCache里面取出缓存的对象返回,否则就new一个新的Long对象返回 。
现在就不难理解Test05程序执行得到的结果了,因为a与b等于5,在-127~128之内,所以都是直接从LongCache里面返回的一个Long对象,所以他们在使用==比较的时候,就是相等的(对于对象类型来说,==比较的是两个对象的引用指向堆中的地址) ,而c与d等于129,不在-127~128之间,所以他们他们是分别new出来的两个新的Long对象,使用==来比较自然是不相等的了。
Long重写了equals方法:
<pre class="java"> public boolean equals(Object obj) { if (obj instanceof Long) { return value == ((Long)obj).longValue(); } return false; }</pre>
它是先通过.longValue()方法获取Long对象的基本类型long的值之后再做比较的。
所以对于Integer与Long的比较,最好是使用equals来比较才能确保得到我们想要的结果。
Integer与Long一样,这里就不举例了。

⑽ integer的默认缓存值是多少

Integer
变量存储为最接近编译环境的长度,例如在32位的编译环境下,Integer为32位,其范围为
-2^15

2^15-1
之间所以最大值是
2^15-1