Java的第二篇文章——基本数据类型和运算符

简介: Java的第二篇文章——基本数据类型和运算符

第二章 Java基础知识(补充)

1.计算机如何存储数据

1.1 进制(了解)

1.1.1 进制的分类

(1)十进制: 数字组成:0-9 进位规则:逢十进一

(2)二进制: 数字组成:0-1 进位规则:逢二进一

十进制的256,二进制:100000000,为了缩短二进制的表示,又要贴近二进制,在程序中引入八进制和十六进制

(3)八进制:很少使用 数字组成:0-7 进位规则:逢八进一

与二进制换算规则:每三位二进制是一位八进制值

(4)十六进制 数字组成:0-9,a-f 进位规则:逢十六进一

与二进制换算规则:每四位二进制是一位十六进制值

1.1.2 进制的换算

十进制 二进制 八进制 十六进制
0 0 0 0
1 1 1 1
2 10 2 2
3 11 3 3
4 100 4 4
5 101 5 5
6 110 6 6
7 111 7 7
8 1000 10 8
9 1001 11 9
10 1010 12 a或A
11 1011 13 b或B
12 1100 14 c或C
13 1101 15 d或D
14 1110 16 e或E
15 1111 17 f或F
16 10000 20 10

这部分了解即可,在开发过程中,可以用计算器进行换算。

1.1.3 在代码中如何表示四种进制的值(了解)

请分别用四种类型的进制来表示10,并输出它的结果:(了解)

(1)十进制:正常表示

System.out.println(10);

(2)二进制:0b或0B开头

System.out.println(0B10);

(3)八进制:0开头

System.out.println(010);

(4)十六进制:0x或0X开头

System.out.println(0X10);

1.2 计算机存储单位

  • 字节(Byte):是计算机信息技术用于计量存储容量的一种计量单位,一字节等于八位。
  • 位(bit):是数据存储的最小单位。也就是二进制。二进制数系统中,每个0或1就是一个位,叫做bit(比特),其中8 bit 就称为一个字节(Byte)。
  • 转换关系:
  • 8 bit = 1 Byte
  • 1024 Byte = 1 KB
  • 1024 KB = 1 MB
  • 1024 MB = 1 GB
  • 1024 GB = 1 TB

1.3 Java的基本数据类型的存储范围

1.3.1 整型系列

(1)byte:字节类型

  • 占内存:1个字节
  • 存储范围:-128~127

(2)short:短整型类型

  • 占内存:2个字节
  • 存储范围:-32768~32767

(3)int:整型

  • 占内存:4个字节
  • 存储范围:-2的31次方 ~ 2的31次方-1

(4)long:整型

  • 占内存:8个字节
  • 存储范围:-2的63次方 ~ 2的63次方-1

注意:如果要表示某个超过int范围的常量整数它是long类型,那么需要在数字后面加L

1.3.2 浮点型系列(小数)

(1)float:单精度浮点型

  • 占内存:4个字节
  • 精度:科学记数法的小数点后6~7位

注意:如果要表示某个常量小数是float类型,那么需要在数字后面加F或f,否则就是double类型

(2)double:双精度浮点型

  • 占内存:8个字节
  • 精度:科学记数法的小数点后15~16位
float f = 12.0F;//右边如果赋值小数常量值,那么必须加F或f

1.3.3 单字符类型:char

  • 占内存:2个字节

1.3.4 布尔类型

boolean:只能存储true或false

虽然计算机底层使用0和1表示false和true,但是在代码中不能给boolean类型的变量赋值0和1,只能赋值false和true

1.4 计算机如何存储数据

1.4.1 补码与符号位

计算机数据的存储使用二进制补码形式存储,并且最高位是符号位,1是负数,0是正数。

规定:正数的补码与反码、原码一样,称为三码合一;

负数的补码与反码、原码不一样:

负数的原码:把十进制转为二进制,然后最高位设置为1

负数的反码:在原码的基础上,最高位不变,其余位取反(0变1,1变0)

负数的补码:反码+1

例如:byte类型(1个字节,8位)

25 ==> 原码 0001 1001 ==> 反码 0001 1001 -->补码 0001 1001

-25 ==>原码 1001 1001 ==> 反码1110 0110 ==>补码 1110 0111

底层是用加法代替减法:-128==》-127-1==》-127+(-1)

-127- -1 ==> -127 + 1

1.4.2 一个字节可以存储的数据范围是多少?

(1)无符号:不考虑正负数

(2)有符号

1个字节:8位

