JavaSE:数据类型与运算符

数据类型与运算符

变量和类型

变量指的是程序运行时可变的量,相当于开辟一块内存空间来保存一些数据,并且只有在程序运行的时候才能知道该变量的值是多少。类型则是变量种类的一种划分, 不同的类型的变量具有不同的特性.

整型变量:int

格式: int 变量名 = 初始值;
举例: int a = 2333;//定义了一个变量名为a的整型变量

我们在后续使用该变量时,都通过其变量名a使用,给变量a初始化是可选的,但是我们建议创建变量的时候都对其进行显式初始化。

在 Java 中, 一个 int 变量占 4 个字节. 和操作系统没有直接关系,而在C语言中,16位的操作系统占2个字节,32/64位的操作系统占4个字节,与操作系统是有关的。

在计算机中,数值一律用二进制的补码来存储的。二进制的最高位是符号位,0表示正数,1表示负数,每个二进制数存储时占1个bit位,8 个二进制位(bit) 为一个字节(Byte),所以int型的变量占32个二进制位(bit),除最高位所代表的符号位外,共有31个二进制位可以用来表示数。在这里插入图片描述

长整型变量:long

如果运算的结果超出了 int 的最大范围, 就会出现溢出的情况,在这种情况下我们就需要使用更大范围的数据类型来定义变量,Java中提供了long类型

格式: long 变量名 = 初始值;
举例: int num = 123L;//定义了一个变量名为num,初始值为123的长整型变量

使用 10 初始化也可以, 10 的类型是 int, 这种情况是一种类型转换,不同数字类型的变量之间赋值, 表示范围更小的类型能隐式转换成范围较大的类型, 反之则不行,而我们写成10L/10l(大小写均可) 的类型是 long,这样赋值更好一些,并且为了区分小写l和1,我们通常使用大写字母L。

Java 中 long 类型占 8 个字节. 表示的数据范围 是为**:-2^63 – 2^63-1**

双精度浮点型变量:double

格式: double 变量名 = 初始值;
举例: double b = 1.0;

重点:

int a = 1;
int b = 2;
System.out.println(a/b);

在java中int类型除以int类型的值任然为int值,会直接舍弃小数部分

在这里插入图片描述

如果想得到0.5,则需要使用double类型进行计算

double a = 1;
double b = 2;
System.out.println(a/b);

在这里插入图片描述

如果我们这样计算,理论上结果应该是1.21,实际上呢?

double num = 1.1;
System.out.println(num*num);

在这里插入图片描述

为什么我们得到的结果不是精确的1.21,而是1.2100000000000002呢?(了解)

  • Java 中的 double 虽然也是 8 个字节, 但是浮点数的内存布局和整数差别很大, 不能单纯的用 2 ^ n 的形式表示数据范围. Java 的 double 类型的内存布局遵守 IEEE 754 标准(和C语言一样), 尝试使用有限的内存空间表示可能无限的小数, 势必会存在一定的精度误差.

单精度浮点型变量:float

格式: float 变量名 = 初始值;
举例: float c = 2.0f;

float类型在Java中占四个字节,一般在工程上用到浮点数都优先考虑使用double,故不太推荐使用float,与double相同的是,在赋值时后面所加的2.0F/2.0f(大小写均可)是可选的,但仍旧推荐加上。

字符类型变量:char

格式: char 变量名 = 初始值;
举例: char c = 'A';

Java 中使用 单引号 + 单个字母 的形式表示字符字面值,而计算机中的字符本质上是一个整数,C 语言中使用 ASCII编码 表示字符,而 Java 中使用 Unicode编码表示字符,在Unicode编码中,一 个字符占用两个字节, 因此表示的字符种类更多, 所以包括中文等很多国家的语言。举例如下:

char ch = '汉'; 
System.out.println(ch);

在这里插入图片描述

字节类型字符变量:byte

格式: byte 变量名 = 初始值;
举例: byte a = 1;

字节类型表示的也是整数,只占一个字节,表示范围较小 ( -128 – +127 ),虽然该类型与字符类型名字相似,但两者完全毫不相干

短整型变量:short

格式: short 变量名 = 初始值;
举例: short n = 10;

short 占用 2 个字节, 表示的数据范围是 (-32768 —— +32767) ,这个表示范围比较小,一般不推荐使用。

布尔类型变量:boolean

格式: boolean 变量名 = 初始值; 
举例: boolean flag = true;

