Java语言的基础

image-20240408213857363

第1章 Java语言基础

1.1 Java主类结构

Java语言是面向对象的程序设计语言,Java程序的基本组成单元是类,类体中又包括属性和方法两部分。每一个应用程序都必须包含一个main()方法,含有main()方法的类称为主类。下面通过程序来介绍Java主类结构。

【例1.1】创建主类并调动其主方法,实现在控制台上输出“你好Java”

1
2
3
4
5
6
7
8
9
package Number;
public class Frist{
static String s1 = "你好"
public static void main(String[] args){
String s2 = "Java";
System.out.println(s1);
System.out.println(s2);
}
}

注意

代码中的所有标点符号都是英文字符。不要在中文输入法状态下输入标点符号,如双引号和分号,否则会导致编译错误。

文件名必须和类名Frist相同,即Frist.java。还要区分大小写,Java是区分大小写的。

1.包声明

一个Java应用程序是由若干个类组成的。在例1.1中就是一个类名为Frist的类,语句package Number为声明该类所在的包,package为包的关键字。

2.声明成员变量和局部变量

通常将类的属性称为类的全局变量(成员变量),将方法中的属性称为局部变量。全局变量声明在类体中,局部变量声明在方法体中,全局变量和局部变量都有各自的应用范围。在例1.1中,s1是成员变量,s2是局部变量。

3.编写主方法

main()方法是类体中的主方法。该方法从“{”开始,至”}”结束。public、static和void分别是main()方法的权限修饰符、静态修饰符和返回值修饰符,Java程序中的main()方法必须声明为public static void。String[] args是一个字符串类型的数组,它是main()方法的参数。main()方法是程序开始执行的位置。

4.导入API类库

在Java语言中可以通过import关键字导入相关的类。在JDK的API中(应用程序接口)提供了130多个包,如java.awt、java.io等。可以通过JDK的API文档来查看这些包中的类,把握类的继承结构、类的应用、成员变量表、构造方法表等,并对每个变量的使用目的进行了解,API文档是程序开发人员不可或缺的工具。

误区警示

Java语言是严格区分大小写的。例如,不能将关键字class等同于Class.

1.2 基本数据类型

在Java中有8种基本数据类型来存储数值、字符和布尔值,如图所示。

image-20240409220719993

1.2.1 整数类型

整数类型简称整型,用来存储整数数值,即没有小数部分的数值。可以是正数,也可以是负数。整型数据根据它所占内存大小的不同,可分为byte、short、int和long 4种类型。它们具有不同的取值范围。

数据类型 内存空间(8位等于1字节) 取值范围
byte 8位 -128~127
short 16位 -32768~32767
int 32位 -2147483648~2147483647
long 64位 -9223372036854775808~9223372036854775807

下面分别对这4种整型数据类型进行介绍。

1.int型

1
2
3
4
int x;                        //定义int型变量x
int x,y; //同时定义int型变量x,y
int x = 10,y = -5; //同时定义int型变量x,y并赋予初值
int x = 5+23; //定义int型变量x,并赋予公式(5+23)计算结果的初值

int变量在内存中占4字节,也就是32位bit,在计算机中bit是由0和1来表示的,所以int型值5在计算机中是这样显示的:00000000 00000000 00000000 00000101

int型是Java整数值的默认数据类型。当对多个尚未定义数据类型的整数做运算时,运算的结果将默认为int类型。例如,下面这行代码:

​ System.out.println(15+20); // 输出35

等同于如下代码:

1
2
3
4
int a = 15;
int b = 20;
int c = a+b;
System.out.println(c); //输出35

2.byte型

byte型的定义方式与int相同。定义byte类型变量,代码如下:

1
2
3
byte a;
byte a,b,c;
byte a = 19,b = -45;

3.short型

short型的定义方式与int相同。定义short类型变量,代码如下:

1
2
3
4
short s;
short s,t,r;
short s = 1000,t = -19;
short s = 20000/10;

4.long型

由于long型的取值范围比int型大,且属于高精度数据类型,所以在赋值时要和int型作出区分,需要在整数后加L和l。定义long类型变量,代码如下:

