Java基本类型-整型解读

来源:互联网 发布:多玩魔兽世界数据库 编辑:程序博客网 时间:2024/06/06 23:56

java的基本类型包括以下几类:

  • 整型 byte short int long
  • 浮点型 float double
  • 字符型 char
  • 布尔型 boolean

它们都有对应的包装类型(如果没有特殊说明,下面都是说包装类型),其中整型和浮点型的基类都是Number,并且都是现实了Comparable接口,下面的内容以Integer为例,Byte,Short,Integer,Long只有整型长度上的区别,其他都是类似的。

Integer内部结构

类的内部数据结构是很简单的,只是简单包含了一个基本类型数据,并且提供了一些对基本类型的常见操作。

public final class Integer extends Number implements Comparable<Integer> {    //more code...    /**     * The value of the <code>Integer</code>.     *     * @serial     */    private final int value;    //more code...}

Integer的hashCode、equals和Comparable接口

Integer实现了Comparable接口,内部只是简单使用value值进行比较。还实现了hashCode和equals方法,不过equals还是会进行类型的对比,这也是equal实现的一个基本原则。所以Integer和Long是无论如何都不会相等的。

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

Integer内部缓存对象

或许你看过一些面试题,使用==来比较进行包装类型的比较,有时候会返回true,这有点不合常理。这个可以通过源码来解释。以Integer它在内部预先定义了一小段Integer对象(见IntegerCache的实现,high的范围还可以通过系统参数java.lang.Integer.IntegerCache.high设置),并在valueOf调用时判断是否落在这个范围,如果范围合适,返回现成的对象。由于Integer是不变对象,所以它的复用是没有任何隐患的。

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

话虽如此,但这只是一个优化手段,平时是不应该使用==来进行判断对象是否相等的。

Integer和字符串的相互转换

整型和字符串的相互转换也是常用的功能。看一下Integer转换成字符串的源码。

    public static String toString(int i, int radix) {        if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)            radix = 10;        /* Use the faster version */        if (radix == 10) {            return toString(i);        }        char buf[] = new char[33];        boolean negative = (i < 0);        int charPos = 32;        if (!negative) {            i = -i;        }        while (i <= -radix) {            buf[charPos--] = digits[-(i % radix)];            i = i / radix;        }        buf[charPos] = digits[-i];        if (negative) {            buf[--charPos] = '-';        }        return new String(buf, charPos, (33 - charPos));    }

算法还是比较简单的,就是根据基数radix不断对这个整数取余数,根据余数找到从digits数组中找到对应字符。这里需要注意的是,
为什么正数要取反使用负数而不是反过来呢,用正数不是更好处理么?其实,这涉及到是否溢出的问题,对于最小的整数integer,取反就会出现移除,还是一个负数,这样就有问题了。

还有一个功能是把整数换成16进制(toHexString)、8进制(toOctalString)或2进制的字符串(toBinaryString),它最终是调用toUnsignedString实现的。

    /**     * Convert the integer to an unsigned number.     */    private static String toUnsignedString(int i, int shift) {        char[] buf = new char[32];        int charPos = 32;        int radix = 1 << shift;        int mask = radix - 1;        do {            buf[--charPos] = digits[i & mask];            i >>>= shift;        } while (i != 0);        return new String(buf, charPos, (32 - charPos));    }

以16进制为例子,shift就是4,得到的mark就是1111,i和mask做与运算后就可以得到在16进制中字符数组的位置,从而得到这4位对应的16进制字符,最后通过右移就抹掉这低4位。

Integer类中有许多方法是和位操作相关的。待后续详解。

0 0