java基本数据类型小结

JAVA数据类型

在这里插入图片描述

byte类型

一个字节,取值范围 -128~127。

  1. 当直接量赋值超出范围时会自动转型,这时会有编译错误。除此之外在进行运算时也会自动进行类型转换。
    在这里插入图片描述
    在取值范围内,直接赋值,类型不会改变。

  2. 同样还有隐式的数据溢出

    byte a=127;
    a+=1;        //a=a+1 会报错,why?  ----->自动转型
    //++a ,也不会自动转型
    System.out.println("溢出值为:"+a);
    

    输出结果为:

    溢出值为:-128
    

从上面的代码我们可以看出一些问题:

  • += 和 = : 功能基本相同,但是+=不会产生类型的自动转换,而 = (后面有运算)会按照一定的规则向高位转型 byte->int

  • 直接量赋值超出数据类型的范围会有编译错误,因为此时会自动转型整数类型默认为int。byte i = 128;

  • 数字类型默认为int类型。

同样的上述问题也对其他的正数类型有效。

在这里插入图片描述
数据溢出
在这里插入图片描述

char类型

使用单引号,java中使用Unicode编码集,每个字符使用2个字节表示。
字符类型常量表示:

  1. 单个字符 ‘A’ ,‘1’,
  2. 转移字符 ‘\t’,‘\n’,‘\r’,‘\b’
  3. unicode ‘\uXXXX’, 例如常用汉字的汉字的表示(\u9e11我的随便写的,范围要比这个大) :‘\u4e00’- ‘\u9e11’
  4. 八进制 ‘\XXX’
	  char c1 = '\u0064'; //输出结果: d
      char c2 = '\101';//输出结果: A
int 类型

int 是最常用的数据类型,所以java整数常量默认的数据类型就是int类型。这也是为什么上面错误提示found : int的原因。

java中整数的表示方法有四种,二进制,八进制,十进制,十六进制。

byte b = 0b10101; //二进制
byte b1 = 0x1F;//十六进制
byte b2 = 0101;//八进制

16进制: 0x和0X等效, 同时a~f也不区分大小写。
二进制: 0b和0B等效

float 类型

java中的浮点数有两种,float,double。默认浮点数类型是double,所以定义float类型的变量时需要指定f,F

	float f= 1.2f;
基本类型数据转型方式

Java所有数值类型变量可以相互转换。

整数类型: 数字的默认类型位int类型。 但是如果该数值被赋予byte,short类型的变量,并且在其范围内的时候,该数字类型为编译时的类型。

浮点数: 默认的类型位双精度double,如果要设为单精度则需要加后缀f或F

有两种转型方式,自动类型转型和强制类型转型

  1. 自动类型转型:系统支持某种基本类型直接赋值给另一种基本类型,则成为自动转型。表示范围小的类型可以直接赋值给范围大的类型,这就是自动转型 范围小的变量可以直接赋值给表示范围大的变量就是自动转型。

  2. 强制转型。将大范围的变量赋值给表示范围小的变量就是强制转型。强转可能会导致部分数据丢失。

    注:低类型自动向高类型转换,高类型转低类型需要强转

    • byte->short ->int ->long ->float->double.
    • char ->int ->long ->float->double.

此处大家可能有疑问:long类型占8个字节,为什么可以自动转型到只有四个字节的float类型。

这就要说到浮点数在计算机中的存储结构了。浮点数在内存中的表示 浮点数在内存中的存储分为三个部分:符号位,指数位,位数部分。简单的说使用科学计数法的形式来存储数据

.111111111 * 10^12
  1. 表达式的类型自动提升
    当一个算术表达式包含多个基本类型的时候,整个算数表达式的数据类型将自动发生提升。提升规则如下:
    • 所有的byte 类型,short类型和char类型将被提升到int类型
    • 整个算数表达式提升到表达式中最高等级的数据类型

比较常见的就是

	byte a=12;
	a=a+1;    //此时就会提示 类型不匹配的错误,需要byte类型而给定的是int类型。就是是规则以提到的,byte->int
包装类型

Java是面向对象的语言,所以基本类型都有其对应的引用类型。而且对于集合而言,其类型参数是不能为基本类型,只能用其对应的包装类型。

List<Integer> list=new ArrayList();

集合只能使用包装类型,但是可以直接添加基本类型数据,因为会有装箱的过程。

除此之外还有一个表示高精度的类,BigDecimal,这是由于浮点数容易引起精度丢失。

可以直接把基本类型赋值给其对应包装类型,这个过程称之为自动装箱。当然也可以把包装类型变量赋值给基本类型变量,称之为自动拆箱。

在这里插入图片描述

有些面试题,经常会出包装类型的比较运算。

将一个数字类型赋给对应的引用类型时,通过XXX.valueOf() 进行自定装箱。

