zoukankan      html  css  js  c++  java
  • int与Integer

    int是基本数据类型,默认值为0;Integer是一个对象,默认值为null。(在实体类中尽量使用Integer修饰,Integer值存到数据库后可以区分出未赋值和值为0的区别)

    一、  int就是我们常说的java八大(primitive types : blooean、 byte 、 short 、 char 、int 、 float 、 double 、 long)原始数据类型之一。java虽然号称一切皆对象但是基本数据类型是例外。

    【八种基本数据类型的包装类】

    byte ——Byte

    short ——Short

    int ——Integer

    long-----Long

    float-----Float

    double----Double 

    char----Character

    boolean---Boolean

    4.2.1. Integral Types and Values

    The values of the integral types are integers in the following ranges:

    • For byte, from -128 to 127, inclusive
    • For short, from -32768 to 32767, inclusive
    • For int, from -2147483648 to 2147483647, inclusive
    • For long, from -9223372036854775808 to 9223372036854775807, inclusive
    • For char, from 'u0000' to 'uffff' inclusive, that is, from 0 to 65535

     

    Integer是int对应的包装类,在 Java 5 中,引入了自动装箱和自动拆箱功能(boxing/unboxing),Java 可以根据上下文,自动进行转换,极大地简化了相关编程。

    关于 Integer 的值缓存,这涉及 Java 5 中另一个改进。构建 Integer 对象的传统方式是直接调用构造器,直接 new 一个对象。但是根据实践,我们发现大部分数据操作都是集中在有限的、较小的数值范围,因而,在 Java 5 中新增了静态工厂方法 valueOf,在调用它的时候会利用一个缓存机制,带来了明显的性能改进。按照 Javadoc,这个值默认缓存是 -128 到 127 之间。

     

     

    二、那么为什么会有这个设计呢?

          原始数据类型和 Java 泛型并不能配合使用,也就是Primitive Types 和Generic 不能混用,于是JAVA就设计了这个auto-boxing/unboxing机制,实际上就是primitive value 与 object之间的隐式转换机制,否则要是没有这个机制,开发者就必须每次手动显示转换,那多麻烦是不是?但是primitive value 与 object各自有各自的优势,primitive value在内存中存的是值,所以找到primitive value的内存位置,就可以获得值;不像object存的是reference,找到object的内存位置,还要根据reference找下一个内存空间,要产生更多的IO,所以计算性能比primitive value差,但是object具备generic的能力,更抽象,解决业务问题编程效率高。于是JAVA设计者的初衷估计是这样的:如果开发者要做计算,就应该使用primitive value如果开发者要处理业务问题,就应该使用object,采用Generic机制;反正JAVA有auto-boxing/unboxing机制,对开发者来讲也不需要注意什么。然后为了弥补object计算能力的不足,还设计了static valueOf()方法提供缓存机制,算是一个弥补。

     

     

    三、再说一下关于缓存的问题

    关于 Integer 的值缓存,这涉及 Java 5 中另一个改进。构建 Integer 对象的传统方式是直接调用构造器,直接 new 一个对象。但是根据实践,我们发现大部分数据操作都是集中在有限的、较小的数值范围,因而,在 Java 5 中新增了静态工厂方法 valueOf,在调用它的时候会利用一个缓存机制,带来了明显的性能改进。按照 Javadoc,这个值默认缓存是 -128 到 127 之间。

    源码:[

    This method will always cache values in the range -128 to 127,

    * inclusive, and may cache other values outside of this range.

     

    public static Integer valueOf(int i) {

    if (i >= IntegerCache.low && i <= IntegerCache.high)

    return IntegerCache.cache[i + (-IntegerCache.low)];

    return new Integer(i);

    }

    ]

    面试题:

    Integer i1=123;

    Integer i2=123;

    System.out.println(i1==i2);//true

    Integer i3=128;

    Integer i4=128;

    System.out.println(i3==i4);//false

    解析:“==”对于引用类型比较的是对象地址是否相同,

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

    Integer i1=new Integer(123);

    Integer i2=new Integer(123);

    System.out.println(123==i1);//true

    System.out.println(i1==i2);//false

     

    Integer i3=new Integer(128);

    Integer i4=new Integer(128);

    System.out.println(i3==i4);//false

    System.out.println(128==i3);//true

    解析:以上结果说明:

    a.当数值范围为-128~127时:如果两个new出来Integer对象,即使值相同,通过“==”比较结果为false,但两个对象直接赋值,则通过“==”比较结果为“true,这一点与String非常相似。

    b.当数值不在-128~127时,无论通过哪种方式,即使两个对象的值相等,通过“==”比较,其结果为false;

    c.当一个Integer对象直接与一个int基本数据类型通过“==”比较,其结果与第一点相同;

    d.Integer对象的hash值为数值本身;

     

    源码:/** 

    1.    * Returns a hash code for this {@code Integer}. 
    2.    * 
    3.    * @return  a hash code value for this object, equal to the 
    4.    *          primitive {@code int} value represented by this 
    5.    *          {@code Integer} object. 
    6.    */  
    7.   public int hashCode() {  
    8.       return value;  
    9.   }  

    Integer重写了hashCode方法,返回值是value,即Integer对象 的数值。

     

    第二个问题,为什么Integer对象的范围是-128~127?

    查看Integer类源码,发现里面有一个私有的静态内部类IntegerCache,而如果直接将一个基本数据类型的值赋给Integer对象,则会发生自动装箱,其原理就是通过调用Integer类的public static Integer valueOf(将int类型的值包装到一个对象中 ,其部分源码如下:

    1. /** 
    2.     * Cache to support the object identity semantics of autoboxing for values between 
    3.     * -128 and 127 (inclusive) as required by JLS. 
    4.     * 
    5.     * The cache is initialized on first usage.  The size of the cache 
    6.     * may be controlled by the -XX:AutoBoxCacheMax=<size> option. 
    7.     * During VM initialization, java.lang.Integer.IntegerCache.high property 
    8.     * may be set and saved in the private system properties in the 
    9.     * sun.misc.VM class. 
    10.     */  
    11.   
    12.    private static class IntegerCache {  
    13.        static final int low = -128;  
    14.        static final int high;  
    15.        static final Integer cache[];  
    16.   
    17.        static {  
    18.            // high value may be configured by property  
    19.            int h = 127;  
    20.            String integerCacheHighPropValue =  
    21.                sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");  
    22.            if (integerCacheHighPropValue != null) {  
    23.                int i = parseInt(integerCacheHighPropValue);  
    24.                i = Math.max(i, 127);  
    25.                // Maximum array size is Integer.MAX_VALUE  
    26.                h = Math.min(i, Integer.MAX_VALUE - (-low) -1);  
    27.            }  
    28.            high = h;  
    29.   
    30.            cache = new Integer[(high - low) + 1];  
    31.            int j = low;  
    32.            for(int k = 0; k < cache.length; k++)  
    33.                cache[k] = new Integer(j++);  
    34.        }  
    35.   
    36.        private IntegerCache() {}  
    37.    }  
    38.   ..................  
    39.  ...................  
    40.  ...................  
    41.   
    42.      /** 
    43.     * Returns an {@code Integer} instance representing the specified 
    44.     * {@code int} value.  If a new {@code Integer} instance is not 
    45.     * required, this method should generally be used in preference to 
    46.     * the constructor {@link #Integer(int)}, as this method is likely 
    47.     * to yield significantly better space and time performance by 
    48.     * caching frequently requested values. 
    49.     * 
    50.     * This method will always cache values in the range -128 to 127, 
    51.     * inclusive, and may cache other values outside of this range. 
    52.     * 
    53.     * @param  i an {@code int} value. 
    54.     * @return an {@code Integer} instance representing {@code i}. 
    55.     * @since  1.5 
    56.     */  
    57.    public static Integer valueOf(int i) {  
    58.        assert IntegerCache.high >= 127;  
    59.        if (i >= IntegerCache.low && i <= IntegerCache.high)  
    60.            return IntegerCache.cache[i + (-IntegerCache.low)];  
    61.        return new Integer(i);  
    62.    }  

    我想通过以上的分析,应该知道原因了吧,简要的说就是在Integer类中有一个静态内部类IntegerCache,在IntegerCache类中有一个Integer数组,用以缓存当数值范围为-128~127时的Integer对象。

    注意:可以通过下面这个参数设置最大值

    -XX:AutoBoxCacheMax

    这个属性是在使用Oracle/Sun JDK 6,在server模式下,使用-XX:AutoBoxCacheMax=NNN参数即可将Integer的自动缓存区间设置为[-128,NNN]。注意区间的下界固定在-128不可配置。 

    在client模式下该参数无效。这个参数是server模式专有的,在c2_globals.hpp中声明,默认值是128;不过这个默认值在默认条件下不起作用,要手动设置它的值或者是开启-XX:+AggressiveOpts参数才起作用。

    Cache to support the object identity semantics of autoboxing for values between

    * -128 and 127 (inclusive) as required by JLS.

    *

    * The cache is initialized on first usage. The size of the cache

    * may be controlled by the {@code -XX:AutoBoxCacheMax=<size>} option.

    * During VM initialization, java.lang.Integer.IntegerCache.high property

    * may be set and saved in the private system properties in the

    * sun.misc.VM class.

    转自:https://blog.csdn.net/yang_154116/article/details/81227073?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param

  • 相关阅读:
    H5调用本地摄像头[转]
    [转]把树莓派配置成无线路由器
    [转]Raspberry Pi做成路由器
    websocket for python
    HRMS(人力资源管理系统)-SaaS架构设计-概要设计实践
    HRMS(人力资源管理系统)-从单机应用到SaaS应用-架构分析(功能性、非功能性、关键约束)-下篇
    HRMS(人力资源管理系统)-从单机应用到SaaS应用-架构分析(功能性、非功能性、关键约束)-上篇
    系统架构-设计模式(适配器、观察者、代理、抽象工厂等)及架构模式(C/S、B/S、分布式、SOA、SaaS)(干货)
    HRMS(人力资源管理系统)-从单机应用到SaaS应用-系统介绍
    2018,全新出发(全力推动实现住有所居)
  • 原文地址:https://www.cnblogs.com/shenjiangwei/p/13773465.html
Copyright © 2011-2022 走看看