boolean类型的变量只有两种取值:true和false, true 表示真, false 表示假,与C++不同的是, Java 的布尔类型变量中的true和false不能和int型变量相互转换,不存在 1 表示 true,0表示false这样的用法,特殊的是,boolean类型有些 JVM 的实现是占 1 个字节,有些是占 1 个比特位,无明确规定。

字符串类型变量: String

和上面的类型不同, String 不是基本类型, 而是引用类型

格式: String 变量名 = "初始值";
举例: String s = "abcdef";

字符的组合称之为字符串,Java中使用双引号加字符串的方式表示字符串的字面值,即"abcdef"表示字符串abcdef

与C语言相同的是,Java字符串中的一些特定的不太方便直接表示的字符需要进行转义,转义规则与C语言相同,如下:

转义字符功能
\n换行
\t水平制表符
\’单引号
\"双引号
\\反斜杠

**字符串拼接:**可以用+来拼接字符串

String a = "abc";
String b = "def";
System.out.println(a+b);

在这里插入图片描述

当字符串和其他类型变量相加是什么情况呢?

String a = "abc";
String b = "def";
int c = 233;
boolean flag = false;
System.out.println(a+c);
System.out.println(b+1.0);
System.out.println(a+b+flag);

在这里插入图片描述

由此可见,当+表达式中存在字符串时,和其他类型的相加,都执行的是字符串形式的相加

变量的作用域

变量的作用域指的是定义的变量可以发挥作用的范围,一般是变量所定义的代码块(花括号)内。

int a = 0;
{
	int b = 0;
}
System.out.println(a+b);

在这里插入图片描述

显然,在变量b的作用域外是不能使用变量b的

变量的命名规则

硬性规则:

  • 变量名只能包含数字,字母, 下划线,美元符号($)
  • 不能以数字开头
  • 大小写是严格区分的,即变量A与变量a是两个不同的变量

强烈建议:

  • 变量命名要具有描述性,做到见名知意,最好是名词,不宜使用拼音。

  • 变量命名推荐小驼峰命名法,当一个变量名由多个单词构成的时候,除了第一个单词之外,其他单词首字母都大 写。

    int maxValue = 233; 
    String studentName = "张三";
    

常量

常量是在程序运行时不能被改变的量,只能被初始化一次,并且在程序编译时常量的值就已经被确定了。每种类型的变量也对应着一种想同类型的常量。

常量主要有一下两种体现形式:

字面值常量

10 //int字面值常量(十进制) 
010//int字面值常量(八进制)由数字0开头,010也就是十进制的8 
0x10//int字面值常量(十六进制)由数字0x开头,0x10也就是十进制的16 
10L//long字面值常量,也可以写作10l(小写L) 
1.0//double字面值常量,也可以写作1.0d或者1.0D 
1.5e2//double字面值常量,科学计数法表示,相当于1.5*10^2 
1.0f//float字面值常量,也可以写作1.0F 
true//boolen字面值常量,同样的还有false 
'a'//char字面值常量,单引号中只能有一个字符
"abc"//String字面值常量,双引号中可以有多个字符

final关键字修饰的常量

final double a=5.0d;
a=10.0;
System.out.println(a);

在这里插入图片描述

常量不能在程序运行中发生修改

类型转换和数值提升

类型转换

Java 作为一个强类型编程语言,当不同类型之间的变量相互赋值的时候,会有教严格的校验,例子如下:

int a = 5; 
long b = 10; 
a = b; // 编译出错, 提示可能会损失精度. 
b = a; // 编译通过. 
int c = 10; 
double d = 1.0; 
c = d; // 编译出错, 提示可能会损失精度. 
d = c; // 编译通过. 

在这里插入图片描述

long表示的范围更大,可以将int赋值给 long,但是不能将long赋值给int,double表示的范围更大,可以将int赋值给double,但是不能将double赋值给int。

不同数字类型的变量之间赋值,表示范围更小的类型能隐式转换成范围较大的类型,反之则不行。

int a = 1;
boolean b = true;
b = a; // 编译出错, 提示不兼容的类型
a = false; // 编译出错, 提示不兼容的类型

在这里插入图片描述

int和boolean是毫不相干的两种类型,不能相互赋值

byte a = 2;
byte b =128;//编译报错,不兼容的类型:从int转换到byte可能会有损失
System.out.println(a);
short c = 233;
short d = 32768//编译报错,不兼容的类型:从int转换到short可能会有损失
System.out.println(d);

在这里插入图片描述

byte表示的数据范围是-128 — +127,128已经超过范围,而2还在范围之内,short表示的范围在-32768 — +32767,32868已经超过范围,而233还在范围之内。