1
2
3
4
long number;
long number,rum;
long number = 12345678l,rum = -987654321L;
long number = 123456789L*987654321L;

注意

整数在Java程序中有3种表示形式,分别为十进制、八进制和十六进制:

(1)十进制:十进制如120、0、-127

(2)八进制:0123(转化为十进制为83),八进制必须为0开头

(3)十六进制:0x23(转化为十进制为37)、0Xb01e(转化为十进制为45086),十六进制必须为0X或0x开头。

1.2.2 浮点类型

浮点类型简称浮点型,用来存储含有小数部分的数值。Java语言中浮点类型分为单精度浮点类型(float)和双精度浮点类型(double),它们具有不同的取值范围,如表所示。

数据类型 内存空间(8位等于1字节) 取值范围
float 32位 1.4E-45~3.4028235E38
double 64位 4.9E-324~1.7976931348623157E308

在默认情况下小数都被看做double型,若想使用float型小数,则需要在小数后面添加F或f。另外,可以使用后缀d或D来明确表明这是一个double类型数据,但加不加d或D并没有硬性规定,系统会认为是double类型数据,进而出错。定义浮点类型变量,代码如下:

1
2
3
float f1 = 13.23f;
double d1 = 4562.12d;
double d2 = 45678.1564;

误区警示

浮点值属于近似值,在系统中运算后的结果可能与实际有偏差。

【例1.2】根据身高体重计算BMI指数

创建BMLexponent类,声明double型变量height来记录身高,单位为米;声明int型变量weight记录体重,单位为千克;根据BMI = 体重/(身高*身高)计算BMI指数。实例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class BMIexponent{
public static void main(String[] args){
double height = 1.72; //身高变量,单位:米
int weight = 70; //体重变量,单位:千克
double exponent = weight/(height*height); //BMI计算公式
System.out.println("您的身高为:"+height);
System.out.println("您的体重为:"+weight);
System.out.println("您的BMI指数为:"+exponent);
System.out.println("您的体重属于:");
if(exponent<18.5){ //判断BMI指数是否小于18.5
System.out.println("体重过轻");
}
if(exponent>=18.5 && exponent<24.9){ //判断BMI指数是否在18.5到24.9之间
System.out.println("正常范围");
}
if(exponent>=24.9 && exponent<29.9){ //判断BMI指数是否在24.9到29.9之间
System.out.println("体重过重")
}
if(exponent>=29.9){ //判断BMI指数是否大于29.9
System.out.println("肥胖")
}
}
}

运行结果如下

1
2
3
4
您的体重为:1.72
您的体重为:70
您的BMI指数为:23.661438615467823
您的体重属于:正常范围

1.2.3 字符类型

1.char型

字符类型(char)用于存储单个字符,占用16位(两个字节)的内存空间。在定义字符型变量时,要以单引号表示,如’s’表示一个字符。但是”s”则表示一个字符串,虽然只有一个字符,但由于使用双引号,它仍然表示字符串,而不是字符。

使用char关键字可定义字符变量,其语法如下:

1
char x = 'a';

由于字符a在Unicode表中的排序位置是97,因此允许将上面的语句写成:

1
char x = 97;

同C和C++语言一样,Java语言也可以把字符作为整数对待。由于Unicode编码采用无符号编码,可以存储65536个字符(0x0000~0xffff),所以Java中的字符几乎可以处理所有国家的语言文字。若想得到一个0~65536的数所代表的Unicode表中相应位置上的字符,也必须使用char型显式转换。

【例1.3】查看字符与Unicode码互转的结果

在项目中创建类Gess,编写如下代码,将Unicode表中某些位置上的字符以及一些字符在Unicode表中的位置在控制台上输出。

1
2
3
4
5
6
7
8
9
10
public class Gess{
public static void main(String[] args){
char word = 'd',word2 = '@';
int p = 23045,p2 = 45213;
System.out.println("d在Unicode表中的顺序位置是:"+(int)word);
System.out.println("@在Unicode表中的顺序位置是:"+(int)word2);
System.out.println("Unicode表中的第23045位是:"+(char)p);
System.out.println("Unicode表中的第45213位是:"+(char)p2);
}
}

