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,而是周日

运算符的优先级

①不要以来运算符的优先级来控制表达式的执行顺序,尽量用( )来控制表达式的执行顺序

②不要把表达式写的过于复杂,可以分成几步去写

 

posted on   gjwqz  阅读(11)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

点击右上角即可分享
微信分享提示