乐趣区

基础篇java基本数据类型

1:java 几种根本数据类型大小

关键字 类型 位数 (8 位一字节) 取值范畴 (示意范畴)
byte 整型 8 -2^7 ~ 2^7-1
short 整型 16 -2^15 ~ 2^15-1
int 整型 32 -2^31 ~ 2^31-1
long 整型 64 -2^63 ~ 2^63-1
float 浮点数 32 3.402823e+38 ~ 1.401298e-45
double 浮点数 64 1.797693e+308~ 4.9000000e-324
char 文本型 16 0 ~ 2^16-1
boolean 布尔值 32/8 true/false

boolean 的占用大小是多少,有如下说法

  • 1bit: boolean 编译后的是应用 1 和 0 贮存,实践上只需 1bit 即可贮存
  • 1byte: 计算机解决数据的最小单位是 1byte, 用一字节的最低位存储,其余的用 0 填补。如果值是 true 则贮存二进制为 0000 0001,false 则是 0000 0000
  • 4byte or 1btye: java 虚拟机没有对 boolean 类型的专用字节码指令,表达式所操作的 boolean 在编译之后是应用 int 数据类型来代替的,而 boolean 数组则会被编译成 byte 数组

正解 在 java 里的正确答复应该是 boolean 类型独自应用是 4 个 byte, 在数组里则是 1 个 byte。然而虚拟机为什么不必 byte 或 short 代替 boolean 而是 int, 这样不是更节俭内存空间?因为 int 对于 32 位处理器,一次解决的数据是 32 位,CPU 寻址也是 32 位的查找,具备高效贮存的特点(如果有更好的了解,大家独特交换下)

2:64 位的 JVM 中,int 类型长度是多少

32 位;int 是 32 位类型,不会随着零碎或者 jvm 的位数而扭转

3:char 类型变量能不能贮存一个中文的汉字,为什么

中文 unicode 编码方式每个字符占用两个字节,char 是 16 位类型,中文贮存须要两个字节,因而能够贮存中文字符。

4:浮点数 float 和双精度浮点数 double 表示法

浮点数的二进制表示法由三局部组成

  • 符号位
  • 指数位
  • 尾数为

float、double 二进制构造

类型 符号位 指数位 (e) 尾数位 (m)
float 1 8 23
double 1 11 52
  • 符号位局部用来贮存数字符号,辨别正负数,0 正 1 负
  • 指数位贮存指数,指数也有正负,指数确定大小范畴

    • 指数是有符号的,但有符号整数比无符号整数计算麻烦,因而理论贮存是将指数转为无符号整数,8bit 的范畴为 0~255,实在的指数须要减去偏移量 127。范畴在(-126 ~ 128)
  • 尾数位存储小数局部,确定浮点数精度,小数能示意的数越大,精度越大,数值越精确

    • float 的尾数位是 23,2^23=8388608,8388608 是个 7 位数的十进制,如果加上疏忽的整数位,最多可示意 8 位的十进制。然而相对能保障无效是 7 位左右的十进制数;double 尾数位是 52,2^52=4503599627370496,16 位的数字,加上整数位 2^53 也是个 16 位数字,因而相对能保障无效位准确是 15 位的十进制数
  • 15.625 的存储示例:

    • 15.625 换成二进制 1111.101
    • 将 1111.101 右移三位,剩小数点前 1 位:1.111101 * 2^3
    • 底数位:因为小数点前必是 1,因而只需记录小数点后的位数即可,此时底数是 1111 01 , 低位补零:111 1010 0000 0000 0000 0000
    • 指数位:指数为 3,加上 127(反转时则减去 127)得 130,指数位二进制为 1000 0010
    • 符号位:负数 0
    • 15.625 在内存的二进制模式示意为

      符号 指数 尾数
      0 1000 0010 111 1010 0000 0000 0000 0000

5:根本类型对应的包装类,区别

根本类型 包装类
boolean Boolean
short Short
byte Byte
int Integer
long Long
float Float
double Double
char Character
  • 对于万物皆对象的 java, 为什么会存在根本类型? 因为 java 产生对象,个别是需在堆创立保护,再通过栈的援用来应用,然而对于简略的小的变量,须要在堆创立再应用太麻烦了
  • 为什么会有包装类

    • 包装类将根本类型包装起来,使其具备对象的性质,能够增加属性和办法,丰盛根本类型的操作
    • 对于泛型编程,或应用 collection 汇合,须要包装类。因为 ArrayList,HashMap 的泛型无奈指定根本类型
    • 区别,根本类型能够间接申明应用,包装类须要在堆创立,再通过援用应用;根本类型默认初始值,int 为 0,boolean 则是 true/false,且无奈赋值为 null;而包装类默认初始值是 null
  • 须要留神的点:Byte、Int、Short、Long 间接赋值(或应用 valueOf)如 Integer x = value(value 在 -128 ~ 127) 是间接援用常量池里的对象,此时对象比拟 == 和 equals 都为 true;Character 申明值则在 0~127 是援用常量池对象、