0000 0001 ~ 0111 111 ==> 1~127

1000 0001 ~ 1111 1111 ==> -127 ~ -1

0000 0000 ==>0

1000 0000 ==> -128(特殊规定)

1.4.3 如何存储小数

  • 为什么float(4个字节)比long(8个字节)的存储范围大?
  • 为什么double(8个字节)比float(4个字节)精度范围大?
  • 为什么float和double不精确

因为float、double底层也是二进制,先把小数转为二进制,然后把二进制表示为科学记数法,然后只保存:

①符号位②指数位③尾数位

1.4.4 如何存储字符

  • Java中使用的字符集:Unicode编码表

在计算机的内部都是二进制的0、1数据,如何让计算机可以直接识别人类文字的问题呢?就产生出了编码表的概念。编码表 :就是将人类的文字和一个十进制数进行对应起来组成一张表格。

将所有的英文字母,数字,符号都和十进制进行了对应,因此产生了世界上第一张编码表ASCII(American Standard Code for Information Interchange 美国标准信息交换码)。

Unicode(统一码、万国码、单一码)是计算机科学领域里的一项业界标准,包括字符集、编码方案等。Unicode 是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。

2.基本数据类型转换(Conversion)

在Java程序中,不同的基本数据类型的值经常需要进行相互转换。Java语言所提供的七种数值类型之间可以相互转换,基本数据类型转换有两种转换方式:自动类型转换和强制类型转换。

2.1 自动类型转换(隐式类型转换)

自动转换

  • 取值范围小的类型自动提升为取值范围大的类型

(1)当把存储范围小的值(常量值、变量的值、表达式计算的结果值)赋值给了存储范围大的变量时

int i = 'A';//char自动升级为int
double d = 10;//int自动升级为double
byte b = 127; //右边的整数常量值必须在-128~127范围内
//byte bigB = 130;//错误,右边的整数常量值超过byte范围
long num = 1234567; //右边的整数常量值如果在int范围呢,编译和运行都可以通过,这里涉及到数据类型转换
long bigNum = 12345678912L;//右边的整数常量值如果超过int范围,必须加L,否则编译不通过

(2)当存储范围小的数据类型与存储范围大的数据类型一起混合运算时,会按照其中最大的类型运算

int i = 1;
byte b = 1;
double d = 1.0;
double sum = i + b + d;//混合运算,升级为double

(3)当byte,short,char数据类型进行算术运算时,按照int类型处理

byte b1 = 1;
byte b2 = 2;
byte b3 = b1 + b2;//编译报错,b1 + b2自动升级为int
char c1 = '0';
char c2 = 'A';
System.out.println(c1 + c2);//113

(4)boolean类型不参与

2.2 强制类型转换(显示类型转换)

1.5 赋值到int 类型变量会发生什么?产生编译失败,肯定无法赋值。

int i = 3.14; // 错误

想要赋值成功,只有通过强制类型转换,将double 类型强制转换成int 类型才能赋值。

  • 强制类型转换:将取值范围大的类型强制转换成取值范围小的类型

比较而言,自动转换是Java自动执行的,而强制转换需要我们自己手动执行。

转换格式:数据类型 变量名 = (数据类型)被强转数据值;

(1)当把存储范围大的值(常量值、变量的值、表达式计算的结果值)赋值给了存储范围小的变量时,需要强制类型转换,提示:有风险,可能会损失精度或溢出

int i = (int)3.14;//强制类型转换,损失精度
double d = 1.2;
int num = (int)d;//损失精度
int i = 200;
byte b = (byte)i;//溢出

(2)boolean类型不参与

(3)当某个值想要提升数据类型时,也可以使用强制类型转换

int i = 1;
int j = 2;
double shang = (double)i/j;

2.3 特殊的数据类型转换

(1)任意数据类型的数据与String类型进行“+”运算时,结果一定是String类型

System.out.println("" + 1 + 2);//12

(2)但是String类型不能通过强制类型()转换,转为其他的类型

String str = "123";
int num = (int)str;//错误的
int num = Integer.parseInt(str);//后面才能讲到,借助包装类的方法才能转

2.4 练习

(1)练习题:判断如下代码是否编译通过,如果能,结果是多少?

short s1 = 120;
short s2 = 8;
short s3 = s1 + s2;

答:不能,因为s1和s2在进行运算时,会自动提升为int类型,再把int类型赋值给short类型会报错。当byte,short,char数据类型进行算术运算时,按照int类型处理

(2)练习题:判断如下代码是否编译通过,如果能,结果是多少?

