JAVA基本数据类型

 

不管是java还是其他语言,都会有基本数据类型,这种类型更加方便常用。

在java中,基本数据类型直接存储在堆栈中

java有八种基本数据类型。六种数字类型(四个整数型,两个浮点型),一种字符类型,还有一种布尔型

基本类型大小最小值最大值包装器类型
boolean------Boolean
char16-bit\u0000(即为0)\uffff(即为65,535)

Character

byte8 bits-128+127Byte
short16 bits-2^15+2^15-1short
int 32 bits-2^31+2^31-1Integer
long64 bits-2^63+2^63-1Long
float32 bitsIEEE754IEEE754Float
double64 bitsIEEE754IEEE754Double

boolean

boolean类型只有两个值,true和false,包装类型是Boolean,里面的hashcode方法是

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

 

char

char是字符类型,有如下几种定义方式,可以用单引号直接定义,也可以用在char的取值范围内的数字定义,还可以用十六进制定义,还有就是用'\uxxxx'的形式定义

       char c1 = 'a';  //char 0 - 2^16-1
       char c2 = '中';
       char c3 = 20013;
       char c4 = 0x4e2d;
       char c5 = '\u4e2d';
       //char c4 = -1;
       System.out.println("next is about char ");
       System.out.println("==c1:"+Integer.toBinaryString(c1)+"==c2:"+Integer.toBinaryString(c2)+"==c4:"+Integer.toBinaryString(c4));
       System.out.println("===c1:"+c1+"===c2:"+c2+"===c1:(int)"+(int)c1+"===c2:(int)"+(int)c2+"===c3:"+c3+"===c4:"+c4+"===c5:"+c5);
       System.out.println(Character.hashCode(c1)+"=="+Character.hashCode(c2)+"=="+Character.hashCode(c3)+"=="+Character.hashCode(c4)+"=="+Character.hashCode(c5));
       

输出结果为

next is about char 
==c1:1100001==c2:100111000101101==c4:100111000101101
===c1:a===c2:中===c1:(int)97===c2:(int)20013===c3:中===c4:中===c5:中
97==20013==20013==20013==20013

上面可以得知不同的定义方式定义同一个字符结果是一样的,Character的hashcode方法得到的结果是它转为int的结果

//character的hashCode源码
public static int hashCode(char value) {
        return (int)value;
    }

byte

byte是由8位二进制组成的带符号的最小的数字类型。这里要说一下bit和byte的区别。

bit(比特)是表示信息的最小单位,就是一个二进制的的一位

byte由8 bit组成,是数据存储的基础单位,1Byte又称为一个字节,用一个字节(Byte)储存,可区别256个数字。

 

short

短整型,长度只有int型二分之一,节省空间

int

整型,32位,一般整型默认为int型

byte,short,int的hashcode都是转为int型的本身

//short,byte,int
public static int hashCode(char value) {
        return (int)value;
    }

 它们三个可以看作都是类似的,在范围内都可以互相转换。都可以通过Integer.toBinaryString(xxx)查看二进制

       byte by = 'a';
       System.out.println("next is about byte ");
       System.out.println(Byte.hashCode(by));
       System.out.println(by);
       System.out.println(Integer.toBinaryString(by));
       short s = 1;
       short s1 = -1;
       System.out.println("next is about short ");
       System.out.println(Integer.toBinaryString(s)+"=="+Integer.toBinaryString(s1));
       System.out.println(Short.hashCode(s)+"=="+Short.hashCode(s1));
       int i = 120;
       int i1 = -1;
       System.out.println("next is about int ");
       System.out.println(Integer.toBinaryString(i)+"=="+Integer.toBinaryString(i1));
       System.out.println(Integer.hashCode(i)+"=="+Integer.hashCode(i1));
next is about byte 
97
97
1100001
next is about short 
1==11111111111111111111111111111111
1==-1
next is about int 
1111000==11111111111111111111111111111111
120==-1

long

长整型,64位,它的hashcode是将值无符号右移32位再与本身异或得到的值,定义大于int型的数时需在后面加个l/L

/**
     * Returns a hash code for a {@code long} value; compatible with
     * {@code Long.hashCode()}.
     *
     * @param value the value to hash
     * @return a hash code value for a {@code long} value.
     * @since 1.8
     */
    public static int hashCode(long value) {
        return (int)(value ^ (value >>> 32));
    }

 

float

单精度浮点类型,32位组成,第一位是符号位,0表示正数。后八位是指数位,用来存储科学计数法中的指数数据,并且采用移位存储。最后23位数是尾数部分

如下三个数。1.5转为二进制数是1.1*2^0,指数位是0,第2-9位就是127+0也就是0111 1111 (指数计算需加上127)

小数点转为二进制是将其*2看其是否大于1,如大于1,则二进制数唯一,否则为0,大于1后取小数部分继续*2

float的hashcode最后是native函数。

这里介绍下native修饰符:

总所周知java是一门跨平台语言,java的跨平台是怎么实现的呢,就是这个native关键字。native关键字的函数都是操作系统实现的, java只能调用,所以java的底层实际上就是在不同的平台上调用不同的native方法实现对操作系统的访问的。当我们看java源码的时候看到这个native就知道这个已经不是java语言能干的事了。

       float f = 1.5f; // 0 0111 1111 1000 0000 0000 .... 直到一共32位 3fc00000
       float f1 = -1.3f; // 1 0111 1111 0100 1100 1100 1100 .... 直到一共32位 bfa66666
       float f2 = -100.3f; // 1 1000 0101 1001 0001 0011 0011 .... 直到一共32位 0110 0100.0100 1100 1100 1100
       float f3 = 0xC2C89999;
       float f4 = 0x3fc00000;
       System.out.println("next is about float ");
       System.out.println(Float.toHexString(f)+"=="+Float.toHexString(f1)+"=="+Float.toHexString(f2));
       System.out.println(Float.hashCode(f)+"=="+Float.hashCode(f1)+"=="+Float.hashCode(f2));
       System.out.println(f3+"==="+f4+"=="+Float.intBitsToFloat(Integer.parseInt("3fc00000",16)));

结果中可以看到想将二进制转为其本身可以用Float.intBitsToFloat(Integer.parseInt("3fc00000",16))的方法,不过此方法受限于parseInt。直接使用二进制表示不出想要的浮点数。

next is about float 
0x1.8p0==-0x1.4cccccp0==-0x1.913334p6
1069547520==-1079613850==-1027040870
-1.0270409E9===1.06954752E9==1.5

double

双精度浮点类型,64位。与单精度类似,第一位是符号位,不过指数位有11位,最后52位数尾数部分

计算也与单精度类似,不过指数位是加上1023这个偏差值,毕竟他是11位。

它的hashcode简单的讲就跟long的差不多,不过是多了long bits = doubleToLongBits(value);这个最后也是个native修饰符

/**
     * Returns a hash code for a {@code double} value; compatible with
     * {@code Double.hashCode()}.
     *
     * @param value the value to hash
     * @return a hash code value for a {@code double} value.
     * @since 1.8
     */
    public static int hashCode(double value) {
        long bits = doubleToLongBits(value);
        return (int)(bits ^ (bits >>> 32));
    }

包装类

每个基本类型都有其包装类,我们知道java的一种思想就是一切皆对象,那么包装类的作用就是将基本数据类型转为一个对象

        Integer i = 2;//装箱
        int j = i;//拆箱

 看下面一段代码

        Integer x = new Integer(123);
        Integer y = new Integer(123);
        System.out.println(x==y); //false
        Integer z = Integer.valueOf(123);
        Integer k = Integer.valueOf(123);
        System.out.println(z==k); //true
        Integer i1 = Integer.valueOf(128);
        Integer i2 = Integer.valueOf(128);
        System.out.println(i1==i2); //false

 第一个new是新建了一个对象,所以两个不同。第二个一样,那第三个怎么不一样?原因是Integer.valueOf()会先判断值是否在缓冲池中,在的话直接返回缓冲池的内容,不是再新建个。Integer的缓冲池大小是-128到127。还有就是java9后就不建议使用new Integer()的方法。可以看到下方源码建议我们使用valueOf的方法。而且valueOf中@HotSpotIntrinsicCandidate这个注解在HotSpot中都有一套高效的实现,该高效实现基于CPU指令

 /**
     * Constructs a newly allocated {@code Integer} object that
     * represents the specified {@code int} value.
     *
     * @param   value   the value to be represented by the
     *                  {@code Integer} object.
     *
     * @deprecated
     * It is rarely appropriate to use this constructor. The static factory
     * {@link #valueOf(int)} is generally a better choice, as it is
     * likely to yield significantly better space and time performance.
     */
    @Deprecated(since="9")
    public Integer(int value) {
        this.value = value;
    }
    @HotSpotIntrinsicCandidate
    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 Integer[] archivedCache;

        static {
            // high value may be configured by property
            int h = 127;
            String integerCacheHighPropValue =
                VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            if (integerCacheHighPropValue != null) {
                try {
                    h = Math.max(parseInt(integerCacheHighPropValue), 127);
                    // Maximum array size is Integer.MAX_VALUE
                    h = Math.min(h, Integer.MAX_VALUE - (-low) -1);
                } catch( NumberFormatException nfe) {
                    // If the property cannot be parsed into an int, ignore it.
                }
            }
            high = h;

            // Load IntegerCache.archivedCache from archive, if possible
            VM.initializeFromArchive(IntegerCache.class);
            int size = (high - low) + 1;

            // Use the archived cache if it exists and is large enough
            if (archivedCache == null || size > archivedCache.length) {
                Integer[] c = new Integer[size];
                int j = low;
                for(int i = 0; i < c.length; i++) {
                    c[i] = new Integer(j++);
                }
                archivedCache = c;
            }
            cache = archivedCache;
            // range [-128, 127] must be interned (JLS7 5.1.7)
            assert IntegerCache.high >= 127;
        }

        private IntegerCache() {}
    }

关于缓冲池Boolean是true和false,四个整数型(Byte,Short,Integer,Long)都是-128到127。 Character是\u0000 到 \u007F

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值