Integer.valueOf();
//该方法的返回值,在-128~127 范围内的值,返回缓存中的对象。超出范围会生成新的对象
 		Integer v1=Integer.valueOf("127");
        Integer v2=Integer.valueOf("127");
        Integer v3=Integer.valueOf(128);
        Integer v4=Integer.valueOf(128);
		// true。
        System.out.println(v1==v2);
        //false 。 此时创建了两个对象。== 对于引用类型比较,比较地址
        System.out.println(v3==v4);
        //true。 Integer重写了equals方法。使用 obj.intValue() 返回基本类型进行比较
        System.out.println(v3.equals(v4));

		int v5=127;
        int v6 = 128;
        //true   
        System.out.println(v1==v5);
        //true   使用基本类型和引用类型比较,该处有拆箱操作
        System.out.println(v6==v3);
		//装箱操作
		Object object = v5;
		
		Integer i1=128;
		Integer i2=128;
		//false。  自动装箱时,使用Integer.valueOf(), -128~127范围内使用缓存
		System.out.println(i1==i2);
关于==的一些辨析
  • 引用类型和基本类型比较会有拆箱操作。 ("=="比较)

    Integer v1=128;
    int v2=128;
    //true
    System.out.println(v1==v2);
    
     Float f1=12.0f;
     float f2=12.0f;
     int f3=12;
     //true
     System.out.println(f1==f2);
    //true
     System.out.println(f3==f2);
     //true
     System.out.println(f3==f1);
     // false。 此处有装箱操作, Integer 和Float类型,是不能比较的
     System.out.println(f1.equals(f3));
     //true , 此处有装箱操作,然后比较float值
     System.out.println(f1.equals(f2));
    
  • 相同引用类型之间比较不会拆箱比较。Integer i=128;Integer i2=128;,返回false

  • 不同包装引用类型无法无法直接比较。

    Long v1=123l; 
    Integer v2=123;
    //System.out.println(v1==v2);// 编译异常
    System.out.println(v1.equals(v2));//返回false
    
    • == 比较: 此时编译异常 operator == cannaot be applied to 'java.lang.Integer' ,'java.lang.Long'

    • equals比较: 返回false。

      //Long 重写了equals方法
      public boolean equals(Object obj) {
              if (obj instanceof Long) {
                  return value == ((Long)obj).longValue();
              }
              return false;
          }
      
关于equals操作
  • 相同包装引用类型,比较其基本类型的值。 obj.floatValue()

  • 如果自动装箱操作后,引用类型不一致直接返回false

    public boolean equals(Object obj) {
            if (obj instanceof Integer) {
                return value == ((Integer)obj).intValue();
            }
            return false;
        }
    
小结
易错点
  1. 相同包装类型之间的比较最好不要使用==。因为整数包装类型中存在缓存
    • Byte,Short,Integer,Long 都为【-128~127】
    • Character 为字符ASCII 码表中的128个字符
  2. 不同的包装类型之间不要使用 equals比较。
    • 因为当包装类型不一致时直接返回false
    • 即便类型一致,如果值不在【-128~127】范围内,也是返回false
类型转化相关

虽然java会自动进行类型转化,但还是有几种情况不会进行类型转化

  1. 表达式 +=,++
 		byte b1=Byte.MAX_VALUE;
        ++b1;
        //-128
        System.out.println(b1);
        byte b2=Byte.MAX_VALUE;
        b2+=2;
        //-127
        System.out.println(b2);
  1. 变量使用final修饰
  		final byte b3=3;
        byte b2 = b3+10; //如果变量b3没有使用final修饰符,会有编译错误

当然了如果越界了,也会有编译异常
在这里插入图片描述
final 类型定义基本类型变量,相当于c中的宏(记忆中。。),会在使用的该变量的位置直接使用其值替换,并尝试进行运算。所以上面的代码相当于

byte b3=128;

这只是我的一己之见。

运算符
位运算

java种支持的位运算有7个:

  • &: 按位与
  • | :按位或
  • ~:按位非
  • ^:按位异或
  • <<:左移运算
  • >>:右移运算
  • >>>:无符号右移

合理使用位运算,就会有比较好的运行效率。因为底层数据存储就是0| 1存储的。

	 @Test
    public void test1(){
        byte by=-5;
        System.out.println(by | 3);
        System.out.println(~by);
        System.out.println(by<<1);
        System.out.println(by<<29);
        System.out.println(by>>1);

    }

-5
4
-10
1610612736
-3

进行位运算(~,<<,>>)可能会修改数字的正负符号。

下面以byte类型为例:
底层运算都是以补码进行的操作的。比如byte 类型的 -5

原码: 10000101
//除符号位,取反
反码: 11111010
//反码加1
补码: 111111011

-5 | 3 => -5

-5:  	 11111011
3:  	 00000011
-5 | 3   11111011

~-5 => 4

-5   	11111011
~-5     00000100 

-5 << 1 => -10

-5  	111111011
-5<<1 	111110110
		111110110
//反码 
		100001001
//补码 
		100001010

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值