short s1 = 120;
short s2 = 8;
byte s3 = (byte)(s1 + s2);

答:不能,因为byte的存储大小只有8位且有符号,byte最大的正整数是127,128已经超过了byte的大小了。

(3)练习题:判断如下代码是否编译通过,如果能,结果是多少?

char c1 = '0';
char c2 = '1';
char c3 = c1 + c2;

答:不能,因为char、short和byte运算都是按照int类型来的,所以在c1+c2是一个int类型的数,是不能赋值给char类型的。

(4)练习题:判断如下代码是否编译通过,如果能,结果是多少?

char c1 = '0';
char c2 = '1';
System.out.println(c1 + c2);

答 :能,输出c1+c2的int类型的数据。

(5)练习题:判断如下代码是否编译通过,如果能,结果是多少?

int i = 4;
long j = 120; //因为右边120默认是int类型,int的值赋值给long类型是可以的,会自动类型转换,但是要求这个int值不能超过int的存储范围,如果超过int的存储范围必须加L.
double d = 34;
float f = 1.2;//因为右边1.2默认是double类型,double的值是不能直接赋值给float的,要么加F要么使用强制类型转换。

(6)练习题:判断如下代码是否编译通过,如果能,结果是多少?

int i = 1;
int j = 2;
double d = i/j;
System.out.println(d);

答:能,答案为0.0,因为i/j都是整数相除后再赋值给double类型,1/2==0。

3.运算符(Operator)

  • 表达式:用运算符连接起来的式子
  • 运算符的分类: 按照功能分:算术运算符、赋值运算符、比较运算符、逻辑运算、条件运算符...
分类 运算符
算术运算符 +-*/%++--
赋值运算符 =+=-=*=/=%=
关系运算符 >>=<<===!=
逻辑运算符 &|^!&&||
条件运算符 (条件表达式)?结果1:结果2;
位运算符(了解) &|~^<<>>>>>
  • 按照操作数个数分:一元运算符(单目运算符)、二元运算符(双目运算符)、三元运算符 (三目运算符)
    一元运算符:操作数只有一个 例如:正号(+) +a 负号(-) -a 自增自减 ++i i++ 逻辑非: !true
    二元运算符:操作数有两个 例如:加法:a+b 减法:a-b 大于:a>b 逻辑与:a&b 三元运算符:条件 ? 结果1 : 结果2

3.1 算术运算符

算术运算符 符号解释
+ 加法运算,字符串连接运算,正号
- 减法运算,负号
* 乘法运算
/ 除法运算,整数/整数结果还是整数
% 求余运算,余数的符号只看被除数
++-- 自增自减运算

3.1.1 加减乘除模

public class OperatorDemo01 {
  public static void main(String[] args) {
    int a = 3;
    int b = 4;
    System.out.println(a + b);// 7
    System.out.println(a - b);// -1
    System.out.println(a * b);// 12
    System.out.println(a / b);// 计算机结果是0,为什么不是0.75呢?
    System.out.println(a % b);// 3
        System.out.println(5%2);//1
    System.out.println(5%-2);//1
    System.out.println(-5%2);//-1
    System.out.println(-5%-2);//-1    
    //商*除数 + 余数 = 被除数
    //5%-2  ==>商是-2,余数时1    (-2)*(-2)+1 = 5
    //-5%2  ==>商是-2,余数是-1   (-2)*2+(-1) = -4-1=-5
  }
}

3.1.2 “+”号的两种用法

  • 第一种:对于+两边都是数值的话,+就是加法的意思
  • 第二种:对于+两边至少有一边是字符串得话,+就是拼接的意思
public class OperatorDemo02 {
  public static void main(String[] args) {
    // 字符串类型的变量基本使用
    // 数据类型 变量名称 = 数据值;
    String str1 = "Hello";
    System.out.println(str1); // Hello
    System.out.println("Hello" + "World"); // HelloWorld
    String str2 = "Java";
    // String + int --> String
    System.out.println(str2 + 520); // Java520
    // String + int + int
    // String   + int
    // String
    System.out.println(str2 + 5 + 20); // Java520
  }
}

3.1.3 自加自减运算

理解:++运算,变量自己的值加1。反之,-- 运算,变量自己的值减少1,用法与++ 一致。

(1)单独使用

  • 变量在单独运算的时候,变量前++和变量后++,变量的是一样的;
  • 变量前++ :例如 ++a
  • 变量后++ :例如 a++
