Java数据类型

Java数据类型

Java数据类型分为两个大类:基本数据类型和引用数据类型
基本数据类型
Java语言提供了八种基本类型
基本类型中的,数字类型默认值为0,布尔类型默认值为false
byte
*byte数据类型是8位
*最大值为127(2^7-1)
*最小值为-128(-2^7)
short
*short数据类型是16位
*最小值为-2^15
*最大值为2^15-1
int
*int数据类型有32位

  • 最小值为-2^31
  • 最大值为2^31-1
    long
    *long的数据类型为64位
    *最小值为-2^61
    *最大值为2^61-1
    *这与前面的有区别,定义的时候要有L
    *long a=10L
    float
    *float数据类型是单精度32位,浮点类型
    *float f=12.3f
    double
    *double是双精度类型64位
    *double d=1234.5
  • 这个要写d不写都可以,浮点类型默认是double类型的
    boolean
    *只有true和false两个值,默认值是false
    char
    char是16位的Unicode字符
    引用类型
    在Java中,应用类型指向一个对象,指向对象的变量是引用变量
    除了基本数据类型,其他的都是引用数据类型,比如:数组
    引用数据类型的默认值都是null

自动装箱和拆箱

基本数据类型都有与之对应的包装类型,Java 5 增加了自动装箱和自动拆箱的机制,方便基本数据类型和包装类型互相转换。
在Java 5 之前,我们要创建一个Integer的包装类型(int的对应的包装类型为Integer)只能

Integet a = new Integer(20);

或者

Integet a = Integer.valueOf(20);

但是在Java 5 以及之后,我们可以做这么写

Integet a = 20;

这里的20默认就是int类型的,这里默认就是采用自动装箱的机制,把int类型转换成Integer类型的数据,反之如果把Integer转换成int就叫作拆箱。
Java 5 之后可以把int型数据,直接赋给Integer对象。
自动装箱和自动拆箱为程序员提供了很大的方便,提高了开发的效率。

装箱和拆箱的实现
包装类型中都有两个方法
第一个是valueOf():把给定的基本数据类型转换成对应的包装类型

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

上面是jdk中Integer的Integer 中valueOf方法,给方法传一个int 类型的名字叫i的参数,方法最后返回的是Integer类型的参数。
第二个是xxxValue()方法:将包装类型转换成对应额基本数据类型
类看看jdk中是怎么定义的

    public int intValue() {
        return value;
    }

   private final int value;

    /**
     * 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.
     */
    public Integer(int value) {
        this.value = value;
    }

我们可以看到返回的value是int类型的
具体来分析一下Integer的部分源代码

public final class Integer extends Number implements Comparable<Integer> {
//一进来就定义了int类型的最大值和最小值
//@Native表示java与其他语言的调用
 @Native public static final int   MIN_VALUE = 0x80000000;
 @Native public static final int   MAX_VALUE = 0x7fffffff;
 //这里定义了一个静态的内部类IntegerCache
 private static class IntegerCache {
        static final int low = -128;
        static final int high;
        static final Integer cache[];

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

            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);

            // range [-128, 127] must be interned (JLS7 5.1.7)
            assert IntegerCache.high >= 127;
        }

        private IntegerCache() {}
    }
    //valueOf方法
        public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }
    //一个value常量
     private final int value;
     //一个构造器
     public Integer(int value) {
        this.value = value;
    }
     //拆箱调用的函数
    public int intValue() {
        return value;
    }

 }

为什么定义了静态内部类
内部类缓存了从[low,high]的Integer对象,也就是从[-128,127],还有一个Integer类型的数组cache[],这个数组就是用来放这些Integer对象的。
valueOf方法
valueOf方法,是用来把int转成Integer的
方法内部首先去判断这个传进来的int的大小,范围是不是落在了[-128,127],如果在这里面,就直接去调用内部类中的cache[]数组,把对应的Integer对象取出来。如果不在这个范围里面,就new Integer(i),调用Integer的有参构造创新新的Integer对象。所以落在-128到127之间,是不会再去创建新对象的,这里是做题的一个坑。
有参构造器
会把要装箱的int,放在常量value中,拆箱的时候直接把这个常量返回出来就可以了
包装类型中,Integer,Byte,Short,Long复用了[-128,127]这些对象,而Charater复用了[0,127]不能表示负数。

基本数据类型类型的存储方式

这里就得稍微分析一下虚拟机的内存区域
这里主要讲一讲运行时数据区
在这里插入图片描述
运行时数据区包含了,方法区,虚拟机栈,本地方法区,堆,程序计数器
程序计数器(或者叫指令计数器)
程序计数器的作用就是,当前线程的行号指示器。
每一个线程都有自己的程序计数器,程序计数器是线程私有的。为了就是在多线程环境下,记录线程暂停时运行到哪一行了,切换线程时才能正确的恢复正确的执行位置。
虚拟机栈(简称栈)
虚拟机栈是用来描述Java方法执行的内存模型。每一个方法在执行时,都会创建一个栈帧,用于存储局部变量表,操作数栈,动态链接,方法出口等信息。每一个方法的调用到执行结束,就对应着栈帧在虚拟机栈中的入栈到出栈的过程。
局部变量表:用于存放基本数据类型、对象引用、returnAddress类型(指向一条字节码指令的地址)
操作数栈:虚拟机栈中用于计算的临时数据存储区

public int test1(){
		int a=6+10;
		int b=a+5;
		return b;
	}

int a=6+10;
编译过程中已经计算了6+10=16,把16压入操作数栈的栈顶,然后把16从操作数栈中弹出来放入局部变量表索引为1的slot
int b=a+5;
把a也就是局部变量表中索引为1的slot,重新压入操作数栈中,然后再把3压入操作数栈中,将栈顶的这两个弹出并进行加法运算后再压入操作数栈顶,然后从栈顶弹出来放入操作数栈中索引为2的slot
这就是操作数栈的具体运算。
本地方法栈
这个本地方法区与虚拟机栈有些类似,虚拟机栈为执行Java方法服务。而本地方法栈为的是执行Native方法服务。

堆是用于存放对象实例的,几乎所有的对象实例都在这里分配内存。所有线程共享
方法区
方法区是用于存放已经被虚拟机加载的类信息,常量,静态变量以及即时编译器编译后的代码等数据。
即时编译器:用于把Java字节码转换成可以直接发送给处理器的指令程序。

public voidint a){
int i=1int j=1}

这是一个方法,方法时放在虚拟机栈中的,变量则放在栈中的局部变量表,a,i,j都是放在局部变量表中

class A{
	int i=1;
	A a=new A();
}

这是一个类,类实例化的对象放在堆中,所以成员变量也在堆中,i和a也都在堆中
上面讲过的基本数据类型的包装类就是在常量池(对象池)中查找对应的对象,找不到再去常量池创建该对象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值