运行结果如下:

1
2
3
4
d在Unicode表中的顺序位置是:100
@在Unicode表中的顺序位置是:64
Unicode表中的第23045位是:娅
Unicode表中的第45213位是:?

String类型为字符串类型,可以用来保存由多个字符组成的文本内容,其用法与字符类型相似,但文本内容需要用双引号标注。

2.转义字符

转义字符是一种特殊的字符变量,它以反斜杠”\“开头,后跟一个或多个字符。转义字符具有特定的含义,不同于字符原有的意义,故称”转义“。例如,printf函数的格式串中用到的”\n“就是一个转义字符,意思是”回车换行“。Java中的转义字符如图所示。

转义字符 含义 转义字符 含义
\ddd 1~3位八进制数据所表示的字符,如\123 \r 回车
\uxxxx 4位十六进制数据所表示的字符,如\u0052 \n 换行
\‘ 单引号字符 \b 退格
\\ 反斜杠字符 \f 换页
\t 垂直制表符,将光标已到下一个制表符的位置

将转义字符赋值给字符变量时,与字符常量值一样需要使用单引号。

【例1.4】输出‘\’字符和‘★’字符。

‘\’字符的转义字符为‘\\’,‘★’字符的Unicode码为2605,实例代码如下:

1
2
3
4
5
6
7
8
public class Demo{
public static void main(String[] args){
char c1 = '\\'; //
char char1 = '\u2605';
System.out.println(c1);
System.out.println(char1);
}
}

运行结果如下:

1
2
\

1.2.4 布尔类型

布尔类型又称逻辑类型,简称布尔型,通过关键字boolean来定义布尔类型变量。布尔类型只有true和false两个值,分别代表布尔逻辑中的“真”和“假”。布尔值不能与整数类型进行转换。布尔类型通常被用在流程控制中,作为判断条件。定义布尔类型变量,代码如下:

1
2
3
boolean b;                       //定义布尔型变量b
boolean b1,b2; //定义布尔值变量b1,b2
boolean b = true; //定义布尔值变量b,并赋给初值true

1.3 变量与常量

在程序执行过程中,其值不能被改变的量称为常量,其值能被改变的量称为变量。变量与常量的命名都必须使用合法的标识符。

1.3.1 标识符和关键字

1.标识符

标识符可以简单的理解为一个名字,是用来标识类名、变量名、方法名、数组名、文件名 的有效字符序列。

Java语言规定标识符由任意顺序的字母、下划线(_)、美元符号($)和数字组成,并且第一个字符不能是数字。标识符不能是Java中的关键字(保留字)。

在Java语言中,标识符中的字母是严格区分大小写的。Java语言使用Unicode标准字符集,最多可以标识65535个字符。

2.关键字

关键字又称保留字,是Java语言中已经被赋予特定意义的一些单词,不可以把这些单词作为标识符来使用。如图所示。

image-20240411222025653

1.3.2 声明变量

变量的使用是程序设计中一个十分重要的环节。声明变量就是要告诉编译器(compiler)这个变量的数据类型,这样编译器才知道需要配置多少空间给它,以及它能存放什么样的数据。在程序运行过程中,空间内的值是变化的,这个内存空间就称为变量。为了便于操作,给这个内存空间取个名字,称为变量名。变量的命名必须是合法的标识符。内存空间内的值就是变量值。在声明变量时可以是没有赋值,也可以是直接赋给初值。

例如,声明一个整数类型变量和声明一个字符类型变量,代码如下:

1
2
int age;                         //声明int型变量
char char1 = 'r'//声明char型变量并赋值

变量占用的内存空间:

image-20240411223445097

如图所知,由图3.2可知,系统的内存可大略分为3个区域,即系统(OS)区、程序(Program)区和数据(Data)区。当程序执行时,程序代码会加载到内存中的程序区,数据暂时存储在数据区中。假设上述两个变量定义在方法体中,则程序加载到程序区中。当执行此行程序代码时,会在数据区配置空间给出这两个变量。
对于变量的命名并不是随意的,应遵循以下几条规则:
 变量名必须是一个有效的标识符。
 变量名不可以使用Java中的关键字。
 变量名不能重复。
 应选择有意义的单词作为变量名。