public class OperatorDemo3 {
  public static void main(String[] args) {
    // 定义一个int类型的变量a
    int a = 3;
    //++a;
    a++;
        // 无论是变量前++还是变量后++,结果都是4
    System.out.println(a);
  }
}

(2)复合使用

  • 其他变量放在一起使用或者和输出语句放在一起使用前++后++就产生了不同。
  • 变量前++ :变量先自身加1,然后再取值。
  • 变量后++ :变量先取值,然后再自身加1。

小结:

++在前,先自加,后使用;

++在后,先使用,后自加。

3.2 赋值运算符

注意:所有的赋值运算符的=左边一定是一个变量

赋值运算符 符号解释
= 将符号右边的值,赋值给左边的变量
+= 将符号左边的值右边的值进行相加操作,最后将结果赋值给左边的变量
-= 将符号左边的值右边的值进行相减操作,最后将结果赋值给左边的变量
*= 将符号左边的值右边的值进行相乘操作,最后将结果赋值给左边的变量
/= 将符号左边的值右边的值进行相除操作,最后将结果赋值给左边的变量
%= 将符号左边的值右边的值进行取余操作,最后将结果赋值给左边的变量

赋值运算符的拓展

public class OperatorDemo04 {
  public static void main(String[] args) {
    short s = 3;
    // s = s + 4; 代码编译报错,因为将int类型的结果赋值给short类型的变量s时,可能损失精度
    s += 4; // 代码没有报错
        //因为在得到int类型的结果后,JVM自动完成一步强制类型转换,将int类型强转成short
    System.out.println(s);
        int j = 1;
    j += ++j * j++;//相当于  j = j + (++j * j++);
    System.out.println(j);//5
  }
}

扩展赋值运算符在将最后的结果赋值给左边的变量前,都做了一步强制类型转换。(+=、-=、*=、/=、%=)

3.3 关系运算符/比较运算符

关系运算符 符号解释
< 比较符号左边的数据是否小于右边的数据,如果小于结果是true。
> 比较符号左边的数据是否大于右边的数据,如果大于结果是true。
<= 比较符号左边的数据是否小于或者等于右边的数据,如果大于结果是false。
>= 比较符号左边的数据是否大于或者等于右边的数据,如果小于结果是false。
== 比较符号两边数据是否相等,相等结果是true。
!= 不等于符号 ,如果符号两边的数据不相等,结果是true。
  • 比较运算符,是两个数据之间进行比较的运算,运算结果一定是boolean值true或者false
  • 其中>,<,>=,<=不支持boolean,String类型,==和!=支持boolean和String。

3.4 逻辑运算符

逻辑运算符,是用来连接两个布尔类型结果的运算符(!除外),运算结果一定是boolean值true或者false

逻辑运算符 符号解释 符号特点
& 与,且 falsefalse
| truetrue
^ 异或 相同为false,不同为true
! falsetrue,非truefalse
&& 双与,短路与 左边为false,则右边就不看
|| 双或,短路或 左边为true,则右边就不看
a b a&b a&&b a | b a || b !a a^b
true true true true true true false false
true false false false true true false true
false true false false true true true true
false false false false false false true false

&&和&区别,||和|区别

  • &&&区别:
  • &&&结果一样,&&有短路效果,左边为false,右边不执行;&左边无论是什么,右边都会执行。
  • |||区别:
  • |||结果一样,||有短路效果,左边为true,右边不执行;|左边无论是什么,右边都会执行。

3.5 条件运算符

条件运算符格式:条件表达式?结果1:结果2

条件运算符计算方式:

  • 条件判断的结果是true,条件运算符整体结果为结果1,赋值给变量。
  • 判断条件的结果是false,条件运算符整体结果为结果2,赋值给变量。
public static void main(String[] args) {
    int i = (1==2 ? 100 : 200);
    System.out.println(i);//200
    int j = (3<=4 ? 500 : 600);
    System.out.println(j);//500
}

3.6 位运算符

位运算符都是在补码的基础上进行位移的

位运算符 符号解释
& 按位与,当两位相同时为1时才返回1
| 按位或,只要有一位为1即可返回1
~ 按(补码)位非,将操作数的每个位(包括符号位)全部取反
^ 按位异或。当两位相同时返回0,不同时返回1
<< 左移运算符
>> 右移运算符
>>> 无符号右移运算符
运算符 运算方式
<< 空位补0,被移除的高位丢弃,空缺位补0。
>> 当最高位是0,右移后,空缺位补0
当最高位是1,空缺位补1。
>>> 被移位二进制最高位无论是0或者是1,空缺位都用0补。
& 二进制位进行&运算,只有1&1时结果是1,否则是0;
| 二进制位进行 | 运算,只有0 | 0时结果是0,否则是1;
^ 二进制位相同是0
二进制位不同是1
~ 按补码取反

