integer 订阅
integer,整数 / 整型数,与小数 / 浮点数相对,是编程语言的基本数据类型之一,用以指示变量的数据类型,有时也用于常量(变量、表达式)的强制数据类型转换。整型数据的长度及其取值范围并不固定,受编译环境影响。在不同的编程语言中做此类型声明时,具体实现方式也可能会有所区别。 展开全文
integer,整数 / 整型数,与小数 / 浮点数相对,是编程语言的基本数据类型之一,用以指示变量的数据类型,有时也用于常量(变量、表达式)的强制数据类型转换。整型数据的长度及其取值范围并不固定,受编译环境影响。在不同的编程语言中做此类型声明时,具体实现方式也可能会有所区别。
信息
外文名
integer
相对应概念
小数 / 浮点数
中文名
整数 / 整型数
范    畴
编程语言
integer含义
Integer 数据类型Integer 一个整型数据用来存储整数,整数包括正整数,负整数和零。整型常量采用十进制整数表示。如 1991,0,-123等等都是整型常量。而52.0或131.4都不是整型常量。Integer 变量存储为最接近编译环境的长度,例如在32位的编译环境下,Integer为32位,其范围为 -2^15 到 2^15-1 之间。VB中Integer 的类型声明字符是百分比符号 (%)。Pascal中就是integer。在C语言中被缩写成为int。
收起全文
精华内容
下载资源
问答
  • 2019-11-22 14:57:50

    发现做项目的过程中,在数值类型的比较上容易犯错,特别是Integer和Integer的比较,Integer和int的比较。虽然这些都是些基础语法,但稍不留意就容易犯错,在实际开发过程中如果出现这类失误,很容易失之毫厘谬以千里。在这里,总结下这些基础知识点。

    java虽然宣称一切都是对象,但原始数据类型是例外。int是整形数字,是java的9个原始数据类型(Primitive Types)(boolean、byte、short、char、int、float、double、long、void)之一。Integer是int对应的包装类,它有一个int类型的字段存储数据,并且提供了基本操作,比如数学运算、int和字符串之间转换等。在java 5中引入了自动装箱和自动拆箱功能(boxing/unboxing),java可以根据上下文,自动进行转换,极大地简化了相关编程。javac自动把装箱转换为Integer.valueOf(),把拆箱替换为Integer.intValue()

    自动装箱实际上算是一种语法糖。什么是语法糖?可以简单理解为java平台为我们自动进行了一些转换,保证不同的写法在运行时等价,他们发生在编译阶段,也就是生产的字节码是一致的。(此句摘自极客时间专栏)

    原始数据类型的变量,需要使用并发相关手段才能保证线程安全。如果有线程安全的计算需要,建议考虑使用类似AtomicInteger、AtomicLong这样的线程安全类。

    原始数据类型和java泛型并不能配合使用。因为java的泛型某种程度上可以算作伪泛型,它完全是一种编译期的技巧,java编译期会自动将类型转换为对应的特定类型。这就决定了使用泛型,必须保证相应类型可以转换为Object。

    废话不多说,直接来demo,这样效果更直接。

    public class Test {
    
    	public static void main(String[] args) {
    		
    		Integer a1 = 6;
    		Integer a2 = 6;
    		int a11 = 6;
    		
    		System.out.println(a1 == a2); //true
    		System.out.println(a1 == a11); //true
    		
    		System.out.println("----------------");
    		
    		Integer a3 = 128;
    		Integer a4 = 128;
    		int a33 = 128;
    		
    		System.out.println(a3 == a4); //false
    		//Integer会自动拆箱为int,所以为true
    		System.out.println(a3 == a33); //true
    		System.out.println(a3.equals(a4)); //true
    		
    		System.out.println("----------------");
    		
    		Integer a5 = new Integer(6);
    		Integer a6 = new Integer(6);
    		
    		System.out.println(a5 == a6); //false
    		System.out.println(a5.equals(a6)); //true
    
    	}
    

    需要明确的一点是,包装型(Integer)和基本型(int)比较会自动拆箱(jdk1.5以上)。

    在这里很多人比较容易迷惑的是如下情况:

    		Integer a1 = 6;
    		Integer a2 = 6;
    		System.out.println(a1 == a2); //true
    		
    		Integer a3 = 128;
    		Integer a4 = 128;
    		System.out.println(a3 == a4); //false
    

    如果研究过jdk源码,你就会发现Integer a3 = 128;在java编译时会被翻译成 Integer a3 = Integer.valueOf(128); 我们再来看看valueOf()的源码就更清晰了。

    public static Integer valueOf(int i) {
        assert IntegerCache.high >= 127;
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }
    

    由以上源码就会发现,对于-128到127之间的数,会进行缓存,Integer a1 = 6时,会将6进行缓存,下次再写Integer a2 = 6;时,就会直接从缓存中取,也就不用new一个对象了,所以a1和a2比较时就为true。但a3和a4是超过范围,会new一个对象,==是进行地址和值比较,是比较两个对象在JVM中的地址,这时a3和a4虽然值相同但地址是不一样的,所以比较就为false了。

    通过上面的分析可知:

    • 两个都不是new出来的Integer,且数值在-128~127之间,用==比较时,基本值相等时为true,否则为false;
    • 两个都是new出来的Integer,为false
    • int和Integer比较,数值相同,用==比较时为true。(因为Integer会自动拆箱为int去比较)

    所有包装类对象之间值的比较,建议使用equals方法比较

    ==判断对象是否同一个。

    Integer var = ?在缓存区间的赋值,会复用已有对象,因此这个区间内的Integer使用==进行判断可通过,但是区间之外的所有数据,则会在上新产生,不会通过。

    因此如果用== 来比较数值,很可能在小的测试数据中通过,而到了生产环境才出问题。

    为了节省内容,对与下列包装对象的两个实例,当他们的基本值相同时,用==判断会为true:

     Boolean  
     Byte  
     Character, \u0000 - \u007f(7f是十进制的127)  
     Integer, -128 — 127  
    

    我们也可以看看其它包装型的缓存情况:

    Boolean:(全部缓存)
    Byte:(全部缓存)
    
    Character(缓存范围'\u0000''\u007F')
    Short(-128127缓存)
    Long(-128127缓存)
    
    Float(没有缓存)
    Doulbe(没有缓存)
    

    如果要比较两个Integer对象的值(均为new的对象),可以通过.intValue()进行转换后来比较,如下:

    		Integer a3 = 128;
    		Integer a4 = 128;
    		System.out.println(a3.intValue() == a4.intValue());
    

    也可以使用equal()来进行比较,如下:

    		Integer a3 = 128;
    		Integer a4 = 128;
    		System.out.println(a3.equals(a4)); //true
    
    更多相关内容
  • mybatis返回Integer

    热门讨论 2013-08-01 12:56:20
    mybatis返回int会报错,改成Integer封装类型可以解决,具体参考我的博客
  • Integer缓存IntegerCache详解

    千次阅读 多人点赞 2020-11-27 10:59:28
    IntegerCache缓存区间为[-128,127]。在调用Integer.valueOf(int i)方法进行自动装箱时假若i的值在[-128,127]区间则生成的Integer对象会被存入缓冲区。当再次对该值进行装箱时会先去缓冲区中获取;如果取到则返回,...

    版权声明

    • 本文原创作者:谷哥的小弟
    • 作者博客地址:http://blog.csdn.net/lfdfhl

    引子

    今天,我们从一段非常简单的代码说起。

    示例代码

    package cn.com;
    /**
    * 本文作者:谷哥的小弟 
    * 博客地址:http://blog.csdn.net/lfdfhl
    * 示例描述:Integer缓存IntegerCache
    */
    public class IntegerCacheTest {
    
    	public static void main(String[] args) {
    		Integer a=9527;
    		Integer b=9527;
    		System.out.println(a==b);	
    		Integer c=97;
    		Integer d=97;
    		System.out.println(c==d);
    	}
    
    }
    

    运行结果

    请问,这段代码运行的结果是什么呢?两次输出的结果都是false,对不对?非也!!!

    在这里插入图片描述
    从上图可以清楚地看到:

    • 1、第一次输出的结果是false
    • 2、第二次输出的结果是true

    看此处,就有点丈二和尚摸不着头脑了。这是为什么呢?

    源码剖析

    在执行Integer a=9527;时会调用Integer类的静态方法public static Integer valueOf(int i)进行自动装箱,其源码如下:

    public static Integer valueOf(int i) {
            if (i >= IntegerCache.low && i <= IntegerCache.high)
                return IntegerCache.cache[i + (-IntegerCache.low)];
            return new Integer(i);
        }
    

    该方法的主要逻辑如下:

    • 如果i >= IntegerCache.low && i <= IntegerCache.high则调用IntegerCache.cache[i + (-IntegerCache.low)]
    • 如果i的值不满足i >= IntegerCache.low && i <= IntegerCache.high则调用new Integer(i)

    顺着这条主线,我们继续探究Integer缓存IntegerCache。IntegerCache是Integer类中的静态内部类,用于缓存数据便于节省内存、提高性能。其源码如下:

    private static class IntegerCache {
            static final int low = -128;
            static final int high;
            static final Integer cache[];
    
            static {
                // high value may be configured by property
                int h = 127;
                String integerCacheHighPropValue =
                    sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
                if (integerCacheHighPropValue != null) {
                    try {
                        int i = parseInt(integerCacheHighPropValue);
                        i = Math.max(i, 127);
                        // Maximum array size is Integer.MAX_VALUE
                        h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
                    } catch( NumberFormatException nfe) {
                        // If the property cannot be parsed into an int, ignore it.
                    }
                }
                high = h;
    
                cache = new Integer[(high - low) + 1];
                int j = low;
                for(int k = 0; k < cache.length; k++)
                    cache[k] = new Integer(j++);
    
                // range [-128, 127] must be interned (JLS7 5.1.7)
                assert IntegerCache.high >= 127;
            }
    
            private IntegerCache() {}
        }
    

    从这里我们可以看出 :

    • IntegerCache.low = -128
    • IntegerCache.high = 127
    • 缓冲区cache是一个Integer类型的数组

    也就是说:IntegerCache缓存区间为[-128,127]。所以,在调用Integer.valueOf(int i)方法进行自动装箱时假若i的值在[-128,127]区间则生成的Integer对象会被存入缓冲区。当再次对该值进行装箱时会先去缓冲区中获取;如果取到则返回,如果没有取到则创建包装类对象存入缓冲区并返回。

    嗯哼,看到这里是不是可以理解之前的那小段代码了呢?

    扩展与延伸

    除了Integer之外,在其他包装类(例如:Byte,Short,Long等)中也存在类似的设计。

    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述

    展开全文
  • Integer.valueof()和Integer.parseInt()的区别

    万次阅读 多人点赞 2020-05-26 11:43:01
    Integer. valueOf()可以将基本类型int转换为包装类型Integer,或者将String转换成Integer,String如果为Null或“”都会报错。 Integer. valueOf()是高效的 public static Integer valueOf(int i) { if (i >= ...

    Integer. valueOf()可以将基本类型int转换为包装类型Integer,或者将String转换成Integer,String如果为Null或“”都会报错。

    Integer. valueOf()是高效的

    public static Integer valueOf(int i) {
            if (i >= IntegerCache.low && i <= IntegerCache.high)
                return IntegerCache.cache[i + (-IntegerCache.low)];
            return new Integer(i);
        }
    private static class IntegerCache {
            static final int low = -128;
            static final int high;
            static final Integer cache[];
    
            static {
                // high value may be configured by property
                int h = 127;
                String integerCacheHighPropValue =
                    sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
                if (integerCacheHighPropValue != null) {
                    try {
                        int i = parseInt(integerCacheHighPropValue);
                        i = Math.max(i, 127);
                        // Maximum array size is Integer.MAX_VALUE
                        h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
                    } catch( NumberFormatException nfe) {
                        // If the property cannot be parsed into an int, ignore it.
                    }
                }
                high = h;
    
                cache = new Integer[(high - low) + 1];
                int j = low;
                for(int k = 0; k < cache.length; k++)
                    cache[k] = new Integer(j++);
    
                // range [-128, 127] must be interned (JLS7 5.1.7)
                assert IntegerCache.high >= 127;
            }
    
            private IntegerCache() {}
        }

    从他的实现方法可以看出他int在[-128,127]之间的时候他会直接拿缓存,而不会new Integer(),Integer.valueOf()方法基于减少对象创建次数和节省内存的考虑,缓存了[-128,127]之间的数字。此数字范围内传参则直接返回缓存中的对象。在此之外,直接new出来。
     

    下面我们来看一道选择题,就是关于Integer.valueOf()的知识,题目如下: 

    这里写图片描述

    A.System.out.println(i01== i02); 
    B.System.out.println(i01== i03); 
    C.System.out.println(i03== i04); 
    D.System.out.println(i02== i04);


    答案呢,我也做对了,但是也是靠排除法做对的,至于这道题考察的具体细节问题,我当时没考虑,不过等我查看了Integer的相关源码时,茅舍顿开。答案这里我这里先不公布,我们慢慢开始分析。

    分析

    选项A

      选项A中比较的是i01和i02,Integer i01=59这里涉及到自动装箱过程,59是整型常量,经包装使其产生一个引用并存在栈中指向这个整型常量所占的内存,这时i01就是Integer 的引用。 
      而int i02=59由于int是基本类型,所以不存在引用问题,直接由编译器将其存放在栈中,换一句话说,i02本身就是59。那么System.out.println(i01== i02)结果任何呢?这里涉及到了拆箱的过程,因为等号一边存在基本类型所以编译器后会把另一边的Integer对象拆箱成int型,这时等号两边比较的就是数值大小,所以是true。

    好了,到了这里,你有没有想到这样一个问题:如果是Integer i01=59;Integer i02=59;然后System.out.println(i01== i02)的结果是?可能你会说比较数值大小所以相等啊,也有可能说等号两边对象引用,所以比较的是引用,又因为开辟了不同的内存空间,所以引用不同所以返回false。可是正确答案是:true. 
    再来看这个问题::如果是Integer i01=300;Integer i02=300;然后System.out.println(i01== i02)的结果是? 你可能说上面你不是说了true嘛,怎么还问这样的问题,可是这次的答案是false。你是否会吃惊?大牛除外,我是小白,求不打脸!
      

    解析:当靠想象无法解决问题的时候,这是就要看源代码了!!很重要!我们可以在Integer类中找到这样的嵌套内部类IntegerCache,这个类就是在Integer类装入内存中时,会执行其内部类中静态代码块进行其初始化工作,做的主要工作就是把一字节的整型数据(-128-127)装包成Integer类并把其对应的引用存入到cache数组中,这样在方法区中开辟空间存放这些静态Integer变量,同时静态cache数组也存放在这里,供线程享用,这也称静态缓存。 
      所以当用Integer 声明初始化变量时,会先判断所赋值的大小是否在-128到127之间,若在,则利用静态缓存中的空间并且返回对应cache数组中对应引用,存放到运行栈中,而不再重新开辟内存。 
      所以对于Integer i01=59;Integer i02=59;**i01 和 i02是引用并且相等都指向缓存中的数据,所以返回true。而对于**Integer i01=300;Integer i02=300;因为其数据大于127,所以虚拟机会在堆中重新new (开辟新空间)一个 Integer 对象存放300,创建2个对象就会产生2个这样的空间,空间的地址肯定不同导致返回到栈中的引用的只不同。所以System.out.println打印出false。

    补充:为什么1个字节的数据范围是-128到127呢,因为Java中数据的表示都是带符号数,所以最高位是用来表示数据的正负,0表示正数,1表示负数,所以正数最大的情况对应的二进制数为:01111111,负数最小对应的二进制数为:10000000.

    B选项

      从上面的分析,我们已经知道Integer i01=59返回的是指向缓存数据的引用。那么Integer.valueOf(59)返回的是什么或者操作是什么呢? 
      这个函数的功能就是把int 型转换成Integer,简单说就是装包,那他是新创建一个对象吗?还是像之前利用缓存的呢?有了之前的经验,肯定想到的是利用缓存,这样做既提高程序速度,又节约内存,何乐而不为? 
    来看一下源代码:

    public static Integer valueOf(int i) {
            if (i >= IntegerCache.low && i <= IntegerCache.high)
                return IntegerCache.cache[i + (-IntegerCache.low)];
            return new Integer(i);
        }

    很明显跟之前的思想一致,若在-128到127范围,直接返回该对象的引用,否则在堆中重新new 一个。 
    到这,System.out.println(i01== i03)的结果毋庸置疑就是true.

    选项C

      Integer.valueOf(59)返回的是已缓存的对象的引用,而Integer i04 = new Integer(59)是在堆中新开辟的空间,所以二者的引用的值必然不同,返回false,这道题呢就选C

    选项D

      System.out.println(i02== i04) i02是整型变量,i04是引用,这里又用到了解包,虚拟机会把i04指向的数据拆箱为整型变量再与之比较,所以比较的是数值,59==59,返回true.


    出一道题:

    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"));

    输出是:

    true

    false

    true

     回答#1:

    Integer.valueOf(String)确有一个不同寻常的行为。

    valueOf会返回一个Integer(整型)对象,当被处理的字符串在-128和127(包含边界)之间时,返回的对象是预先缓存的。这就是为什么第一行的调用会返回true-127这个整型对象是被缓存的(所以两次valueOf返回的是同一个对象)——第二行的调用返回false是因为128没有被缓存,所以每次调用,都会生成一个新的整型对象,因此两个128整型对象是不同的对象。

    重要的是你要知道在上面的比较中,你实际进行比较的是integer.valueOf返回的对象引用,所以当你比较缓存外的整型对象时,相等的判断不会返回true,就算你传个valueOf的值是相等的也没用。(就像第二行中Integer.valueOf(128)==Integer.valueOf(128))。想让这个判断返回true,你需要使用equals()方法。

    parseInt()返回的不是整型对象,而是一个int型基础元素。这就是为什么最后一个判断会返回true,第三行的判断中,在判断相等时,实际比较的是128 == 128,所以它必然是相等的。

    再来说说第三种比较中的一点区别,使得它的结果与第二种比较不一样了:

    一个unboxing conversion(一种比较时的转换,把对对象的引用转换为其对应的原子类型)在第三行的比较中发生了。因为比较操作符使用了==同时等号的两边存在一个int型和一个Integer对象的引用。这样的话,等号右边返回的Integer对象被进一步转换成了int数值,才与左边进行相等判断。

    所以在转换完成后,你实际比较的是两个原子整型数值。这种转换正是你在比较两个原子类型时所期待看到的那样,所以你最终比较了128等于128。

    回答#2:

    Integer类有一个静态缓存,存储了256个特殊的Integer对象——每个对象分别对应-128 和127之间的一个值。

    有了这个概念,就可以知道上面三行代码之间的区别。

    new Integer(123);

    显示创建了一个新的Integer对象。

    Integer.parseInt("123");

    解析完字符串后返回一个int值。

    Integer.valueOf("123");

    这种情况比其他的要更复杂一些。首先进行了字符串解析,然后如果解析的值位于-128和127之间,就会从静态缓存中返回对象。如果超出了这个范围,就会调用Integer()方法并将解析的值作为参数传入,得到一个新的对象。

    现在,让我们看一下问题中的3个表达式。

    Integer.valueOf("127")==Integer.valueOf("127");

    上面的表达式返回true,因为Integer的值从静态缓存中取了2次,表达式返回了对象与自己比较的结果。因为只有一个Integer对象,所以返回结果为true。

    Integer.valueOf("128")==Integer.valueOf("128");

    上面的表达式返回false,因为128没有存在静态缓冲区。所以每次在判断相等时等式两边都会创建新的Integer对象。由于两个Integer对象不同,所以==只有等式两边代表同一个对象时才会返回true。因此,上面的等式返回false。

    Integer.parseInt("128")==Integer.valueOf("128");

    上面的表达式比较的是左边的原始int值128与右边新创建的Integer对象。但是因为int和Integer之间比较是没有意义的,所以Java在进行比较前会将Integer自动拆箱,所以最后进行的是int和int值之间的比较。由于128和自己相等,所以返回true。

    注意:此文只适应于jdk7或以上版本,因为jdk6与jdk7的Integer具体实现有差别,详情可查看下源代码.


    Integer.parseInt()

    Integer.valueof() 和 Integer.parseInt() 的底层都是用的Integer.parseInt(String s ,int radix)这个方法。在这里给这个方法做一下解释。

      Integer.parseInt(String s ,int radix),radix用来表示传进来的值是什么进制的,并返回10进制的 int 类型的结果 

      比如Integer.parseInt(“A”,16),则输出结果为10进制的10,其中16表示"A"是一个16进制的值。

      根据:Character.MIN_RADIX=2和Character.MAX_RADIX=36 则,parseInt(String s, int radix)参数中radix的范围是在2~36之间,超出范围会抛异常。其中s的长度也不能超出7,否则也会抛异常。其中限制在36位之内是因为数字加字母刚好可以表示到36位,比如Integer.parseInt(“Z”,36),输出结果为35。

      以下为parseInt(String s ,Int radix)的源代码实现。

    /**
     * 字符串转换成整数
     * @param s	待转换字符串
     * @param radix	进制
     * @return
     */
    public static int parseInt(String s,int radix){
    	//边界值处理
    	if(s==null)
    		throw new NumberFormatException("null");
    	if(radix<Character.MIN_RADIX){
    		throw new NumberFormatException("radix "+radix+" less than Character.MIN_RADIX");
    	}
    	if(radix>Character.MAX_RADIX){
    		throw new NumberFormatException("radix "+radix+" greater than Character.MAX_RADIX");
    	}
    	
        //最终返回的结果的负数形式
    	int result=0;
    	
    	//判断是否为负数
    	boolean negative=false;
    	
    	//字符串偏移指针
    	int i=0;
    	
    	int digit;
    	
    	int max=s.length();
    	
    	//最大边界值
        int limit;
    	
    	//最大边界值右移一位
    	int multmin;
    	
    	if(max>0){
    		//处理符号
    		if(s.charAt(0)=='-'){
    			negative=true;
    			//边界值为0x80000000
    			limit=Integer.MIN_VALUE;
    			i++;
    		}
    		else{
    			//边界值为-0x7fffffff
    			limit=-Integer.MAX_VALUE;
    		}
    		//计算multmin 值 ,multmin = -214748364 负数跟整数的limit是不同的
    		multmin=limit/radix;
    		if(i<max){
    			digit=Character.digit(s.charAt(i++), radix);
    			if(digit<0){
    				throw NumberFormatException.forInputString(s);
    			}
    			else{
    				result=-digit;
    			}
    		}
            //开始循环追加数字,比如输入“123” 10进制数
    		while(i<max){
    			//获取字符转换成对应进制的整数,如上,这里第一次循环获取1
                //第二次循环获取2
                //第三次循环获取3
    			digit=Character.digit(s.charAt(i++), radix);
    			if(digit < 0){
    				throw NumberFormatException.forInputString(s);
    			}
    			//判断,在追加后一个数字前,判断其是否能能够在继续追加数字,比如multmin = 123
                //那么再继续追加就会变为123*10+下一个数字,就会溢出
    			if(result < multmin){
    				throw NumberFormatException.forInputString(s);
    			}
    
                //第一次循环   result = 0;
                //第二次循环   result = -10;
                //第三次循环   result = -120;
    			result*=radix;
    			
    			if(result<limit+digit){
                    //第一次循环  limit + digit = -2147483647+1;
                    //第二次循环   limit + digit = -2147483647+2;
                    //第三次循环   limit + digit = -2147483647+3;
    				throw NumberFormatException.forInputString(s);
    			}
    			result-=digit;
                //第一次循环 result = -1;
                //第二次循环 result = -12;
                //第三次循环 result = -123;
    		}
    	}
    	else{
    		throw NumberFormatException.forInputString(s);
    	}
    	if(negative){
    		if(i>1){
    			return result;
    		}
    		else{
    			throw NumberFormatException.forInputString(s);
    		}
    	}
    	else{
            //negative 值为false,所以 -result = -(-123) = 123  返回结果
    		return -result;
    	}
    }

    关键点:

    1. 正数的边界值为1至0x7fffffff;负数的边界值为-1至0x80000000;
    2. 代码中将所有数据当做负数(正数)来处理,最后处理符号问题;
    3. 方法中multmin这个变量是为了在循环中result*=radix不会发生越界;

    Integer.parseInt("")、 Integer.valueOf("")new Integer("")它们之间有什么区别呢?我们可以分别看一下它们的源码

    //Integer.parseInt("")
    public static int parseInt(String s) throws NumberFormatException {
      return parseInt(s,10);
    }
    //Integer.valueOf("")
    public static Integer valueOf(String s) throws NumberFormatException {
      return Integer.valueOf(parseInt(s, 10));
    }
    //new Integer("")
    public Integer(String s) throws NumberFormatException {
      this.value = parseInt(s, 10);
    }
    

    从源码中可以看出,Integer.valueOf("")Integer.parseInt("")内部实现是一样的,它们之间唯一的区别就是Integer.valueOf(“”)返回的是一个Integer对象,而Integer.parseInt(“”)返回的是一个基本类型的int

    我们再看Integer.valueOf("")new Integer(""),它们同样返回的是一个Integer对象,但它们又有什么区别呢?我们再进入Integer.valueOf(parseInt(s, 10) )方法内部:

    public static Integer valueOf(int i) {
      if (i >= IntegerCache.low && i <= IntegerCache.high)
      return IntegerCache.cache[i + (-IntegerCache.low)];
      return new Integer(i);
    }
    

    我们可以看到,Integer.valueOf("")会用到IntegerCache对象,当IntegerCache中存在时就从cache中取,不存在时才会调用new Integer(i)构造函数返回一个Integer对象。所以Integer.valueOf("")会用到cache,其效率可能会比用构造函数new Integer(i)

    关于IntegerCache,在-127~128之间的值都会被cache,所以当我们要的值位于这个区间时返回的都是同一个实例,例如:

    System.out.println(Integer.valueOf(5) == Integer.valueOf(5)); 
    
    System.out.println(Integer.valueOf(500) == Integer.valueOf(500));

    输出结果:

    true //会用到缓存
    
    false //不会用到缓存

     

    展开全文
  • java Integer等号判断

    千次阅读 2020-11-15 20:58:44
    在-128到127范围内的赋值,Integer对象在IntegerCache.cache产生,会复用已有对象,这个区间的Integer值可以直接使用==进行判断,但是这个区间之外的所有数据都会在堆上产生,并不会复用已有对象,这是一个大坑,...

    《阿里Java开发手册》中有这样一项强制要求:

    “所有整形包装类对象之间值的比较,全部使用equals方法比较。说明:对于Integer var= ?在-128到127范围内的赋值,Integer对象在IntegerCache.cache产生,会复用已有对象,这个区间的Integer值可以直接使用==进行判断,但是这个区间之外的所有数据都会在堆上产生,并不会复用已有对象,这是一个大坑,推荐使用equals方法进行判断。”

    究其原因,为什么呢。我们先看一段代码:

        public static void main(String[] args) {
            Integer i1 = 64;
            int i2 = 64;
    
            Integer i3 = Integer.valueOf(64);
            Integer i4 = new Integer(64);
    
            Integer i5 = 256;
            Integer i6 = Integer.valueOf(256);
    
            System.out.println("i1 == i2:" + (i1 == i2)); // true
            System.out.println("i1 == i3:" + (i1 == i3)); // true
            System.out.println("i1 == i4:" + (i1 == i4)); // false
            System.out.println("i2 == i4:" + (i2 == i4)); // true
            System.out.println("i3 == i4:" + (i3 == i4)); // false
            System.out.println("i3.equals(i4):" + (i3.equals(i4))); // true
            System.out.println("(i5 == i6):" + (i5 == i6)); // false
        }
    

    如果有些结果和我们预料的不太一样,我们还是认真深究一下。

    变量在JVM中的存储

    在彻底弄清楚上问题之前,我们先来了解一下基础类型变量、引用类型变量在JVM中的存储。

    通常变量分为局部变量和全局(成员)变量。局部变量是声明在方法内的变量,也包括方法参数;全局变量是声明在类中的成员变量。

    基础类型的变量和值在分配的时候是在一起的,都在方法区或栈内存或堆内存。而引用类型的变量和值不一定在一起。

    局部变量存储在方法栈中

    当方法被调用时,Java虚拟机都同步创建一个栈帧,局部变量便存储在其中。当方法结束虚拟机会释放方法栈,其中声明的变量随着栈帧的销毁而结束。因此,局部变量只能在方法中有效。

    此过程中,基础类型和引用类型的存储有所区别:

    (1)基本类型:变量和对应的值存放在JAVA虚拟机的栈中;

    (2)引用类型:变量存储在栈中,是一个内存地址,该地址值指向堆中的对象。
    在这里插入图片描述
    栈属于线程私有的空间,局部变量的生命周期和作用域一般都很短,为了提高gc效率,所以没必要放在堆里面。

    全局变量存储在堆中

    全局变量存放在堆中,不会随着方法结束而销毁。同样在类中声明的变量也是分为基本类型和引用类型。

    (1)基本类型:变量名和值存放在堆内存中。

    (2)引用类型:变量是一个引用地址,该地址指向所引用的对象。此时,变量和对象都在堆中。

    举个简单的例子,如下代码:

    public class Person {
    	int age = 10;
    	String name = "Tom";
    }
    

    结合上面的理论,我们通过一段代码来分析一下各种类型所存储的位置。

    public class DemoTest {
    
     int y; // 变量和值均在堆上
     
     public static void main(String[] args) {
    
         int x = 1; // 变量和值分配在栈上
         
         String name = new String("cat"); // 数据在堆上,name变量的指针在栈上
         
         String address = "北京"; // 数据在常量池,属于堆空间,指针在栈上
         
         Integer price = 4; // 包装类型为引用类型,编译时会自动装拆箱,数据在堆上,指针在栈
     }
    }
    

    基础类型的栈内存储

    通过上面的实例,基本了解了不同类型的值的内存分配情况。下面我们重点讨论局部变量。

    下面先来看看在同一栈帧中,针对int类型的处理模式。

    int a = 3;
    int b = 3

    上述代码中a和b均为局部变量。假设编译器先处理int a=3,此时会在栈中创建a的引用变量,然后查找栈中是否存在3这个值,如果没有就将3存放进来,然后将a指向3。

    接着处理int b=3,创建完b的引用变量后,同样进行查找。因为在栈中已经有3这个值,便将b直接指向3。

    此时,a与b同时指向3这个值,自然是相等的。

    关于基础类型与引用类型的底层比较,可稍微延伸一下:对于“==”操作符号,JVM会根据其两边相互比较的操作数的类型,在编译时生成不同的指令:

    (1)对于boolean,byte、short、int、long这种整形操作数会生成if_icmpne指令。该指令用于比较整形数值是否相等。

    (2)如果操作数是对象的话,编译器则会生成if_acmpne指令,与if_icmpne相比将i(int)改成了a(object reference)。

    回归正题

    学习了上面的底层理论知识,我们基本上可以得出如下结论:(1)两个int类型比较,直接使用双等号即可;(2)int的包装类Integer对象比较时,使用equals进行比较即可。

    但是这并不能说明所有问题,还涉及到整形的装箱拆箱操作、Integer的缓存。我们下面逐一分析。

    不同创建形式的比较

    先看Integer的初始化,根据Integer的内部实现,创建Integer有三种,分别是:

    Integer a = new Integer(1); //创建新的类
    
    Integer b = Integer.valueOf(2);  
    
    Integer c = 3; //自动包装,会调用valueOf方法
    

    其中直接赋值底层会调用valueOf方法进行操作的,因此这两种操作效果是一样的。

    因为通过new和valueOf创建的是完全两个对象,那么针对题目中的 i3 == i4 项,直接比较两个对象的引用肯定是不相等的,因此结果为false。但 i1 == i3项为什么为true呢?后面我们会讲到。

    比较中的拆箱

    在题目中,我们发现 i1 == i2i2 == i4 都为true,而且它们的比较格式都是基础类型与包装类型的对比。

    针对这种形式的对比,包装类型会进行自动拆箱,变成基础类型(int)。很显然,结果是相等的。当然,这种比较时候要注意NPE问题,又是另外一个话题了。

    Integer的缓存
    为什么i1和i3相等,但i5和i6却不相等呢?对应题目中的B和G项。这里就涉及到Integer的缓存机制。

    我们上面已经知道,Integer直接赋值和valueOf是等效的,那先看一下valueOf及相关的方法。

    public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }
    private static class IntegerCache {
            static final int low = -128;
            static final int high;
            static final Integer cache[];
            static {
                // high value may be configured by property
                int h = 127;
                String integerCacheHighPropValue = sum.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
                if (integerCacheHighPropValue != null) {
                    try {
                        int i = parseInt(integerCacheHighPropValue);
                        i = Math.max(i, 127);
                        // Maximum array size is Integer.MAX_VALUE
                        h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
                    } catch( NumberFormatException nfe) {
                        // If the property cannot be parsed into an int, ignore it.
                    }
                }
                high = h;
                cache = new Integer[(high - low) + 1];
                int j = low;
                for(int k = 0; k < cache.length; k++)
                    cache[k] = new Integer(j++);
                assert IntegerCache.high >= 127;
            }
            private IntegerCache() {}
        }
    

    valueOf方法判断数字是否大于low(-128)并且小于high(127),如果满足条件,则直接从IntegerCache中返回对应数字。

    IntegerCache用于存储一些常用的数,防止重复创建,在Integer类装入内存时通过静态代码进行初始化。

    所以只要是用valueOf或者Integer直接赋值的方式创建的对象,其值小于127且大于-128的,无论对其进行==比较还是equals 比较,都是true。

    上面的源码及原理也解释了阿里Java开发手册中所说明的原因。

    为什么equals可以规避问题

    对于不满足-128到127范围的数,无论通过什么方式创建,都会创建一个新的对象,只能通过equals进行比较。接下来我们再看看equals方法。

    public boolean equals(Object obj) {
        if (obj instanceof Integer) {
            return value == ((Integer)obj).intValue();
        }
        return false;
    }
    

    equals实现比较简单,先比较类型是否一致,如果不一致,直接返回false;否则,再比较两者的值,相同则返回true。

    小结

    关于Integer的比较核心点有以下三点:引用对象的存储结构、Integer的缓存机制、自动装箱与拆箱。

    Integer在==运算时,总结一下:

    (1)如果==两端有一个是基础类型(int),则会发生自动拆箱操作,这时比较的是值。

    (2)如果==两端都是包装类型(Integer),则不会自动拆箱,首先会面临缓存问题,即便在缓存范围内的数据还会再次面临创建方式的问题,因此强烈建议使用equals方法进行比较。

    原文来自: https://cloud.tencent.com/developer/article/1688593

    展开全文
  • Integer

    千次阅读 2016-10-11 23:35:27
    Interger:整数类型 1、属性。 static int MAX_VALUE:返回最大的整型数;  static int MIN_VALUE:返回最小的整型数;...System.out.println(“Integer.MAX_VALUE: ” + Integer.MAX_VALUE );  结果为:In
  • Integer比较大小

    千次阅读 2021-03-17 15:21:32
    Integer比较大小java的两种类型:● 基本类型基本数据类类型存的是数值本身●引用类型引用类型变量在内存放的是数据的引用基本类型通过==比较的是他们的值大小,而引用类型比较的是他们的内存地址正文在一些特殊的类...
  • java Integer常用方法详解

    千次阅读 2019-08-27 11:50:28
    先来Integer吧 package com.String; //封装类 /* * 比如int对应的类是Integer 这种类就叫做封装类 */ public class Damo { static void m1() { // Integer 的构造函数 Integer it1 = new Integer(5);// ...
  • Java中的Integer

    千次阅读 2021-02-26 10:07:58
    包装类———IntegerInteger 类在对象中包装了一个基本类型int的值。Integer类型的对象包含一个 int 类型的字段。此外,该类提供了多个方法,能在 int 类型和 String 类型之间互相转换,同时还提供了其他一些处理int...
  • Integer 类型对象之间大小比较

    千次阅读 2021-03-08 10:33:34
    一.Integer 类型对象之间大小比较1. 使用 new Integer() 创建的对象 :首先,我们知道,在java中,基本类型之间是可以做大小比较的,例如int i=1,int j=2,是可以直接使用关系运算符“”、“==”等符号来做比较的。但...
  • Integer

    千次阅读 2018-04-18 17:59:17
    Integer类:基本数据类型和对应的包装类类型、Integer包装类的构造方法、int类型和String类型之间的转换、Integer包装类的其他成员方法、Integer包装类的进制转换、Integer包装类的自动拆装箱原理、Integer包装类的...
  • Integer与Int

    万次阅读 多人点赞 2019-06-15 19:55:00
    在进行描述之前先给出下面代码,观测结果: package ... /** * created by LMR on 2019/6/15 */ public class IntegetTest { ... public static void main(String[] args) { Integer i = 10; Inte...
  • Integer与int的区别

    千次阅读 2022-01-17 14:55:29
    Integer与int的区别
  • Integer详解

    千次阅读 2021-11-24 21:09:12
    Integer 简介 Integer 类在对象中包装了一个基本类型 int 的值。Integer 类对象包含一个 int 类型的字段。此外,该类提供了多个方法,能在 int 类型和 String 类型之间互相转换,还提供了处理 int 类型时非常有用的...
  • Java Integer类型比较问题

    万次阅读 2021-05-07 10:22:09
    Java Integer类型比较问题 【强制】所有整型包装类对象之间值的比较,全部使用 equals 方法比较。 说明:对于 Integer var = ? 在-128至127范围内的赋值,Integer 对象是在 IntegerCache.cache产生,会复用已有对象...
  • Integer类型比较

    千次阅读 2021-10-26 10:29:21
    比较两个Integer类型的值是否相等 2、equals方法: 两个Integer类型的数值比较不能使用==比较 应该使用.equals进行比较 注意在使用equals方法前对equals前面的对象进行判空处理 3、Integer中重写了equals方法...
  • Integer.valueOf和new Integer的区别

    千次阅读 2022-02-16 13:16:46
    Integer currentVersion = new Integer(1); 此时sonar报错,并建议使用Integer.valueOf()方法: Constructors forString,BigInteger,BigDecimaland the objects used to wrap primitives should never be used. ...
  • JDK源码阅读之Integer

    千次阅读 2019-08-20 14:51:41
    我们在学习对象的自动装箱和自动拆箱时首次接触的就是Integer类。同时我们知道如果新建小数字对象其实是同一个对象,那么这之中的奥秘是什么呢?现在我们从源码的角度剖析一下吧!
  • java - 将Integer转换为Long

    千次阅读 2021-02-27 21:32:21
    java - 将Integer转换为Long我需要使用反射来获取字段的值。 碰巧我并不总是确定该字段的数据类型是什么。 为此,为了避免一些代码重复,我创建了以下方法:@SuppressWarnings("unchecked")private static T ...
  • integer是不是关键字要看看是什么语言,每种语言不一样,例如 integer 是 delphi的保留字 却不是 c语言的保留字。Integer为什么不是Java关键字?Integer 是数据类型不是C的关键字,它就一个英文单词,本意为整数,可...
  • int和Integer有什么区别

    千次阅读 多人点赞 2021-07-02 14:18:56
    面试中会问道int和Integer的区别,这里我们详细说一下 Integer是int的包装类;int是基本数据类型。 Integer变量必须实例化后才能使用;int变量不需要。 Integer实际是对象的引用,当new一个Integer时,实际上是...
  • 从 Int 到 Integer 对象,细细品来还是有不少东西

    千次阅读 多人点赞 2019-09-29 09:24:31
    int 是 Java 八大原始类型之一,是 Java 语言中为数不多不是对象的东西,Integer 是 int 的包装类,里面使用了一个 int 类型的变量来存储数据,提供了一些整数之间的常用操作,常规性的介绍就这么一点,程序员不喜欢...
  • Java中的Integer

    万次阅读 多人点赞 2019-05-03 15:20:27
    常见对象(Integer类的概述和构造方法) 如果有两个需求: 需求: a: 将100转换成二进制, 八进制, 十六进制 b: 判断一个数是否在int的范围内 当然,可以使用最基本的方法累除来求一个十进制数的其他进制,也可以...
  • Integer和int区别

    千次阅读 2022-04-06 17:43:37
    1、Integer是int的包装类,int则是java的一种基本数据类型 2、Integer变量必须实例化才能使用,int变量不需要实例化 3、Integer的默认值是null,而int的默认值是0 4、Integer实际是一个对象的引用,当new一个Integer...
  • JAVA Integer类型自加

    千次阅读 2021-02-13 02:13:09
    这些数据类型可以支持一些运算操作符,其中对于int类型的++/--操作符Integer类型是一个对象类型,居然也可以支持++运算,那么问题来了一个Integer对象执行++操作之后还是原来那个对象吗?测试代码public class ...
  • 在Java中将Double转换为Integer

    千次阅读 2021-02-27 12:37:36
    您无法直接将 Integer 转换为 Double 对象 . 此外 Double 和 Integer 是不可变对象,因此您无法以任何方式修改它们 .每个数字 class 都有 primitive 替代( Double vs double , Integer vs int ,...) . 请注意,...
  • Integer的最大值

    千次阅读 2021-02-12 22:20:53
    for循环运行到 i = Integer.MAX_VALUE ,即 i = 2147483647,i再加1,就变成了-2147483648 (这个地方明白源码,反码,补码的同学已经懂了吧,不明白的等我详细的整理一个专题或者留言询问……请关注我) 这个...
  • 用Java将Double转换为Integer

    千次阅读 2021-02-12 16:18:32
    您不能直接将投射Integer到Double对象。并且Double和Integer是不可变的对象,因此您不能以任何方式修改它们。每个数字类都有一个原始的替代项(Doublevs double,Integervs int,...)。请注意,这些原语以小写字母...
  • integer表示的最大整数

    千次阅读 2021-05-05 01:55:02
    Integer类型的变量可能存在的最大整数为? A.256 BInteger类的数据范围为,最小值为 -2^31,最大值为 2^31-1; 验证如下,创建java类TestInteger,做测试验证用,编写java代码,创建Integer对象,值为256,数据可以...
  • 源码看JAVA【八】Integer

    千次阅读 2019-02-27 23:44:59
    int mag = Integer.SIZE - Integer.numberOfLeadingZeros(val); int chars = Math.max(((mag + (shift - 1)) / shift), 1); char[] buf = new char[chars]; formatUnsignedInt(val, shift, buf, 0, chars); /...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,722,571
精华内容 1,089,028
关键字:

integer

友情链接: MMSAUTO2010.rar