说明
在Java语言中允许使用汉字或其他语言文字作为变量名,如“int年龄= 21”,在程序运行时不会出现错误,但建议读者尽量不要使用这些语言文字作为变量名。

1.3.3 声明常量

在程序运行过程中一直不会改变的量称为常量(constant),通常也被称为“final变量“。常量在整个程序中只能被赋值一次。在为所有的对象共享值时,常量是非常有用的。

在Java语言中声明一个常量,除了要指定数据类型,还需要通过final关键字进行限定。声明常量的标准语法如下:

1
final 数据类型 常量名称 [= 值]

当变量被final关键字修饰时,该变量就变成了常量,必须在定义时就设定它的初值,否则将会产生编译错误。

【例1.5】尝试给常量赋值,观察是否会发生错误。

​ 在项目中创建Part,在类体中创建变量age与变量PI。在主方法中分别将变量与常量赋值,通过输出信息可测试变量与常量的有效范围。

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Part{
static fianl double PI=3.14;
static int age=23;
public static void main(String[] ages){
final int number;
number = 1235;
age = 22;
number = 1236;
System.out.println("常量PI的值;"+PI);
System.out.println("赋值后number的值为:"+number);
System.out.println("int型变量age的值为:"+age);
}
}

运行结果如下:

1
2
3
Exception in thread"main"java.lang.Error:无法解析的编译问题:
final 局部变量 number 可能已经被赋过值
at Partmain(Part.java:10)

从这个结果可以看到,Part类运行后发生了错误,异常日志中记载Part类出现编译问题,此编译问题正是常量number被第二次赋值。

1.3.4 变量的有效范围

由于变量被定义出来后只是暂存在内存中,等到程序执行到某一个点,该变量会被释放掉,也就是说变量有它的生命周期。因此,变量的有效范围是指程序代码能够访问该变量的区域,若超出该区域,则在编译时会出现错误。在程序中,一般会根据变量的“有效范围”将变量分为“成员变量”和“局部变量”。

1.成员变量

在类体中所声明的变量被称为成员变量,成员变量在整个类中都有效。类的成员变量又可分为两种,即静态变量和实例变量。例如下面这段代码:

1
2
3
4
class Demo{
int x=45;
static int y=90;
}

其中,x为实例变量,y为静态变量(也称类变量)。如果在成员变量的类型称为静态变量。静态变量的有效范围可以跨类,甚至可达到整个应用程序之内。对于静态变量,除了能在声明它的类内存区,还能直接以“类名.静态变量”的方式在其他类内使用。

2.局部变量

在类的方法体中声明的变量(方法内部定义,“{”与“}”之间的代码中声明的变量)称为局部变量。局部变量只在当前代码块中有效,也就是只能在“{”与“}”之内使用。

在类的方法中声明的变量,包括方法的参数,都属于局部变量。局部变量只在当前定义的方法内有效,不能用于类的其他方法中。局部变量的生命周期取决于方法,当方法被调用时,Java虚拟机会为方法中的局部变量分配内存空间,当该方法的调用结束后,则会释放方法中的局部变量占用的内存空间,局部变量也将被销毁。

局部变量可与成员变量的名字相同,此时成员变量将被隐藏,即这个成员变量在此方法中暂时失效。

变量的有效范围如图所示

image-20240416212333425

【例1.6】把成员变量“排挤掉”的局部变量

在项目中创建类Vel分别定义名称相同的局部变量与成员变量,当名称相同时成员变量将被隐藏。

1
2
3
4
5
6
7
public class Val{
static int times = 3;
public static void main(String[] args){
int times = 4;
System.out.println("times的值为:"+times);
}
}

运行结果如下

1
times的值为:4

1.4 运算符

运算符是一些特殊的符号,主要用于数学函数、一些类型的赋值语句和逻辑比较方面。Java中提供了丰富的运算符,如赋值运算符、算数运算符、比较运算符等。