使用字面值常量赋值的时候, Java 会自动进行一些检查校验, 判定赋值是否合理,这也解释了为什么我们用int型的字面值常量给范围更小的byte和short进行赋值时不会报错的原因。

强制类型转换

int a = 5;
long b = 10;
a = (int)b;//编译通过
boolean c = false;
c = a;// 编译出错, 提示不兼容的类型.
c = (boolean)a;// 编译出错, 提示不兼容的类型.

在这里插入图片描述

上面的例子中,赋值之后,10.5就变成10了,小数点后面的部分被忽略,int类型不能强制类型转换为boolean类型。

使用强制类型转换的方式可以将double类型强制转成int,但是强制类型转换可能会导致精度丢失,并且强制类型转换不是一定能成功,互不相干的类型之间无法进行强制类型转换。

数值提升

int a = 10;
long b = 20;
int c = a + b; // 编译出错,提示将long转成int会丢失精度
long d = a + b;//编译通过
int e =(int)(a + b);// 编译通过

在这里插入图片描述

当int和long混合运算的时候,int会提升成long,得到的结果仍然是long类型,需要使用long类型的变量来接收结果,如果非要用int来接收结果, 就需要使用强制类型转换

byte a = 10; 
byte b = 20; 
byte c = a + b;// 编译报错,不兼容的类型: 从int转换到byte可能会有损失
System.out.println(c); 

byte和byte都是相同类型,但是仍然会出现编译报错,是因为 a和b虽然都是byte,但是计算a+b会先将a和b都提升成int,再进行计算,得到的结果也是int,这时将int型的结果赋给c,就会出现上述错误

由于计算机的CPU通常是按照 4 个字节为单位从内存中读写数据,为了硬件上实现方便,诸如byte和short这种低于4 个字节的类型,会先提升成 int,再参与计算

int和String类型的相互转换

int转String

int num = 10;
String str1 = num + "";// 方法1
String str2 = String.valueOf(num); // 方法2
System.out.println(str1);
System.out.println(str2);

关于方法1的原理我们在分析String类型时已经讲过,方法2我们可以先记住,随着之后的学习我们会明白的

String转int

String str = "2333";
int num = Integer.parseInt(str);
System.out.println(num);

改方法我们可以先记住,随着之后我们学习,我们会明白的!

运算符

算术运算符:

基本运算符:加(+)减(-)乘(*)除(/)取余(%)

因为其规则较为简单,故我们不在赘述过多内容,只对其需要注意的部分进行一些说明

  1. int型/int型结果还是int型,若需要得到精确数值,需要使用double来计算
  2. 0不能做除数(编译会报错)
  3. %表示取余,不仅仅可以对整数取余,也能对小树来取余

增量赋值运算符: (+=) (-=) (*=) (/=) (%=)
可为我们自动进行强制类型转换
规则如下

a+=1  等价于  a=a+1;
b-=1   <=>  b=b-1;
c*=2   <=>  c=c*2;
d/=3   <=>  d=d/3;
e%=4   <=>  e=e%4;

自增/自减运算符: (++) (–)

int a = 2;
int b = 2;
System.out.println(a++);
System.out.println(++b);
System.out.println(a);
System.out.println(b);

在这里插入图片描述

如果不取自增运算的表达式的返回值, 则前置++/–和后置++/–没有区别,都是使该变量+1或者-1,如果取表达式的返回值,则前置++/–的返回值是++/–之后的值,后置++/–的返回值是++/–之前的值.,

关系运算符

关系运算符包括:等于**(==)** 大于**(>)** 大于等于**(>=)** 小于**(<)** 小于等于**(<=)** 不等于**(!=)**

int a = 2;
int b = 3;
System.out.println(a==b);
System.out.println(a>b);
System.out.println(a>=b);
System.out.println(a<b);
System.out.println(a<=b);
System.out.println(a!=b);

在这里插入图片描述

关系运算符的表达式返回值都是boolean类型

逻辑运算符

逻辑运算符主要有三个:与(&&) 或(||) 非(!)
注意: 逻辑运算符的操作数(操作数往往是关系运算符的结果)和返回值都是boolean

逻辑与(&&):两个操作数都为true,结果为true,否则结果为 false

System.out.println(10>20&&10>5);
System.out.println(10>5&&5>3);

在这里插入图片描述

逻辑或(||):两个操作数都为 false, 结果为 false, 否则结果为 true

System.out.println(10>20||10>5);
System.out.println(10>20&&5>30);

在这里插入图片描述