(1)左移:<<

运算规则:左移几位就相当于乘以2的几次方

(2)右移:>>

运算规则:右移几位就相当于除以2的几次方

(3)无符号右移:>>>

运算规则:往右移动后,左边空出来的位直接补0,不看符号位

注意:当左移的位数n超过该数据类型的总位数时,相当于左移(n-总位数)

byte,short,char在计算时按照int类型处

(4)按位与:&

运算规则:

1 & 1 结果为1

1 & 0 结果为0

0 & 1 结果为0

0 & 0 结果为0

(5)按位或:|

运算规则:

1 | 1 结果为1

1 | 0 结果为1

0 | 1 结果为1

0 & 0 结果为0

(6)按位异或:^

运算规则:

1 ^ 1 结果为0

1 ^ 0 结果为1

0 ^ 1 结果为1

0 ^ 0 结果为0

(7)按位取反:~

运算规则:~0就是1

~1就是0

4.三元运算符

 

5.运算符优先级

提示说明:

(1)表达式不要太复杂

(2)先算的使用()

大体的排序:算术->位-->比较-->逻辑-->三元-->赋值

感谢尚硅谷的老师们的指导!!!

相关文章
|
2月前
|
存储 安全 Java
从入门到精通:Java Map全攻略,一篇文章就够了!
【10月更文挑战第17天】本文详细介绍了Java编程中Map的使用,涵盖Map的基本概念、创建、访问与修改、遍历方法、常用实现类(如HashMap、TreeMap、LinkedHashMap)及其特点,以及Map在多线程环境下的并发处理和性能优化技巧,适合初学者和进阶者学习。
58 3
|
3月前
|
Java
Java运算符
Java运算符
51 12
|
21天前
|
Java
Java基础之数据类型
Java基础之数据类型
17 6
|
22天前
|
Java
在Java中如何将基本数据类型转换为String
在Java中,可使用多种方法将基本数据类型(如int、char等)转换为String:1. 使用String.valueOf()方法;2. 利用+运算符与空字符串连接;3. 对于数字类型,也可使用Integer.toString()等特定类型的方法。这些方法简单高效,适用于不同场景。
45 7
|
1月前
|
存储 缓存 Java
大厂面试必看!Java基本数据类型和包装类的那些坑
本文介绍了Java中的基本数据类型和包装类,包括整数类型、浮点数类型、字符类型和布尔类型。详细讲解了每种类型的特性和应用场景,并探讨了包装类的引入原因、装箱与拆箱机制以及缓存机制。最后总结了面试中常见的相关考点,帮助读者更好地理解和应对面试中的问题。
53 4
|
1月前
|
存储 消息中间件 NoSQL
使用Java操作Redis数据类型的详解指南
通过使用Jedis库,可以在Java中方便地操作Redis的各种数据类型。本文详细介绍了字符串、哈希、列表、集合和有序集合的基本操作及其对应的Java实现。这些示例展示了如何使用Java与Redis进行交互,为开发高效的Redis客户端应用程序提供了基础。希望本文的指南能帮助您更好地理解和使用Redis,提升应用程序的性能和可靠性。
37 1
|
2月前
|
算法 Java 测试技术
🌟Java 零基础 | 详解 单目运算符
【10月更文挑战第14天】本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
48 7
|
2月前
|
存储 安全 Java
从入门到精通:Java Map全攻略,一篇文章就够了!
【10月更文挑战第19天】本文介绍了Java编程中重要的数据结构——Map,通过问答形式讲解了Map的基本概念、创建、访问与修改、遍历方法、常用实现类(如HashMap、TreeMap、LinkedHashMap)及其特点,以及Map在多线程环境下的使用和性能优化技巧,适合初学者和进阶者学习。
73 4
|
2月前
|
Java 测试技术 开发者
🌟Java 零基础 | 深入理解三目运算符
【10月更文挑战第13天】本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
39 3
|
2月前
|
存储 Java 关系型数据库
[Java]“不同族”基本数据类型间只能“强转”吗?
本文探讨了不同位二进制表示范围的计算方法,重点分析了Java中int和char类型之间的转换规则,以及float与int类型之间的转换特性。通过具体示例说明了显式和隐式转换的条件和限制。
38 0
[Java]“不同族”基本数据类型间只能“强转”吗?