1.4.1 赋值运算符

赋值运算符以符号“=”表示,它是一个二元运算符(对两个操作数作处理),其功能是将右方操作数所含的值赋给左方的操作数。例如

1
int a = 100

该表达式是将100赋值给变量a。作坊的操作数必须是一个变量,而右边的操作数则可以是任何表达式,包括变量(如a、number)、常量(如123、‘book’)、有效的表达式(如45*12)。

由于赋值运算符”=”处理时会先取得右方表达式处理后的结果,因此一个表达式中若含有两个以上的”=”运算符,会从最右方的”=”开始处理。

【例1.7】使用赋值运算符同时为两个变量赋值

在项目中创建类Eval,在主方法中定义变量,使用赋值运算符为变量赋值。

1
2
3
4
5
6
7
8
9
public class Eval{
public static void main(String[] args){
int a,b,c;
a = 15;
c=b=a+4;
System.out.println("c的值为:"+c);
System.out.println("b的值为:"+b);
}
}

输入结果为:

1
2
c的值为:19
b的值为:19

说明

在Java中可以把赋值运算符连在一起使用。如:

x=y=z=5;

在这个语句中,变量x、y、z都得到同样的值5。但在实际开发中建议开发者分开赋值,这样可以让代码的层次更清晰。

1.4.2 算术运算符

Java中的算术运算符主要有+(加)、-(减)、*(乘)、/(除)、%(求余),它们都是二元运算符。Java中算术运算符的功能及使用方式,如图示。

image-20240416221427183

其中,”+”和”-“运算符还可以作为数值的正负符号,如+5、-7。

注意

在进行除法运算时,0不能做除数。例如,对于语句”int a = 5/0;”,系统会抛出ArithmeticException异常。

【例1.8】使用算术运算符模拟计算器

创建ArithmeticOperator类,让用户输入两个数字,分别用5种运算符对两个数字进行计算。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import java.util.Scanner;
public class ArithmeticOperator{
public static void main(String[] args){
Scanner sc = new Scanner(Systen.in);
System.out.println("请输入两个数字,用空格隔开(num1 num2):");
double num1 = sc.nextDouble();
double num2 = sc.nextDouble();
System.out.println("num1+num2的和为:"+(num1+num2));
System.out.println("num1-num2的差为:"+(num1-num2));
System.out.println("num1*num2的积为:"+(num1*num2));
System.out.println("num1/num2的商为:"+(num1/num2));
System.out.println("num1%num2的余数为:"+(num1%num2));
sc.close();
}
}

运行结果如下:

1
2
3
4
5
6
7
请输入两个数字:,用空格隔开(num1 num2):
23 15
num1+num2的和为:38.0
num1-num2的差为:8.0
num1*num2的积为:345.0
num1/num2的商为:1.533333333333333334
num1%num2的余数为:8.0

1.4.3 自增和自减运算符

自增、自减运算符是单目运算符,可以放在操作元之前,也可以放在操作元之后。操作元必须是一个整型或浮点型变量。自增、自减运算符的作用是使变量的值增1或减1。放在操作元前面的自增、自减运算符,会先将变量的值加1(减1),然后再使该变量参与表达式的运算。放在操作元后面的自增、自减运算符,会先使变量参与表达式的运算,然后再将该变量加1(减1)。例如:

1
2
++a(--a)       //表示在使用变量a之前,先使a的值加(减)1
a++(a--) //表示在使用变量a之后,使a的值加(减)1

粗略的分析,“++a”与“a++”的作用都相当于a=a+1。假设a=4,则:

1
b = ++a;             //先将a的值加1,然后赋值给b,此时a的值为5,b的值为5

再看另一个语法,同样假设a=4,则:

1
b = a++;             //先将a的值赋值给b,再将a的值变为5,此时a的值为5,b的值为4

1.4.4 比较运算符

比较运算符属于二次运算符,用于程序中的变量之间、变量和自变量之间以及其他类型的信息之间的比较。比较运算符的运算结果是boolean型。当运算符对应的关系成立时,运算结果为true,否则为false。所有比较运算符通常作为判断的依据用在条件语句中。比较运算符共有6个,如图所示:

image-20240417223404273

【1.9】使用不同的比较运算符判断两个整数的关系

在项目中创建类Compare,在主方法中创建整型变量,使用比较运算符对变量进行比较运算,并将运算后的结果输出。

1
2
3
4
5
6
7
8
9
10
11
12
public class Compare{
public static void main(String[] args){
int number1=4;
int number2=5;
System.out.println("number1>number2的返回值为:"+(number1>number2));
System.out.println("number1<number2的返回值为:"+(number1<number2));
System.out.println("number1==number2的返回值为:"+(number1==number2));
System.out.println("number1=number2的返回值为:"+(number1!=number2));
System.out.println("number1>=number2的返回值为:"+(number1>=number2));
System.out.println("number1<=number2的返回值为:"+(number1<=number2));
}
}

运行结果如下:

1
2
3
4
5
6
number1>number2的返回值为:false
number1<number2的返回值为:true
number1==number2的返回值为:false
number1!=number2的返回值为:true
number1>=number2的返回值为:false
number1<=number2的返回值为:true

1.4.5 逻辑运算符
返回类型为布尔型的表达式,如比较运算符,可以被组合在一起构成一个更复杂的表达式。这是通过逻辑运算符来实现的。逻辑运算符包括&(&&)(逻辑与)、||(逻辑或)、!(逻辑非)。逻辑运算符的操作元必须是boolean型数据。在逻辑运算符中,除了“!”是一次运算符,其他都是二次运算符。

运算符 含义 用法 结合方向
&&、& 逻辑与 op1&&op2 从左到右
|| 逻辑或 op1||op2 从左到右
! 逻辑非 !op 从右到左

结果为boolean型的变量或表达式可以通过逻辑运算符组合为逻辑表达式。

用逻辑运算符进行逻辑运算时,结果如下:

表达式1 表达式2 表达式1&&表达式2 表达式 1||表达式2 !表达式1
true true true true false
true false false true false
false false false false true
false true false true true

逻辑运算符”&&”与”&”都表示”逻辑与”,那么它们之间的区别在哪?从上表中可见,当两个表达式都为true时,”逻辑与”的结果才会是true。使用逻辑运算符”&”会判断两个表达式;而逻辑运算符”&&”则是针对boolean类型的类进行判断,当第一个表达式为false时则不去判断第二个表达式,直接输出结果,从而节省计算机判断的次数。通常将这种在逻辑表达式中从左端的表达式可推断出整个表达式的值的情况称为”短路”,而那些始终需要执行逻辑运算符两边的表达式才能推断出整个表达式的值的情况称为”非短路”。”&&”属于”短路”运算符,而”&”属于”非短路”运算符。

【例1.10】使用不同的比较运算符判断两个整数的关系。

在项目中创建类Cal,在主方法中创建3个整数,分别记录男生人数、女生人数和总人数,使用逻辑运算符来判断”男生人数大于女生人数并且总人数大于30人”和”男生人数大于女生人数或者总人数大于30人”这两种情况是否存在。

1
2
3
4
5
6
7
8
9
10
11
public class Cal{
public static void main(String[] args){
int boys = 15;
int girls = 17;
int total = boys+girls;
boolean result1 = ((boys>girls)&&(total>30));
boolean result2 = ((boys>girls)||(total>30));
System.out.println("男生人数大于女生人数并且总人数大于30人:"+result1);
System.out.println("男生人数大于女生人数或者总人数大于30人:"+result2);
}
}

运行结果如下:

1
2
男生人数大于女生人数并且总人数大于30人:false
男生人数大于女生人数或者总人数大于30人:true

1.4.6 位运算符

位运算符除”按位与”或”按位或”运算符外,其他只能用于处理整数的操作数,包括byte、short、char、int和long等数据类型。位运算是完全针对位方面的操作。整型数据在内存中以二进制的形式表示,如int型变量7的二进制表示00000000 00000000 00000000 00000111。

