《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