6:根本类型的主动转换

主动转换规则有如下几个

  • 布尔类型 boolean 不存在隐式转换为其余类型(非主动封装类型)
  • 整数类型的主动晋升

    • byte -> (short/char) -> int -> long (主动晋升链)
    • 示意范畴低的数据类型可隐式主动晋升为示意范畴高的数据类型(byte b = 1; short s = b;); 无编译谬误
    • short 和 char 都是 16 位,然而不能隐式转换
  • 字符型数据向整型数据的主动转换

    • char 是无符号类型,示意范畴在(0~2^16-1),可隐式转为 int 或 long 类型
  • 整型、字符型数据都可向浮点型的主动转换

    • 因为浮点型能保留的有效数字是限度的,须要思考转换后的无效位问题

  • 浮点型数据的主动晋升

    • float 转 double 存在精误差问题,double 如果强制转 float 则存在精度失落问题

7:short s1 = 1; s1 = s1 + 1; 有错吗? short s1 = 1; s1 += 1; 有错吗?

  • s1 = s1+1 中的 1 默认类型是 int,表达式中低范畴类型 s1 会默认转为 int 来相加,失去 int 型的后果,最初 int 型的后果不能隐式转为 short,编译报错
  • s1 += 1; 存在隐含的强制转化 s1 += 1 -> s1 = (short) s1+ 1; 编译不会报错

8:不同的根本类型强制转换,可能会产生什么问题

  • 浮点型转整型,精度失落、数据溢出
  • 取值范畴大的整型转取值范畴小的整型,数据溢出,高位失落

9:float f = 3.4; 是否正确?

在 java 里,不加后缀润饰的浮点数默认是 double 类型。double 类型不能隐式类型转成 float, 编译会报错

10:表达式 3 *0.1 == 0.3 将会返回什么?true 还是 false?

浮点型存在精度问题,3*0.1 失去的 double 数据尾数位 和 0.3 尾数位是不一样的,false

11:浮点数和 BigDecimal

  • 浮点类型应用二进制存储,无论 float(7),double(15), 其无效位是有限度的,存在舍入误差,精度容易缺失
  • 十进制小数转为浮点数再计算,重大存在精度问题。那么是否能够把十进制小数扩充 N 倍化为整数维度来计算,并保留其精度位数,这就是 BigDecimal
  • BigDecimal 是基于 BigInteger 来解决计算,BigInteger 外部有一个 int[] mag, 示意寄存负数的原字节数组 BigInteger 原理
  • 结构 BigDecimal 时防止应用浮点类型结构,会呈现精度问题。尽量应用字符串来创立 BigDecimal,或者应用 valueOf 办法

    BigDecimal data= new BigDecimal(0.1);
    System.out.println("data:" + data);
    
    result:
    data:0.1000000000000000055511151231257827021181583404541015625
  • BigDecimal 进行除法运算不整除时呈现有限循环小数,会抛出 ArithmeticException 异样,须要指定精度
  • 指定精度位数,同时须要指定舍入模式

12:switch 语句是否作用在 byte 类型变量上,是否作用在 long 类型变量上,是否作用在 String 类型变量上?

  • switch(expr) expr 须要时 int 类型,而 byte,char,short 会主动晋升为 int,因而能够作用在 switch 关键字。long,float,double 不能主动转为 int,编译会报错
  • String 也不能主动转为 int,在 1.7 之前也是不能用在 switch。然而 1.7 之后 JDK 反对 String, 通过 String.hashCode 返回一个 int 类型,并在 case 里再次应用 String.equals 比拟

    // 语法糖反编译
    switch(s.hashCode()){
        default;
            break;
        case 3556498:
            if(s.equals("test")){.....}
            break;
    }

13:是否在不进行强制转换的状况下将一个 double 值赋值给 long 类型的变量

不行,因为 double 取值范畴大于 long 类型。不强制转换会编译报错。如果应用 += 操作符编译不会报错,然而存在隐含的强制转换

关注公众号,大家一起交换

参考文章

  • 你真的晓得 Java 中 boolean 类型占用多少个字节吗?
  • 为什么浮点数比 int,long 示意的范畴要大?
退出移动版