左边最高位是符号位,最高位是0表示正数,若为1则表示负数。负数采用补码表示,如-8的二进制表示为11111111 11111111 11111111 11111000。这样就可以对整型数据进行按位计算。

1.”按位与”运算

“按位与”运算的运算符为”&”,为双目运算符。”按位与”运算的运算法则是:如果两个整型数据a、b对应为都是1,则结果位才是1,否则为0。如果两个操作数的精度不同,则结果的精度与精度高的操作数相同,如图所示。

image-20240421220509545

2.”按位或”运算

“按位或”运算的运算符为”|”,为双目运算符。”按位或”运算的运算法则是:如果两个操作数对应位都是0,则结果位才是0,否则为1。如果两个操作数的精度不同,则结果的精度与精度高的操作数相同,如图所示:

image-20240421220948162

3.”按位取反”运算

“按位取反”运算也称”按位非”运算,运算符”~”,为单目运算符。”按位取反”就是将操作数二进制中的1修改为0,0修改为1,如图所示:

image-20240421221418802

4.”按位异或”运算

“按位异或”运算的运算符是”^”,为双目运算符。”按位异或”运算的运算法则是:当两个操作数的二进制表示相同(同时为0或同时为1)时,结果为0,否则为1。若两个操作数的精度不同,则结果的精度与精度高的操作数相同,如图所示:

image-20240421222139538

5.移位操作

除了上述运算符,还可以对数据按二进制位进行移位操作。Java中的移位运算符有以下3种:

1
2
3
<<:左移
>>:右移
>>>:无符号右移

左移就是将运算符左边的操作数的二进制数据,按照运算符右边操作数指定的位数向左移动,右边移空的部分补0。右移则复杂一些。当使用”>>”符号时,如果最高位是0,右移空的位就填入0;如果最高位是1,右移空的位就填入1,如图所示:

image-20240421223021025

Java还提供了无符号右移”>>>”,无论最高位是0还是1,左移被移空的高位都填入0。

技巧

移位可以实现整数除以或乘以2ⁿ的效果。例如,y<<2与y*4的结果相同;y>>1的结果与y/2的结果相同。总之,一个数左移n位,就是将这个数乘以2ⁿ;一个数右移n位,就是将这个数除以2ⁿ。

1.4.7 三元运算符

三元运算符的使用格式为

1
条件式 ? 值1 :值2

三元运算符的运算规则为:若条件式的值为true,则整个表达式取值1,否则取值2。例如:

1
boolean b = 20 < 45 ? true : false; 

上述程序表达式”20<45”的运算结果返回为真,那么boolean型变量b取值为true。相反,如果表达式的运算结果返回为假,则boolean型变量b取值为false。

三元运算符等价于if…else语句,例如上述代码等价于:

1
2
3
4
5
boolean a;
if(20<45)
a = true;
else
a = false;

1.4.8 运算符优先级

Java中的表达式就是使用运算符连接起来的符合Java规则的式子。运算符的优先级决定了表达式中运算执行的先后顺序。通常,优先级由高到低的顺序依次是:

  • 增量和减量运算

  • 算数运算

  • 比较运算

  • 逻辑运算

  • 赋值运算

    如果两个运算有相同的优先级,那么左边的表达式要比右边的表达式先被处理。表中显示了在Java中众多运算符特定的优先级。

image-20240422232038407

技巧:

在编写程序时尽量使用圆括号来指定运算次序,以免产生错误的运算顺序。

1.5 数据类型转换

类型转换是将一个值从一种类型更改为另一种类型的过程。例如,可以将String类型的数据”457”转换为数值型,也可以将任意类型的数据转换为String类型。

如果从低精度数据类型向高精度数据类型转换,则永远不会溢出,并且总是成功的;而把高精度数据类型向低精度数据类型转换时,则会有信息丢失,有可能失败。

数据类型转换有两种方式,即隐式转换与显示转换。

1.5.1 隐式类型转换

从低级类型向高级类型的转换,系统将自动执行,程序员无须进行任何操作。这种类型的转换称为隐式转换。下列基本数据类型会涉及数据转换,不包括逻辑类型和字符类型。这些类型按精度从低到高排列的顺序为:byte<short<int<long<float<double。

