Java基础3
变量
概念:内存中的一个存储区域,该区域的数据可以在同一类型范围内不断变化。
变量的构成三要素: 数据类型、变量名、存储的值
Java中变量声明的格式: 数据类型 变量名 = 变量值
说明:
1.变量都有其作用域。变量只在作用域内是有效的,出了作用域就失效了。
2.在同一个作用域内,不能声明两个同名的变量。
3.定义好变量以后,就可以通过变量名的方式对变量进行调用和运算。
数据类型
补充:引用数据类型包括:类(class)、数组([ ])、接口(interface)、枚举(enum)、注解(annotation)、记录(record) 前三种占主要
上图说明
1.java数据类型分为两大类基本数据类型,引用类型
⒉.基本数据类型有8中数值型 [ byte , short , int , long , float ,double, char , boolean ]
3.引用类型 [ 类,接口,数组 ]
整数类型:
整型的使用细节
1. Java各整数类型有固定的范围和字段长度,不受具体OS[操作系统]的影响,以保证java程序的可移植性。
2. Java的整型常量默认为int型,声明long型常量须后缀加'l'或'L'
3. java程序中变量常声明为int型,除非不足以表示大数,才使用long
4. bit:计算机中的最小存储单位。byte:计算机中基本存储单元,1byte = 8 bit.
补充:
字节(Byte): 是计算机用于计量存储容量的基本单位,一个字节等于 8 bit。
位(bit):是数据存储的最小单位。二进制数系统中,每个0或1是一个位,叫做bit(比特),其中8bit就称为一个字节(Byte)。
转换关系: 8 bit = 1 Byte 1024 Byte = 1 KB 1024 KB = 1 MB 1024 MB = 1 GB 1024 GB = 1 TB
浮点型:
1.关于浮点数在机器中存放形式的简单说明,浮点数=符号位+指数位+尾数位
2.尾数部分可能丢失,造成精度损失(小数都是近似值)。
注意:float表示数值的范围比long大
浮点型使用细节
1.与整数类型类似,Java浮点类型也有固定的范围和字段长度,不受具体OS的影响。[float 4个字节; double是8个字节]
2. Java的浮点型常量(具体值)默认为double型,因为double的精度更高,声明float型常量,须后加'f'或‘F'
3.浮点型常量有两种表示形式
- 十进制数形式:如:5.12 512.0f .512(必须有小数点)
- 科学计数法形式:如:5.12e2 [5.12*10的2次方] 5.12E-2[5.12/10的2次方]
浮点型的精度说明:
1.并不是所有的小数都可以精确的用二进制浮点数表示。二进制浮点数不能精确的表示0.1、0.01、0.001这样10的负次幂
2.浮点类型float、double的数据不适合在不容许舍入误差的金融计算领域。如果需要精确数字计算或保留指定位数的精度,需要使用BigDecimal类。
//float num1 = 1.1 ; // 对不对? 错误 因为小数默认为double型,没有声明不能够直接存放在float中。 float num2 = 1.1F; //对的 double num3 = 1.1; //对 double num4 = 1.1f; //对
浮点数使用陷阱:
//2.7 和 8.1/3比较看看一段代码 double num11 = 2.7; double num12 = 8.1/3;//2.7 System.out.println(num11);//2.7 System.out.println(num12);//接近2.7的一个小数,而不是2.7 //得到一个重要的使用点:当我们对运算结果是小数的进行相等判断是,要小心 //应该是以两个数的差值的绝对值,在某个精度范围类判断 if( num11 == num12){ System.out.print1n("相等");} //正确的写法 if(Math.abs(num11 - num12)<0.000001 ) { System.out.println("差值非常小,到我的规定精度,认为相等..."); }
字符型数据 char
char型数据用来表示通常意义上“字符” (占2字节)。
表示形式1 :使用一对' '(单引号)表示,内部有且仅有一个字符。
编译通过: char a1 = 'a' char a2 = '你' char a3 = '1' char a4 = '&' char a5 = 'γ'
编译不通过: char a1= 'ab' char = '' (''里面没有字符也不可以!)
表示形式2: 直接使用Unicode值来表示字符型常量: '\uXXX' 例如: char a1 = '\u0036';
char类型变量可以存储一个中文汉字,虽然中文字不在ASCII码中,但是在Unicode字符集中,包含了世界范围内所有的字符。
表示形式3: 使用转义字符 char a1 = '\t' char a2 = '\n'
表示形式4: 使用ASCII码 char a1 =97 System.out.print(a1) 输出a(ASCII码是97)
布尔型数据 boolean
只有两个取值 True False (不可以使用0或1的整数替代false和true,这和C语言不同的点)
布尔类型占几个字节?
编译的时候不谈占几个字节,但是在JVM给boolean类型分配内存空间时,boolean类型的变量占用一个槽位(slot,4个字节和int一样)
拓展:在内存中,byte/short/char/boolean/int/float :占用1个slot double/long: 占用2个slot
基本数据类型变量建的运算规则
可以做运算的基本数据类型有7种,不包含boolean类型!
运算规则包括: ① 自动类型提升 ② 强制类型转换
- 自动类型提升
规则:当容量小的变量与容量大的变量做运算时,结果自动转换为容量大的数据类型。
说明:此时的容量小或大,并非指占用的内存空间的大小,而是指表示数据的范围的大小。
举例: long(8字节) float(4字节) 但实际上float的表示范围比long大,所以long型的数据可以转换为float型
结论: byte / short / char ---> int ---> long ---> float ----> double
按理说:byte ---> short ---> int ---> long --->float --->double
特殊的: byte a = 12; byte b = 10; byte c = a + b; 编译不通过! short d = 10; short e = d + a; 编译不通过!
如果改为int c = a +b; 通过! int e = d + a; 通过!
char a1 = 'a'; char f = a1 + a; 编译不通过! 改为: int f = a1 +a; 通过!f = 109 ('a'转换为int 是97 再+12)
byte 、short 、char类型的变量之间做运算,结果为 int 型!
//练习1: long l1 = 123L; //标准的long类型数据的赋值 long l2 = 123; //这不是long类型数据赋值,而是理解为自动类型提升, 这里的123是int类型(int ---> long) //因此 long l3 = 12312312312312; 这行语句会报错,因为12312312312312应该为int类型,但是超出了int的表示范围 long l4 = 12312312312312L; //此时不会报错,因为这里12312312312312L是long类型,使用了8个字节存储。 //练习2: float f1 = 12.3F; //标准的float类型的赋值 //float f2 = 12.3; 会报错,这里的12.3被理解为double类型,不满足自动类型提升的规则 (double ---> float) //练习3: //规定1:整型常量,规定为int类型 byte b1 = 10; // byte b2 = b1 + 1; 这行语句会报错,因为1是int类型, 应该为int i1 = b1 + 1; //规定2:浮点型常量,规定为double类型 double d1 = b1 + 12.3; //不可以用byte b2 = b1 + 12.3; 因为12.3为double类型!
- 强制类型转换
规则:
1. 如果需要将容量大的变量的类型转换为容量小的变量的类型,需要使用强制类型转换
2. 强制类型转换需要使用强转符: ( ) 在( )内指明要转为的数据类型。
3. 强制类型转换过程中可能会导致精度损失
//精度损失例子: double d1 = 12.9; int i1 = (int) d1; //i1为12 是直接截断而不是四舍五入! //例子2: int i2 = 128; byte b1 = (byte) i2; //这里的b1是-128!因为int中的128是1000 0000 占一个字节,而byte就是一个字节,最高位为符号位 所以是-128
为什么标识符的声明规则里面要求不能用数字开头:
//如果允许数字开头,则这个的声明编译就可以通过: int 123L = 12; //进而,如下的声明中的l的值到底是123?还是变量123L对应的值12呢? long l = 123L;
基本数据类型与String的运算:
注意:String类,属于引用类型而不是基本数据类型!俗称字符串。
String类型的变量,可以使用一对" "(双引号)的方式进行赋值,String声明的字符串内部,可以包含0个、1个或多个字符。
String与基本数据类型(8种 包含boolean)变量之间的运算:
String与基本数据类型变量之间只能做连接运算,使用"+"表示。
//测试String连接运算 int num1 = 10; boolean b1 = true; String str1 = "hello"; System.out.println(str1 + b1); // 输出:hellotrue System.out.println(str1 + b1 +num1); // 输出:hellotrue10 //但是如下的编译不可以!! String str2 = b1 + num1 + str1; //因为运算是从左到右 先做b1 + num1 但是布尔类型和int类型不可以直接相加 //除非把String类型的数据放在前面 str1 + b1是String类型 字符串类型和其他任意都可以连接
如何把String类型转换为其他数据类型
String str1 = "10"; int num = Integer.parseInt(str1); //想要将String类型的变量转换为其他的类型,需要使用Integer类
//练习: String str = 3.5f +""; System.out.println(str); //输出:3.5 因为是将float类型转换为了String类型 不要带后面的f! System.out.println('a' + 1 + "hello!"); //输出:98hello! 因为'a'的ASCII码为97 char+int为 int 即98 System.out.println("* *"); //输出:* * System.out.println('*' +"\t" + "*"); //输出:* * 因为char类型+字符串是表示连接 而“\t”是tab键 System.out.println('*' + '\t' + "*"); //输出:51* 因为此时的'\t'表示一个字符 所以前面的两个相加为int类型
进制的分类:
- 十进制(decimal) 数字组成:0-9 进位规则:满十进一
- 二进制(binary) 数字组成:0-1 进位规则:满二进一,以'0b'开头或'0B'开头 (这里的0是数字零)
- 八进制(octal) 数字组成:0-7 进位规则:满八进一,以数字‘0’开头
- 十六进制 数字组成:0-9,a-f 进位规则:满十六进一,以'0x'开头或'0X'开头 (这里的0是数字零)此处的a-f不区分大小写
二进制转十进制:
计算机数据的存储使用二进制补码形式存储
二进制最高位为符号位。规定: 正数:最高位是0; 负数: 最高位是1.
正数的补码、反码和原码一样,称之“三码合一” 负数的补码、反码和原码不一样
负数的原码:把十进制转为二进制,然后最高位设置为1,
负数的反码:在原码的基础上,最高位保持不变,其余位取反(0变1,1变0)
负数的补码:反码+1
十进制转二进制:
方法:除2取余的逆
二进制与八进制、十六进制之间的转换:
十进制与八进制、十六进制之间的转换可以用二进制当做桥梁,间接相互转换。
运算符(operator)
运算符是一种特殊的符号,用以表示数据的运算、赋值、比较等
按照功能分类:
按照操作个数分为:一元运算符(单目运算符)、二元运算符(双目运算符)、三元运算符(三目运算符)
算数运算符
+(正) -(负) +(加) -(减) * / % (前)++ (后)++ (前)-- (后)-- +(连接)
/* 算术运算符的使用: +(正) -(负) +(加) -(减) * / % (前)++ (后)++ (前)-- (后)-- +(连接) */ //除法: int m1 = 12; int n1 = 5; int k1 = m1 / n1; //输出:2 因为得到的结果用整型接收,除非用类型转换 //取模:取模以后,结果跟被模数符号一致 int i = -12; int j = 5; System.out.println(i%j); //-2 int i = 12; int j = -5; System.out.println(i%j); //2 int i = -12; int j = -5; System.out.println(i%j); //-2 //(前)++:先自增1,再运算; (后)++:先运算,后自增1 short s1 = 10; //编译不会通过: s1 = s1 + 1; 因为s1是short类型,但是1是int 不符合自动类型提升 s1 ++; //可以得到 11 自增不会改变数据类型!
注意:
//练习1 byte b1 = 127; b1 ++; //这里得到的是-128 因为127是0111 1111 再+1 即 1000 0000就是-128 //练习2 int i = 1; int j = i++ + ++i * i++; //即j = 1 + 3*3; 所以i=4,j=10; 自增是从左到右的 运算是先乘除后加减 //练习3 int m = 2; m = m++; System.out.println(m); //输出:2 //首先m=2,然后把m的值存储在一个空间后续会赋值 然后2+1 但是存储的值还是2不会变, 再把存储的2赋值给为3的m 所以还是2
赋值运算符
= += -= *= /= %=
说明:
- 当“=”两侧的数据类型不一致时,可以使用自动类型转换或者使用强制类型转换原则进行处理
- 支持连续赋值
- += -= *= /= %= 操作不会改变变量本身的数据类型
//说明1 “=”两侧数据类型不一致时,可以使用自动类型提升或使用强制类型转换处理 int i = 5; long l = 10;//自动类型提升 int 提升到long byte b = (byte) i; //强制类型转换 //连续赋值一: int a1,b1; a1 = b1 = 10; //连续赋值二: int a2 = 10, b2 = 20; //+= -= *= /= %=不会改变数据类型 byte by1 = 10; by1 += 5;//实际上是 by1 = (byte)(by1 + 5); //练习: int n = 10; n += (n++) + (++n); System.out.println(n); //输出n是32 即 n = n + (n++) + (++n)
比较运算符
说明:
- == != >= <= > <适用于除boolean类型之外的其他7中基本数据类型, 比较运算符的结果是boolean类型
- == != 可以适用于引用数据类型
//区分== 与= boolean a = false; boolean b = true; System.out.println(a == b); //false System.out.println(a = b); //是将b的值赋给a true
逻辑运算符
说明:
- 逻辑运算符针对的都是boolean类型的变量进行的操作,得到的运算结果也是boolean类型
- 逻辑运算符常使用在条件判断结构、循环结构中
位运算符
<< (左移)
在一定范围内,每向左移动一位,结果就在原有的基础上*2。(对于正数、负数都适用)
//<< 在一定范围内,左移一位就在原基础上乘2 int num1 = 7; // 0111 System.out.println(num1<<2); //输出14, 1110 System.out.println(num1<<28); //得到的是负数 因为符号位变为1了 过犹不及
注意:负数的运算用补码,运算结果看原码
>>(右移)
在一定范围内,数据每向右移动一位,相当于原数据/2。(正数、负数都适用) 注意:如不能整除,向下取整。
>>>(无符号右移)
往右移动后,左边空出来的位直接补0.(正数、负数都适用)
按位与:&
运算规则:对应位都是1才为1,否则为0. 1&1=1 1&0=0 0&1=0 0&0=0
按位或:|
运算规则:对应位只要有1即为1,否则为0。 1|1=1 1|0=1 0|1=1 0|0=0
按位异或:^
运算规则:对应位一个为1一个为0,才为1,否则为0. 1^1=0 1^0=1 0^1=1 0^0=0
交换两个变量的值:
int m =10; int n = 20; //方式一: int temp = m; m = n; n = temp; //方式二: 优点:不需要定义临时的变量 缺点:适用性差,非数值类型不适用、可能超出int的范围 m = n + m; n = m - n; m = m - n; //方式三: 优点:不需要定义临时的变量 缺点:不适用非数值类型 m = m ^ n; n = m ^ n; //(m^n)^n -->m m = m ^ n;
按位取反:~
运算规则:对应位为1,即结果为0;对应位为0,即结果为1.
条件运算符
条件运算符格式: (条件表达式)?表达式1 : 表达式2
说明:
- 条件表达式的结果是boolean类型
- 如果条件表达式的结果是true,则执行表达式1,否则执行表达式2.
- 开发中,凡是可以使用条件运算符的位置,都可以改写成if-else。反之,能使用if-else结构不一定能够改写为条件运算符。
//练习: 控制台输出“今天是周2,10天后是周X” int week = 2; //week = 4; week += 10; week %= 7; System.out.println("今天是周2,10天以后是周" + ( (week==0) ? "日" : week) ) //如果是week%7=0 不能输出周0,而是周日
运算符的优先级
①不要以来运算符的优先级来控制表达式的执行顺序,尽量用( )来控制表达式的执行顺序
②不要把表达式写的过于复杂,可以分成几步去写
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理