一、java的数据类型

java的数据类型分为两大类:

  • 八大基本数据类型
  • 整数类型
  • byte 占1个字节:-128 ~ 127
  • short 占2个字节:-32768 ~ 32767
  • int (常用)占4个字节:-2147483648 ~ 2147483647(21亿)
  • long 占8个字节:-9223372036854775808 ~ 9223372036854775807
  • 浮点类型
  • float 占4个字节
  • double常用)占8个字节
  • 字符类型 char 占2个字节
  • 布尔类型 只占1位
  • 引用数据类型 (除了基本数据类型,剩下的就是引用类型)
  • 接口
  • 数组、
//八大基本数据类型
        int num1 =10;
        byte num2= 100;
        short num3 =30;
        long num4=30L; //不加L没法区分是其他类型还是long类型
        
        float num5=5.12F;//加F,道理同上
        double num6=1.234567898765431;
        
        char c='你';
        
        boolean flag=true;

主要注意这两个:

java 一个数字多少字节 java中数字占几个字节_ico

 1. 整型拓展

//二进制0b    八进制0   十进制    十六进制0x
        int num1 =0b1010; //=(1×2×2×2)+(0×2×2)+(1×2)+0=10
        int num2 =0120;   //=(1×8×8)+(2×8)+0=80
        int num3 = 1234;  //=(1×10×10×10)+ (2×10×10)+(3×10)+4=1234
        int num4 = 0xfff; //(15×16×16)+(15×16)+15=4095

2.浮点型拓展

1)如下情况,在num1和num2都输出为0.1时,num1却不等于num2

float num1 = 0.1f;     //0.1
        double num2 = 1.0/10;  //0.1

        System.out.println(num1);  //0.1
        System.out.println(num2);  //0.1
        System.out.println(num1==num2); //flase

2)在num1和num2都输出为0.6时,num1却不等于num2

float num1 = 0.6f;     //0.6
        double num2 = 0.6;  //0.6

        System.out.println(num1);  //0.6
        System.out.println(num2);  //0.6
        System.out.println(num1==num2); //false

3)当num1和num2都输出为0.0625时,true

float num1 = 0.0625f;
        double num2 = 0.0625;

        System.out.println(num1);  //0.0625
        System.out.println(num2);  //0.0625
        System.out.println(num1==num2); //true

4)这种情况下却输出了true

float f1 = 212121212f;
        double d1 = f1+1;

        System.out.println(f1==d1);  //true

        究其原因,问题出在浮点数在计算机中的表示。我们以IEEE754标准的单精度浮点数格式为例,其表示方法如下:

java 一个数字多少字节 java中数字占几个字节_类型转换_02

        你会发现,这种表示方式只能表示刚刚好由2^(-n)组合起来的数:

k1×2^(-1) + k2×2^(-2) + k3×2^(-3) + k4×2^(-4)+...kn×2^(-n)           kn=0或1

        所以,这样是没法表示十进制的0.1的。只有0.59375这种“刚刚好”的数,才能用0.10011B表示出来。0.59376或者0.6都是没法表示的。

        也就是说,虽然我们的float和double能表示如下这么大范围的数,

java 一个数字多少字节 java中数字占几个字节_学习_03

离散的,中间有很多数都表示不了(比如0.1、0.6),只能以一个接近它的数去表示。

刚刚解释完了小数部分,那么对于例4)里的大数呢?怎么解释?

找一个接近但是不等于的数去表示它,所以也是离散的。

综上,我们得出一个结论,避免使用浮点数去进行数值比较

那么对于小数或者大额数字如何精确表示呢?经典场景就是微信支付和支付宝(或者银行业务),钱可不能近似表示

        用BigDecimal这个数学工具类。

3. 字符拓展

1)Unicode编码

java默认采用Unicode编码而不是ASCII,每一个字符都对应一个int型数值。只需要记住,字符的本质是数值

        Unicode包含了ASCII。也就是说,无论用ASCII编码还是Unicode编码,A-Z都对应65-90.

char a ='a';
        char b ='明';

        System.out.println((int)a);  //97
        System.out.println(a);  //a
        System.out.println((int)b); //26126
        System.out.println(b);  //明

java 一个数字多少字节 java中数字占几个字节_ico_04

         ASCII码只能表示英文,对于英美这样的国家足够了。Unicode编码占两个字节,最多可以表示65536个字符,对于汉语还是不够用(10万字左右)。Unicode只是一种概念编码,而UTF-8是其一种实现形式。

java 一个数字多少字节 java中数字占几个字节_类型转换_05

        因为我们使用汉语,一般使用UTF-8,UTF-8是可变长的编码,对于汉字占3个字节,足够汉语的使用了。

二、数据类型转换

        首先,将除布尔值以外的数据类型按照精度由低到高排列:

byte(1) -> short char(2) -> int(4) -> long(8) -> float (4) -> double(8)

自动类型转换:把级别低的类型赋值给级别高的类型时,自动完成类型转换

强制类型转换:反之,必须使用类型转换运算。此时可能导致①内存溢出②精度的损失

// 1.自动类型转换
        int a =50;
        double b = a;
        System.out.println(a);  //50
        System.out.println(b);  //50.0

        // 2.强制类型转换
        int c = 98;
        System.out.println((char)c);  //int->char的强制转换  //'b'
            // 1) 内存溢出问题---->byte截断int的低8位
        int d =128;
        byte e = (byte)d;
        System.out.println(e);  //-128

        int a = 128+256; // ...1_1000_0000
        byte b =(byte)a;
        System.out.println(b);  //-128
            // 2) 精度损失问题
        double f=123456786.3215498754;
        float ff=(float)f;
        System.out.println(ff);  //1.23456784E8

例1)

//JDK7的新特性,大数之间用下划线分割便于阅读
        int money=10_0000_0000;
        int year=20;

        int total1=money*year; //200亿,int最大表示21亿
        System.out.println(total1);

        long total2=money*year;
        System.out.println(total2);

        long total3=money*((long)year);
        System.out.println(total3);

java 一个数字多少字节 java中数字占几个字节_java 一个数字多少字节_06