例如,可以将int型变量直接赋值给float型变量,此时int型变量将隐式转换成float型变量。代码如下:

1
2
int x = 50;
float y = x;

隐式转换也要遵循一定的规则,来解决在什么情况下将哪种类型的数据转换成另一种类型的数据。下列规则:

操作数1的数据类型 操作数2的数据类型 转换后的数据类型
byte、short、char int int
byte、short、char、int long long
byte、short、char、int、long float float
byte、short、char、int、long、float double double

【例1.11】使用隐式转换提升数值的精度

在项目中创建类Conver,在主方法中创建不同数值型的变量,实现将各项变量隐式转换。

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Conver{
public static void main(String[] args){
byte mybyte = 127;
int myint = 150;
float myfloat = 452.12f;
char mychar = 10;
double mydouble = 45.46546
System.out.println("byte型与float型数据进行运算结果为:"+(mybyte+myfloat));
System.out.println("byte型与int型数据进行运算结果为:"+(mybyte+myint));
System.out.println("byte型与char型数据进行运算结果为:"+(mybyte+mychar));
System.out.prontln("double型与char型数据进行运算结果为:"+(mydouble+mychar));
}
}

运行结果如下:

1
2
3
4
byte型与float型数据进行运算结果为:579.12
byte型与int型数据进行运算结果为:19050
byte型与char型数据进行运算结果为:12
double型与char型数据进行运算结果为:55.46546

1.5.2 显示类型转换

当把高精度的变量的赋值给低精度的变量时,必须使用显示类型转换运算(又称强制类型转换)。语法如下:

1
(类型名)要转换的值

例如,将高精度数字转换为低精度数字。代码如下:

1
2
3
int a = (int)45.23;
long y =(long)456.6F;
int b = (int)'d';

执行显示类型转换时,可能会导致精度损失。除boolean类型外,其他基本类型都能以显示类型转换的方法实现转换。

误区警示

当把整数赋值给byte、short、int、long型变量时,不可以超出这些变量的取值范围,否则必须进行强制类型转换。例如:

1
byte b = (byte)129;

1.6 代码注释与编码规范

在程序代码中适当地添加注释,可以提高程序的可读性和可维护性。

1.6.1 代码注释

通过在程序代码中添加注释提高程序的可读性。注释中包含了程序的信息,可以帮助程序员更好地阅读和理解程序。在Java源程序文件的任意位置都可以添加注释语句。注释的文字Java编译器不进行编译,所有代码中的注释文字对程序不产生任何影响。Java语言提供三种添加注释的方法,分别为单行注释、多行注释和文档注释。

1.单行注释

“//“为单行注释标记,从符号”//“开始直到换行为止的所有内容均作为注释而被编译器忽略。语法如下:

1
//注释内容

例如,以下代码为声明的int型变量添加注释:

1
int age;               //定义int型变量,用于保存年龄信息

2.多行注释

注释的内容可以换行,代码如下

1
2
3
4
5
/*
注释内容1
注释内容2
...
*/

注意

(1)在多行注释中可嵌套单行注释。例如:

1
2
3
/*
程序名称:Hello world //开发时间:2024-4-25
*/

(2)多行注释中不可以嵌套多行注释,以下代码是错误的:

1
2
3
4
/*
程序名称:Hello world
/*开发时间:2024-4-25;*/
*/

3.文档注释

“/** /“为文档注释标记。符号”/**”与”/“之间的内容均为文档注释内容。当文档注释出现在声明(如类的声明、类的成员变量的声明、类的成员方法的声明等)之前时,会被javadoc文档工具读取作为javadoc文档内容。除注释标记不同外,文档注释的格式与多行注释的格式相同。

说明

程序中,注释要占程序代码总量的20%~50%。

第2章 流程控制

image-20240425223329771

2.1 复合语句

Java语言的复合语句是以整个块区为单位的语句,所以又称块语句。复合语句有开括号”{“开始,闭括号”}”结束。

2.2 条件语句

条件语句可根据不同的条件执行不同的语句。条件语句包括if条件语句与Switch多分支语句。