《Java编程的逻辑》笔记26--剖析包装类 (上)

作者: 天一方蓝 | 来源:发表于2019-06-26 22:11 被阅读5次
    剖析包装类 (上).png

    包装类是什么呢?

    它是一个类,内部有一个实例变量,保存对应的基本类型的值, 这个类一般还有一些静态方法、静态变量和实例方法,以方便对数据进行操作。

    • 八种基本类型,对应的包装类


      image.png

    基本类型和包装类

    • 装箱
      将基本类型转换为包装类的过程
    • 拆箱
      将包装类型转换为基本类型的过程
      自动装箱和拆箱
      Java 1.5以后引入,可以直接将基本类型赋值给引用类型,反之亦可
    Integer a = 100; 
    int b = a;
    
    Integer a = Integer.valueOf(100);
    int b = a.intValue();
    

    自动装箱/拆箱是Java编译器提供的能力,背后,它会替换为调用对应的valueOf()/xxxValue()
    可以通过new创建

    Integer a = new Integer(100);
    Boolean b = new Boolean(true);
    Double d = new Double(12.345);
    Character c = new Character('马');
    

    那到底应该用静态的valueOf方法,还是使用new呢?
    般建议使用valueOf
    new每次都会创建一个新对象,而除了Float和Double外的其他包装类, 都会缓存包装类对象,减少需要创建对象的次数,节省空间,提升性能

    重写Object方法

    • equals
      equals用于判断当前对象和参数传入的对象是否相同,Object类的默认实现是比较址, 对于两个变量,只有这两个变量指向同一个对象时,equals才返回true,它和比较运算符(==)的结果是一样的。
      equals应该反映的是对象间的逻辑相等关系
      Long
    public boolean equals(Object obj) {
        if (obj instanceof Long) {
            return value == ((Long)obj).longValue();
        }
        return false;
    }
    

    Float

    public boolean equals(Object obj) {
        return (obj instanceof Float)
               && (floatToIntBits(((Float)obj).value) == floatToIntBits(value));
    }
    

    Float有一个静态方法floatToIntBits(),将float的二进制表示看做int。 需要注意的是,只有两个float的二进制表示完全一样的时候,equals才会返回true
    Double的equals方法与Float类似,它有一个静态方法doubleToLongBits,将double的二进制表示看做long,然后再按long比较,数值不精确

    • hashCode
      hashCode返回一个对象的哈希值,哈希值是一个int类型的数,由对象中一般不变的属性映射得来,用于快速对对象进行区分、分组等。一个对象的哈希值不能变,相同对象的哈希值必须一样。不同对象的哈希值一般应不同,但这不是必须的,可以有不同对象但哈希值相同的情况。
      hashCode和equals方法联系密切,对两个对象,如果equals方法返回true,则hashCode也必须一样。反之不要求
      子类重写equals时,也必须重写hashCode
      之所以有这个约定,是因为Java API中很多类依赖于这个行为,尤其是集合中的一些类
      Byte, Short, Integer, Character,hashCode就是其内部值
    public int hashCode() {
        return (int)value;
    }
    

    Boolean

    public int hashCode() {
        return value ? 1231 : 1237;
    }
    

    Long

    public int hashCode() {
        return (int)(value ^ (value >>> 32));
    }
    

    是高32位与低32位进行位异或操作
    Float

    public int hashCode() {
        return floatToIntBits(value);
    }
    

    Double

    public int hashCode() {
        long bits = doubleToLongBits(value);
        return (int)(bits ^ (bits >>> 32));
    }
    
    • toString
      每个包装类也都重写了toString方法,返回对象的字符串表示
    • Comparable
      个包装类也都实现了Java API中的Comparable接口
    public interface Comparable<T> {
        public int compareTo(T o);
    }
    

    <T>是泛型语法,我们后续文章介绍,T表示比较的类型,由实现接口的类传入。 接口只有一个方法compareTo,当前对象与参数对象进行比较,在小于、等于、大于参数时,应分别返回-1,0,1
    对于Float和Double,存在和equals一样的问题,0.01和0.10.1相比的结果并不为0*

    • 包装类和String
      除了toString方法外,包装类还有一些其他与String相关的方法
    System.out.println(Integer.toBinaryString(12345)); //输出2进制
    System.out.println(Integer.toHexString(12345)); //输出16进制
    System.out.println(Integer.parseInt("3039", 16)); //按16进制解析
    
    11000000111001
    3039
    12345
    

    常用常量

    Boolean类型

    public static final Boolean TRUE = new Boolean(true);
    public static final Boolean FALSE = new Boolean(false)
    

    Integer

    public static final int   MIN_VALUE = 0x80000000;
    public static final int   MAX_VALUE = 0x7fffffff;
    

    Float和Double

    public static final double POSITIVE_INFINITY = 1.0 / 0.0;
    public static final double NEGATIVE_INFINITY = -1.0 / 0.0;
    public static final double NaN = 0.0d / 0.0;
    

    Number

    六种数值类型包装类有一个共同的父类Number
    抽象类
    方法

    byte byteValue()
    short shortValue()                
    int intValue()
    long longValue()
    float floatValue()
    double doubleValue()
    

    不可变性
    包装类都是不可变类
    这是通过如下方式强制实现的:
    所有包装类都声明为了final,不能被继承
    内部基本类型值是私有的,且声明为了final
    没有定义setter方法
    不可变使得程序可以更为简单安全,因为不用操心数据被意外改写的可能了,可以安全的共享数据,尤其是在多线程的环境下

    相关文章

      网友评论

        本文标题:《Java编程的逻辑》笔记26--剖析包装类 (上)

        本文链接:https://www.haomeiwen.com/subject/wgkfcctx.html