逻辑非(!):操作数为 true,结果为 false,操作数为 false,结果为 true(这是个单目运算符,只有一个操作数)

System.out.println(!(5>3));
System.out.println(!(3>7));

在这里插入图片描述

短路求值

&& 和 || 遵守短路求值的规则

System.out.println(1 > 2 && 5 / 0 == 0);
System.out.println(1 < 2 || 1 / 0 == 0);

在这里插入图片描述

我们知道,0是不能做除数的,这样会导致程序抛出异常. 但是上面的代码却能正常编译运行, 说明该运算并没有真正被求值,所以,对于 && ,如果左侧表达式值为 false,则表达式的整体的值一定是 false,无需计算右侧表达式,对于||,如果左侧表达式值为 true,则表达式的整体的值一定是 true,无需计算右侧表达式

位运算符

Java 中对数据的操作的最小单位不是字节,而是二进制位,位运算符主要有四个:(&) (|) (~) (^)

位操作表示按二进制位运算,计算机中都是使用二进制来表示数据的(01构成的序列),按位运算就是在按照二进制位的
每一位依次进行计算

按位与&: 如果两个二进制位都是 1, 则结果为 1, 否则结果为 0.

int a = 10;               //a的二进制:0000 1010
int b = 20;				  //b的二进制:0001 0100
int c = 8;				  //c的二进制:0000 1000
System.out.println(a&b);      //a&b=0000  0000  转换为十进制:0
System.out.println(a&c);	  //a&c=0000  1000	转换为十进制:8

在这里插入图片描述

按位或 |: 如果两个二进制位都是 0, 则结果为 0, 否则结果为 1.

int a = 10;                //a的二进制:0000 1010
int b = 20;                //b的二进制:0001 0100
int c = 8;                 //c的二进制:0000 1000
System.out.println(a|b);        //a|b=0001 1110   转换为十进制:30
System.out.println(a|c);		//a|c=0000 1010   转换为十进制:10

在这里插入图片描述

  • **当 & 和 | 的操作数为整数(int, short, long, byte) 的时候, 表示按位运算, 当操作数为 boolean 的时候, 表示逻辑
    运算,但是和 && 以及 || 相比, 它们不支持短路求值(不推荐使用此方法!!!) **
System.out.println(false&true);
System.out.println(false&false);
System.out.println(true&true);
System.out.println(false|true);
System.out.println(true|true);
System.out.println(false|false);

在这里插入图片描述

按位取反 ~: 如果该位为 0 则转为 1, 如果该位为 1 则转为 0

int a = 7;			   
System.out.println(~a);

这里的结果输出之后为-8,涉及到了一些计算机在计算时的原码反码补码的知识,这里也不在赘述,有兴趣可以自行了解

按位异或 ^: 如果两个数字的二进制位相同, 则结果为 0, 相异则结果为 1

int a = 10;                //a的二进制:0000 1010
int b = 20;                //b的二进制:0001 0100
int c = 8;                 //c的二进制:0000 1000
System.out.println(a^b);        //a^b=0001 1110   转换为十进制:30
System.out.println(a^c);		//a^c=0000 0010   转换为十进制:2

在这里插入图片描述

位移运算

移位运算符有三个:**(<<) (>>) (>>>)**都是按照二进制位来运算

左移 <<: 最左侧位不要了, 最右侧补 0. 右移 >>: 最右侧位不要了, 最左侧补符号位(正数补0, 负数补1) 无符号右移 >>>: 最右侧位不要了, 最左侧补 0

int a = 10;                //a的二进制:0000 1010
System.out.println(a<<1);  //a<<1=0001 0100   转换为十进制:20
System.out.println(a>>1);  //a>>1=0000 1010   转换为十进制:5
System.out.println(a>>>1); //a>>>1=0000 1010  转换为十进制:5

在这里插入图片描述

条件运算符

条件运算符只有一个,格式为: 表达式 1 ? 表达式 2 : 表达式3
当表达式1 的值为true时,整个表达式的值为表达式2的值,当表达式1 的值为 false 时,整个表达式的值为表达式3的值。

int a =10;
int b =20;
int max = a>b? a : b;
System.out.println(max);

在这里插入图片描述

Java 中唯一的一个 三目运算符, 是条件判断语句的简化写法

运算符的优先级

运算符之间是有优先级的,具体的规则我们不必记忆,我也不在此赘述,在写代码时根据自己的运算逻辑,加上括号即可。

在这里插入图片描述

以上就是本文的全部内容了,鉴于笔者水平有限,文章可能出现错误,希望大家可以多多批评指正!

  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值