当前位置:主页 > 查看内容

java第二话:java的数据类型与运算符(同C语言在比较下进行学习

发布时间:2021-04-27 00:00| 位朋友查看

简介:java数据类型与运算符 数据类型 基本数据类型 java数据类型使用的常犯错误 整数的默认类型和浮点数的默认类型 过大数据的存储和数据类型的转换 整型提升针对小于四字节的运算 算术转换 char类型来表示汉字 boolean 与整形能不能进行相互转换 java中也能对浮……

数据类型

下面附上一张java数据类型的表,以便读者形成整体的观念。
在这里插入图片描述

基本数据类型

这里我给读者一张关于java的数据类型的表,这样更加方便你们阅读和查看
在这里插入图片描述
以上就是java的八大基本数据类型
对于上述表中,大概有几点需要注意:
1. java中所参照的字符表不再是ASCII码表,而是Unicode表
2. 包装类是啥 ?这个在我之后的博客会继续讲解,这里只需记住它们各自的包装类就好了
3. java中的 byte,short, int, long 没有无符号数这种概念,它们均为有符号数,即最高位为符号位,剩下的都是数值位
4. java中的char类型无负数,即你不能将一个 -1 赋值给一个char类型(会报错,C语言中就不会报错)
5. 除了 int 和 char 对应的包装类需要特殊记忆,其他数据类型的包装类就只是首字符大写就完事了
6. 字节大小数里 char 和 C 相比发生了改变,还新增了byte 和 boolean 。以及 java中的数据类型是固定的(java语言的可移植性)
7. boolean 是啥?它又叫布尔类型,它只能取 true 或者 false 这两个值(不像C语言中0为假,非零为真, java中具体的给出了这种类型)

java数据类型使用的常犯错误

整数的默认类型和浮点数的默认类型

int a =10;
long b =10;
float c= 10.0;
double d= 10.0;

在上述代码中,第三行会报错,为什么呢?因为整数默认类型为 int 类型,而浮点数默认类型为 double 类型,因此,在第三行的时候,就相当于把一个double类型赋值给一个float类型,就会发生数据的截断而出错,至于第二行代码为什么没出错是因为将一个int类型赋值给一个long类型是小类型赋值给大类型,因此不会出错。
但是,为了代码的安全性。在读入一个long和float类型的时候,我们可以在整数后面加一个L(大小写均可),在浮点数后面加一个F(也是大小写均可),如下面代码

        int a =10;
        long b =10L;
        float c= 10.0F;
        double d= 10.0;

过大数据的存储和数据类型的转换

byte a =128;
int b = 2147483648;

以上两行代码均会报错,因为java是一种强类型的语言,会对右边将要赋值的数据进行检查,如果超过了所能存储的范围,那么它将报错。
再看以下代码

     byte c = 30+30byte b = 127+1;//错误代码(注:127是byte所能存储的最大值)
    int a= 2147483647+1;//(注:2145483647)

这三行代码里面只有第二行代码出错了,为啥?为什么第三行代码存储的值也超过的存储的范围,但是不报错?
对于这个问题我们分两种情况进行讨论()
第一种,赋值给小于四字节的
第二种,赋值给大于四字节的
在讨论之前,我们就现需要了解整形提升和算术转换的含义

整型提升(针对小于四字节的运算)

看如下代码

    byte h = 10;
    byte i = 21;
    byte m = 10+21;
    byte b = 127+1;//错误代码
    byte j = h+i;//错误代码
    byte k = h+1;//错误代码

为啥上面最后三行代码会发生错误?出错的原因如下图
在这里插入图片描述

因为当进行 h+i 这个运算的时候,计算机发现这是两个小于4字节的变量在进行计算,因此会将它们的数据类型提升为四字节的整形,至于为啥是四字节,是因为计算机总是以4字节的形式来拿取数据,提升为四字节是为了提升计算机的工作效率。
注意刚才我说的是变量在进行计算,你可以这样来理解,即计算机不知道这个变量到底存了些什么,它只知道这个变量只有两个字节,然后就将它提升为四个字节,以提高工作效率。
但为什么第三行代码又对,第四行代码 byte b = 127+1又错呢?
则会使因为java对右边的数据进行了数值大小的检查,它检查到数值超过了所能存储的最大值的时候就会将这个较大的数归属于存储范围更大的整形,因此,第四行代码也会发生类型的冲突,而第三行不会。

算术转换

和整形提升差不多,算术转换是更高字节之间的转换,但是依然像整型提升一样满足低转高

        int a =4;
        double c= a/1.0;

我们知道1.0默认的是double型,而当一个整形和一个double型进行运算的结果就会属于一个double型

总之,对于整形提升和算术转换我们记住这几点就好
1.整型提升和算术转换时自动发生的
2.整型提升和算术转换都是小转大,不过整形提升时小于4字节的都提升为4字节的整形(注意char类型也会哦),而算术转换时根据操作数 的数据类型来转换。

到这,我们了解了整形提升和算术转换,我们在继续刚才的两种情况吧
第一:小于四字节的运算
1.如果等号右边只有数值没有变量,会自动检查等号右边的数值
如果只有一个字面常量(不用运算)且大于范围,那么它会直接报数值过大的错误
如果是运算后的结果大于范围,那么它将会把运算后的结果设置为int类型,然后导致类型冲突发生错误。
2. 如果等号右边有变量,那么将会发生整形提升,然后导致类型冲突
第二:大于四字节的运算

1.如果等号右边只有一个字面常量且大于范围,那么它将会直接报错。
2.如果有字节更大的变量,那么将会发生算术转换。
如果没有,只是单纯的数值运算,结果超出范围,像下面这样

 int a= 2147483647+1;//结果是-2147483648

那么它将会进入一个数值的循环,不会出错。如下图
在这里插入图片描述
即-1+1=0,2147483647+1=-2147483648,这样循环着来,也就有了为啥刚刚代码的结果,
其实byte里面也有这样的操作,但是不太容易出现,会有整型提升等很多问题直接报错,看下面的代码

short a =128byte b =(byte) a;

128已经超过了byte的范围了,128 = 127+1,如下图,这里的 b 应该是-128

在这里插入图片描述

到这,关于这个小知识点的讲解大概就完结了,我们再来总结三点
1.这些数值类型都存在如上图这样的循环,但是byte这样小于四字节的数字往往会由于整型提升或者其他原因直接报错,但是int long这样的数据类型就经常会发生这样数值的循环特性。
2.所有类型,如果直接赋值给一个超过范围的字面常量都是会直接报错的。,如果不是直接赋值一个字面常量,那么就具体问题具体分析。
3.了解小转大的整型提升和算术转换,当然,如果你想大转小那么强制转换就行

char类型来表示汉字

这是一个小知识点,一个汉字的大小是两个字节,在java中char类型也刚好是两个字节。
因此,java中的char类型刚好能表示一个汉字,C语言中则不能

boolean 与整形能不能进行相互转换?

答案是不能,java中故意设置boolean这种类型的变量就是为了和C语言中用数字非零与否判断真假的方式区别开来,因此我们不能写下面这样的代码

   boolean a =0; 
   boolean b =1;

只能写如下这样的

boolean a = true;
boolean b = false;

java中也能对浮点数进行取模运算吗?

答案也是可以的,在C语言中,我们只能对整数进行取模运算,而在java中,我们对浮点数也能进行取模运算,如下图代码


double a = 10 % 3.0;

至于为什么要用double类型,上文也已经提到过,1.0是默认double类型,所以运算之后也会默认转换为double类型

引用数据类型

string类

我们这里只介绍一种引用数据类型,那就是字符串类型

String arr = "abcdef";

创建方式很简单,为什么叫引用类型呢?因为String是在java.lang包的一个String类。
我们的java程序会自动引用java.lang包,所以可以直接使用。
下面介绍字符串转换成数字和数字转换成字符串的方法

数字转字符串

方法一:拼接上一个空字符串然后变成字符串,例如

int a=29;
String string = a+"";

方法二:采用String类的一个叫valueOf的方法,如下

int a =29;
String string = String.valueOf(a);

字符串转数字

用整形包装类下面的一个方法:

        String string = "123456";
        int num = Integer.valueOf(string);

运算符

算术运算符

算术运算符包含 ’ + ‘,’ - ‘,’ * ‘,’ / ‘,’%’(加,减,乘,除,取模)
自增自减运算符:+=,-=,++,–

这里需要注意的一点是关于除法的运算

如何保留小数

下面给出一段代码

        System.out.println(5/2);//结果为2
        System.out.println(5/2.0);//结果为2.5
        System.out.println(5.0/2);//结果为2.5
        System.out.println((float)5/2);//结果为2.5
        System.out.println(5/(float)2);//结果为2.5
        System.out.println((float)(5/2));//结果为2.0

从上面的代码以及上文对于一个整数和一个浮点数默认的数据类型来看
我们可以发现:
如果不需要保留小数,那么直接用整数之间的除法就可以,如果需要保留小数,至少要保证操作符左右两边至少有一个浮点数

0不能作为除数

int a = 10/0;

这段代码编译时就会报出下面的异常

在这里插入图片描述

关于负数的除法取模

下面给出一些例子

        System.out.println(-10/3);//结果为-3
        System.out.println(10/-3);//结果为-3
        System.out.println(-10/-3);//结果为3
        System.out.println(-10%3);//结果为-1
        System.out.println(10%-3);//结果为1
        System.out.println(-10%-3);//结果为-1

我们可以看到负数的除法和我们正常计算的情况一样,那么负数的取模运算呢?
假如-10%3 或者 -10%-3,我们先商一个 -3 或者 3,那么-10-(-9)或者- 10 - (-9)结果都是剩-1,这个运算很简单,读者可以自己去试一试。

+=,-=,++,-- 的特点

避免产生类型冲突

通过上文的阅读我们知道下面的代码时会发生整形提升然后报错

   byte a =10;
   a = a + 1;//这里会发生类型的冲突
   short b =11;
   b = b + 1;//这里也会发生类型的冲突

如果我们使用 a+=1 , b+=1 这样的代码就不会出错,如

byte a =10;
a++;
a+=10;
a--;
a-=2;

所以对于小于4字节的变量的自增自减,我们可以使用+=或者-=,避免产生类型冲突。

前置++,-- 和后置++,–的区别

        int a =10;
        int b=a++;//这里a先赋值给b,再自增为11
        int c=++a;//这里a先自增为12,再赋值给c
        System.out.println(a);//最终a为12
        System.out.println(b);//b为10
        System.out.println(c);//c为12

由上图代码我们可以知道,前置++和后置++的区别就是,前置会先进行自增,再返回,后置则是先返回,再自增。
而–和++是同样的方式操作。
当然如下图代码

int a=10;
a++;
++a;

这样不需要返回值的时候,二者就没有区别。

关系运算符

关系运算符有:’ == ’ ,’>=’, <=, >, <, !=(等于,大于等于,小于等于,大于,小于,不等于)
这里和C语言差不多,唯一要注意一点是不要把’=’ 看成 ‘==’,前者是赋值符号,后者是等号

逻辑运算符

逻辑运算符有&&,||,!,&,|(短路与,短路或,逻辑非,逻辑与,逻辑或)
这里和C语言有个区别,那就是java多了两个逻辑运算符 & 和 | ,与 && 和 || 之间的区别就是
前者不支持短路运算,而后者和C语言一样支持短路运算

短路运算

因为与的规则是只有操作符两边的布尔表达式均为true,结果才为true,只要左边的操作符为false,那么无论右边的操作符结果是多少,结果都是false,所以只要左边的满足false,那么短路与&&这个操作符将不会检查右边的代码
如下图代码

            if(!(20<10 && 10/0==0))
            System.out.println("world");

结果会打印world,并不会报错,原因是20<10为false,那么结果一定为false,所以也就没有检查右边的错误代码
同理,或的规则是只要有true,那么结果一定为true,短路或 || 也就不会去检查右边的代码

      if(  20>10 || 10/0==0)
            System.out.println("hello");

这里会输出hello,因为20>10为true,短路与操作符也就不会去检查右边的代码。

位运算符

位运算符主要有:’&’ , ‘|’ , ‘~’, ‘^’(与,或,取反,异或)
啥叫位运算符呢?
因为数据在计算机里面都是以二进制进行存储的**,位运算符就是对于二进制中的每一位进行位操作**。

按位与:两个二进制位都为1,那么结果为1,否则结果为0。
按位或:两个二进制位都为0,那么结果为0,否则结果为1。
按位取反:如果该位为0,那么转为1,如果该位为1,那么转为0
按位异或:两个二进制数相同为0,相异为1

对于某一位数据来说,你与上一个0,相当于置0,因为结果一定是0,那么你与上一个1呢?原数据相当于不改变,是1还是1,是0还是0。
因此我们可以总结一下
与0=置0,与1=不变
或0=不变,或1=置1

对于异或:
0^n=n, 0 异或任何数都是任何数,不改变。

移位运算符

移位操作符有三个:<<,>>,>>>(左移,右移,无符号右移)
‘<<’: 左移的规则是位左移之后,在后面补0。 左移N位相当于乘于2的N次方
‘>>’: 右移的规则是位右移之后,在前面补符号位 右移N位相当于除于2的N次方
‘>>>’:无符号右移的规则是右移之后,在前面补0

条件运算符

条件运算符只有一个:布尔表达式?代码1:代码2 (又叫三目操作符)
如果这个布尔表达式为真,那么就会执行代码1,否则会执行代码2,举个例子

        int a = 10;
        int b = 20;
        int c = 30;
        int max = c>(a>b?a:b)?c:(a>b?a:b);//(a>b?a:b)来找出ab之间的最大值,又和c比较,找出三者之间的最大值
        System.out.println(max);

这样一段代码就找出了三者之间的最大值。

到这,今天我们关于java的数据类型和运算符的讲解就告一段落,如有问题,欢迎指正,想和我一起学习java的小伙伴记得关注我,我之后也会陆续发布关于java的知识点博文,一起加油吧!

;原文链接:https://blog.csdn.net/weixin_51306225/article/details/115417548
本站部分内容转载于网络,版权归原作者所有,转载之目的在于传播更多优秀技术内容,如有侵权请联系QQ/微信:153890879删除,谢谢!

推荐图文


随机推荐