第二章 JAVA基础语法

1.1 JAVA程序的基本格式

Java程序代码必须放在一个类中,初学者可以简单地把一个类理解为一个Java程序。类使用class关键字定义,在class前面可以有类的修饰符,类的定义格式如下:

修饰符 class 类名{
程序代码;
}

  1. Java程序代码可分为结构定义语句功能执行语句,其中,结构定义语句用于声明一个类或方法,功能执行语句用于实现具体的功能。每条功能执行语句的最后必须用分号(;)结束。如下面的语句:
System.out.println("这是第一个Java程序!");
  1. 需要注意的是,在程序中不要将英文的分号(;)误写成中文的分号(;),如果写成中文的分号,编译器会报告 “illegal character”(非法字符)错误信息。
  2. Java语言是严格区分大小写的。在定义类时,不能将class写成Class,否则编译器会报错。程序中定义一个computer的同时,还可以定义一个Computer,computer和Computer是两个完全不同的符号,在使用时务必注意。
  3. 在编写Java程序时,为了便于阅读,通常会使用一种良好的格式进行排版,但这并不是必需的,我们也可以在两个单词或符号之间插入空格、制表符、换行符等任意的空白字符。
  4. 虽然Java没有严格要求用什么样的格式编排程序代码,但是,出于可读性的考虑,应该让自己编写的程序代码整齐美观、层次清晰。常用的编排方式是一行只写一条语句,符号“{”与语句同行,符号“}”独占一行,示例代码如下:
public class HelloWorld {
	public static void main(String[] args) {
		System.out.println("这是第一个Java程序!");
	}
}
  1. Java程序中一个连续的字符串不能分成两行书写。例如,下面这条语句在编译时将会出错:
System.out.println("这是第一个
	 	Java程序!");

如果为了便于阅读,需要将一个比较长的字符串分两行书写,可以先将字符串分成两个字符串,然后用加号(+)将这两个字符串连起来,在加号(+)处换行。例如,可以将上面的语句可以修改成如下形式:

System.out.println("这是第一个" + 
 	    "Java程序!");

1.2 注释

1.2.1 单行注释

单行注释用于对程序中的某一行代码进行解释,一般用来注释局部变量。单行注释用符号“//”表示,“//”后面为被注释的内容

int c = 10;      // 定义一个整型变量

1.2.2 多行注释

多行注释顾名思义就是注释的内容可以为多行,它以符号“/”开头,以符号“/”结尾。多行注释具体示例如下:

/*  int c = 10; 
int x = 5; */

1.2.3 文档注释

文档注释是以“/**”开头,并在注释内容末尾以“*/”结束。文档注释是对一段代码概括性的解释说明,可以使用javadoc命令将文档注释提取出来生成帮助文档。文档注释具体示例如下:

/**
  name = “程序员”;
 */

1.3 标识符

标识符是Java对各种变量、方法和类等要素命名时使用的字符序列。凡是需要命名的类名、接口名、变量名、方法名、包名等统称标识符。

1.3.1 标识符的命名规则

1.每个标识符只能包含数字、字母、下划线和美元符号。
2.不能以数字开头。
3.不能使用关键字和保留字作为标识符。
4.标识符不能包含空格。
5.严格区分大小写。

示例:

//合法标识符
username
username123
user_name
userName
$username

// 非法标识符
123username
class
98.3
Hello World

1.3.2 命名规范

标识符规范示例
类名多个单词组成,每个单词的首字母大写、其他字母小写VariableDemo
接口名多个单词组成,每个单词的首字母大写、其他字母小写Comparator
变量名由多个单词组成,第一个单词的字母全部小写,从第二个单词开始,每个单词的首字母大写、其他字母小写。myCode
方法名由多个单词组成,第一个单词的字母全部小写,从第二个单词开始,每个单词的首字母大写、其他字母小写。getMax
包名由多个单词组成时,所有字母小写,多层包结构中间用小圆点"."隔开。并且采用域名倒置的命名法。com.study.demo
常量名所有字母大写,由多个单词组成时每个单词用下划线连接MAX_VALUE

注意:
1.在起名字时,为了提高阅读性,要尽量"见名知意"。
2.Java采用Unicode字符集,因此标识符也可以使用汉字声明,但是不建议使用。

1.4 关键字和保留字

关键字是被Java语言赋予特殊含义,具有特殊用途的字符串(单词),关键字有一个特点是所有字母都是为小写形式。

类别关键字说明
访问控制private私有的
protected受保护的
public公共的
default默认
类、方法和变量修饰符abstract声明抽象
class
extends扩充,继承
final最终的,不可改变的
implements实现(接口)
interface接口
native本地,原生方法
new创建
static静态
strictfp严格,精准
synchronized线程,同步
transient短暂
volatile易失
程序控制语句break跳出循环
case定义一个值以供switch选择
continue继续
default默认
do运行
else否则
for循环
if如果
instanceof实例
return返回
switch根据值选择执行
while循环
错误处理assert断言表达式是否为真
catch捕获异常
finally有没有异常都会执行
throw抛出一个异常对象
throws声明一个异常可能被抛出
try捕获异常
包相关import引入
package
基本类型boolean布尔型
byte字节型
char字符型
double双精度浮点
float单精度浮点
int整型
long长整型
short短整型
变量引用super父类,超类
this本类
void无返回值
保留关键字goto是关键字,但不能使用
const是关键字,但不能使用

编写Java程序时,需要注意以下几点:
(1)所有的关键字都是小写的。
(2)不能使用关键字命名标识符。
(3)const和goto是保留字关键字,虽然在Java中还没有任何意义,但在程序中不能用来作为自定义的标识符。
(4)true、false和null虽然不属于关键字,但它们具有特殊的意义,也不能作为标识符使用。

1.5 常量

常量就是在程序中固定不变的值,是不能改变的数据。例如,数字1、字符’a’、浮点数3.2等都是常量。在Java中,常量包括整型常量、浮点数常量、布尔常量、字符常量等。

1.5.1 整型常量

整型常量是整数类型的数据,有二进制、八进制、十进制和十六进制4种表示形式。

  • 二进制:由数字0和1组成的数字序列。从JDK7开始,允许使用字面值表示二进制数,前面要以0b或0B开头,目的是为了和十进制进行区分,如0b01101100、0B10110101。
  • 八进制:以0开头并且其后由0~7范围内(包括0和7)的整数组成的数字序列,如0342。
  • 十进制:由数字0~9范围内(包括0和9)的整数组成的数字序列,如198。
  • 十六进制:以0x或者0X开头并且其后由09、AF(包括0和9、A和F,字母不区分大小写)组成的数字序列,如0x25AF。

1.5.2 浮点数常量

浮点数常量就是在数学中用到的小数,浮点数分为单精度浮点数(float)和双精度浮点数(double)两种类型。其中,单精度浮点数后面以F或f结尾,而双精度浮点数则以D或d结尾。当然,在使用浮点数时也可以在结尾处不加任何的后缀,此时JVM会默认浮点数为double类型的浮点数。浮点数常量还可以通过指数形式表示。

1.5.3 字符常量

字符常量用于表示一个字符,一个字符常量要用一对英文半角格式的单引号(‘’)括起来。字符常量可以是英文字母、数字、标点符号、以及由转义序列表示的特殊字符。

'a'  
'1'  
'&'  
'\r' 
'\u0000' 

1.5.4 字符串常量

字符串常量用于表示一串连续的字符,一个字符串常量要用一对英文半角格式的双引号(“”)括起来。

"HelloWorld"   
"123"   
"Welcome \n XXX" 
""

1.5.5 布尔常量

布尔常量即布尔型的值,用于区分事物的真与假。布尔常量有true和false两个值。

1.5.6 null常量

null常量只有一个值null,表示对象的引用为空。

1.6 变量

在程序运行期间,随时可能产生一些临时数据,应用程序会将这些数据保存在内存单元中,每个内存单元都用一个标识符标识,这些用于标识内存单元的标识符就称为变量,内存单元中存储的数据就是变量的值。

1.6.1 变量的定义

Java中的变量包含三个要素,分别是数据类型,变量名和变量值。数据类型决定了这个变量中要存储的数据值的数据类型及这块内存的宽度。变量名就是一个标识符,方便在程序中使用。变量值就是这个变量具体的值。例如:

int age = 18;

1.6.2 变量的声明与使用

变量的使用步骤可以具体分为声明、赋值、使用三步:
1.声明
变量的声明相当于向JVM申请一部分指定数值类型的大小的内存。不同的数据类型需要占用的内存大小是不同的。JVM中每字节的内存都有自己的编号,称为内存地址,但是在程序中直接使用内存地址是极其不方便的。因此需要给这部分内存命名,方便在程序中对这部分内存进行访问和使用。

2-1变量声明.jpg

声明变量的语法:

数据类型 变量名;

示例:

int age;
double weight;

2.赋值

将符号"="右边的值放到对应的内存中。
变量赋值的语法格式:

变量名 = 值;

示例:

age = 19;
weight = 102.5;

声明和赋值这两步可以合二为一,语法如下:

数据类型 变量名  = 值;

示例:

int age = 19;
double weight = 102.5;

3.使用
在变量的作用域内将变量中的值拿出来进行打印、运算、比较等。示例:

public class VarDemoTest{
	public static void main(String[] args){
        int age = 19;
        double weight = 102.5;
        
        System.out.println("age = " + age);
        System.out.println("weight = " + weight);
	}
}

1.6.2 变量的注意事项

1.必须先声明再使用
2.变量必须在初始化后才能使用
3.变量有作用域,并且在同一个作用域中不可以重复命名
4.变量的值可以变化,但必须在变量声明的数据类型范围内

1.7 数据类型

Java是一门强类型语言,根据存储元素的需求不同,将数据类型划分为基本数据类型和引用数据类型,如图:

2-2数据类型分类.jpg

1.7.1 整型

整数类型变量用来存储整数数值,即没有小数部分的值。在Java中,为了给不同大小范围内的整数合理地分配存储空间,整数类型分为4种不同的类型,分别是字节型(byte)、短整型(short)、整型(int)和长整型(long)。如表所示:

类型宽度表示范围
byte8位(1字节)-128~127
short16位(2字节)-215~215-1
int32位(4字节)-231~231-1
long64位(8字节)-263~263-1

int是最常用的整型之一,系统通常将一个整型值默认当作int处理。需要注意一下三种情况:

(1)如果将一个整型字面量赋值给byte或short,编译器会先判断这个整型字面量值是否在指定类型的表数范围内,如果在则赋值成功;如果不在则编辑报错。

示例:

public class TestInteger1{
    public static void main(String[] args){
        // 100属于byte类型的表数范围,故赋值成功
        byte b1 = 100; //编译通过
        
        // 10000
        byte b2 = 10000; //编译不通过
        
    }
}

(2)如果将一个巨大的整型常量赋值给long类型,那么需要以小写l或者大写L作为后缀。因为小写l很容易和1搞混,所以推荐使用L。示例:

public class TestInteger3{
    public static void main(String[] args){
        long num1 = 9999999999999L; // 需要在常量值后面添加l或者L后缀
    }
}

byte和short的实际存储和运算都是当作int类型处理的,通过分析字节码可以发现,使用byte和short类型声明变量,实际分配都是4字节空间。系统划分出byte和short,主要是逻辑意义上的划分,编译时检查数值的范围。后续可以根据具体的应用场景选择适当的数据类型,在默认情况下,习惯使用int类型来定义整型。

1.7.2 浮点型

浮点数类型变量用于存储小数数值。double类型所表示的浮点数比float类型更精确,两种浮点数所占存储空间的大小以及取值范围。根据存储因素的精确度不同,浮点型划分为如下两种类型,如表所示:

类型占用存储空间表示范围
单精度(float)32位(4字节)-3.403E38~3.403E38
双精度(double)64位(8字节)-1.798E308~1.798E308
  • float型:单精度,尾数可以精确到7位有效数字。很多情况下,单精度很难满足需求。
  • 双精度double:双精度,精度是float型的两倍,开发中通常用double类型来表示效数。

Java的浮点型常量默认位double型。若使用float型,则须加f或F后缀;若使用double型,则后缀d或D可加可不加。通常情况下使用double型,因为它比float型更精确。

public class TestFloat{
    public static void main(String[] args){
        // 系统自动将1.5当作double处理,故赋值成功
        double d = 1.5;
        
        // 系统自动将1.5当作double处理,而目标类型为float,故赋值失败
        float f1 = 1.5;
    }
}

如果要将1.5当作float处理,需要在常量值后添加f或F后缀。

float f2 = 1.5f;

1.7.3 字符型

在Java中,字符类型变量用char表示,用于存储一个单一字符。Java中每个char类型的字符变量都会占用2个字节。在给char类型的变量赋值时,需要用一对英文半角格式的单引号(’ ‘)把字符括起来,如’a’。字符型底层依然是以整型(相当于无符号整型)存储的,因此需要借助一个字符编码集,将每个字符一一对应成一个整数。Java使用的是Unicode字符集,Unicode字符集支持全世界所有书面语言的字符,它是固定长度编码方式,兼容ASCII字符集。

类型占用存储空间字符集
字符型(char)2字节Unicode

字符串常量值的表示形式有如下几种:

  • 用单引号括起来的单个字符的常量值,不能是空的如:‘’,必须有单个字符。这种表示形式最常见。
  • 转义字符’\n’ '\t’等。
  • 直接使用Unicode值,格式是’\uxxxx’, 其中’xxxx’表示一个16进制的整数。
  • 直接使用十进制整型常量值,如100、98等。

示例:

public class TestCharacter{
    public static void main(String[] args){
        char c1 = 'a';
        char c2 = '\"';
        char c3 = '\u0043';
        char c4 = 100;
        
        System.out.println("c1:" + c1);
        System.out.println("c2:" + c2);
        System.out.println("c3:" + c3);
        System.out.println("c4:" + c4);
    }
}

常见转义字符,如表所示:

转义字符说明
\b退格符
\n换行符
\r回车符
\t制表符
"双引号
单引号
\\反斜线

1.7.4 布尔型

在Java中,使用boolean定义布尔类型变量,布尔类型变量只有true和false两个值。定义布尔类型变量,具体示例如下:

boolean flag = false;	 // 定义一个boolean类型的变量flag,初始值为false
flag = true; 		 // 改变变量flag的值为true

Java中使用布尔型控制的语句主要有以下几种:

  • if条件。
  • while循环。
  • do-while循环。
  • for循环。
  • 三元运算符的条件。

布尔型的注意事项:

  1. 布尔型数据只允许取值true和false,无null。
  2. 不可以使用0或非0的整数替代false和true,这点和C语言不同。

1.7.5 使用变量

示例:

public class MyInfoDemo{
    public static void main(String[] args){
        String name = "lily";
        String school = "college";
        int age = 18;
        char gender = '女';
        int height = 168;
        double weight = 152.5;
        boolean marry = false;
        
        System.out.println("姓名:" + name);
        System.out.println("学校:" + school);
        System.out.println("年龄:" + age);
        System.out.println("性别:" + gender);
        System.out.println("身高:" + height);
        System.out.println("体重:" + weight);
        System.out.println("婚否:" + marry);
    }
}

1.7.6 数据类型的转换

根据开发需求,不同数据类型的值经常需要进行互相转换,Java只支持布尔型之外的七大基本数据类型间的转换,它们之间的转换类型分为自动类型转换和强制类型转换。

1.7.6.1 自动类型转换

自动类型转换也叫隐式类型转换,指的是两种数据类型在转换的过程中不需要显式地进行声明,由编译器自动完成。自动类型转换必须同时满足两个条件,第一是两种数据类型彼此兼容,第二是目标类型的取值范围大于源类型的取值范围。基本数据类型的自动转换关系如图所示,左边类型的值可以自动转换成右边类型,反之则不可以。

2-3基本数据类型自动转换关系.jpg
下面列出3种可以进行自动类型转换的情况,具体如下:

  1. 整数类型之间可以实现转换。例如,byte类型的数据可以赋值给short、int、long类型的变量;short、char类型的数据可以赋值给int、long类型的变量;int类型的数据可以赋值给long类型的变量。
  2. 整数类型转换为float类型。例如,byte、char、short、int类型的数据可以赋值给float类型的变量。
  3. 其他类型转换为double类型。例如,byte、char、short、int、long、float类型的数据可以赋值给double类型的变量。
byte b = 3;
int x = b;  

上面的代码中,使用byte类型的变量b为int类型的变量x赋值,由于int类型的取值范围大于byte类型的取值范围,编译器在赋值过程中不会造成数据丢失,所以编译器能够自动完成这种转换,在编译时不报告任何错误。

注意事项:
1. 当多种类型的数据进行混合运算时,系统首先自动将所有数据转换成容量最大的数据类型,再进行计算。
2. byte、short、char之间不会相互转换,它们在计算时首先会转换为int类型。
3. 布尔类型不能与其他数据类型进行运算。
4. 当把任何基本数据类型的值和字符串(String)进行"+“运算时,此时的”+"不再是加法的意思,而是表示连接运算。此时,运算的结果是String型。

1.7.6.2 强制类型转换

强制类型转换也叫显式类型转换,指的是两种数据类型之间的转换需要进行显式地声明。当两种类型彼此不兼容,或者目标类型取值范围小于源类型时,自动类型转换无法进行,这时就需要进行强制类型转换。
示例如下:

int a = 200;
byte b = a; // 编译报错

长度大的数据类型转为长度小的数据类型是会削去一部分,从而造成数据丢失,所以Java语言规范将强制类型转换成为Narrow Conversion。强制类型转换的语法格式如下所示:

目标类型  变量 = (目标类型)值

示例代码:

public class TestConversion{
	public static void main(String[] args){
		int num = 98;
		short s = (short) num;
		System.out.println(s);
		
		double d = 9.95;
		int i = (int) d;
		System.out.println(i);
			
	}
}

具体规则:

  1. 如果目标类型和原类型都为整型,如将32位int类型强转为8位byte类型,则需要截断前面的24位,只保留8位。
  2. 目标类型是整型,原类型是浮点型,将直接截断浮点型的小数部位,这会造成精度损失。例如:
int iValue = (int) 12.5;
// 强转后得到的iValue的值是12

练习题:

public class ConversionDemo1{
    public static void main(String[] args){
        char c = 'a';
        int i = 5;
        float d = .314F;
        
        int result = c + i + d;
    }
}

类型提升规则的一般情况下,表达式结果的类型为操作数类型最大的。c+i+d结果的类型为float,转为int类型未使用强制类型转换,编译时会报错。

数据类型转换的相关内容可以总结为如下几点:

  1. 表达式类型自动提升的一般原则:表达式结果的类型为操作数中最大的类型。
  2. byte类型和short类型进行运算时,系统自动当作int类型处理。
  3. char变量可以直接保存为int常量值,但不能直接保存为int变量值,char类型进行运算时,系统自动当作int类型处理。
  4. 自动类型转换的逆工程是将容量大的数据类型转换为容量小的数据类型。使用时要加上强制转换符号,但可能造成精度降低或溢出,需要格外注意。
  5. 强制转换符号为小括号,优先级非常高,故强制转换表达式结果的类型时,需要将表达式用小括号包起来,提升优先级。
  6. 布尔类型不可以转换为其他的数据类型。

表达式类型的自动提升:
所谓表达式是指由变量和运算符组成的一个算式。变量在表达式中进行运算时,可能发生自动类型转换,这就是表达式数据类型的自动提升。例如,一个byte型的变量在运算期间类型会自动提升为int型。

1.7.7 变量的作用域

变量需要先定义后使用,但这并不意味着定义的变量,在之后所有语句中都可以使用。变量需要在它的作用范围内才可以被使用,这个作用范围称为变量的作用域。在程序中,变量一定会被定义在某一对大括号中,该大括号所包含的代码区域便是这个变量的作用域。
image.png
图中的代码有两层大括号。其中,外层大括号所标识的代码区域就是变量x的作用域,内层大括号所标识的代码区域就是变量y的作用域。
示例:

public class Example04 {
    public static void main(String[] args) {
        int x = 12;      		// 定义了变量x
        {
            int y = 96; 	// 定义了变量y
            System.out.println("x is " + x); 	// 访问变量x
            System.out.println("y is " + y); 	// 访问变量y
        }
        y = x;          	// 访问变量x,为变量y赋值
        System.out.println("x is " + x);    // 访问变量x
    }
}

编译上述代码,程序报错,原因:变量y在作用域范围之外被使用(y=x;)。

1.8 运算符和标点符号

在程序中经常出现一些特殊符号,如+、-、*、=、>等,这些特殊符号称作运算符。运算符用于对数据进行算术运算、赋值运算和比较运算等。在Java中,运算符可分为算术运算符、赋值运算符、比较运算符、逻辑运算符等共有38个运算符,按照功能不同可以分为如下几种:

  • 算术运算符
  • 赋值运算符
  • 比较运算符
  • 逻辑运算符
  • 位运算符
  • 条件运算符
  • lambda操作符

按照需要的操作数个数运算符可以分为如下几种:

  • 一元运算符(单目运算符):在Java语言中只有4个一元运算符,分别是"++“,”–“,‘’!”,“~”。
  • 二元运算符(双目运算符):除了一元和三元运算符,剩下的都是二元运算符。
  • 三元运算符(三目运算符):在Java语言中只有1个三元运算符即"?:"。、

1.8.1 算数运算符

在数学运算中最常见的就是加减乘除,被称作四则运算。Java中的算术运算符就是用来处理四则运算的符号,算术运算符是最简单、最常用的运算符号。其中正号、负号、自增、自减是一元运算符,其余是二元运算符。

运算符运算示例结果
+正号a=+3;b=+aa=3;b=3;
-负号a=-4;b=-aa=-4;b=4;
+5+510
-6-42
*3*412
/7/51
%取模(取余)7%52
++自增(前):先自增后取值a=2;b=++a;a=3;b=3;
++自增(后):先取值后自增a=2;b=a++;a=3;b=2;
自减(前):先自减后取值a=2;b=–a;a=1;b=1
自减(后):先取值后自减a=2;b=a–;a=1;b=2;
+字符串连接“He” + “llo” +1+2+3“Hello123”

1.加法运算符
两个浮点型常量相加,结果为浮点型。

两整型常量值相加,结果为整型。

int a = 3;
int b = 5;
System.out.println(a + b); //结果为:8

2.减法运算符

double a = 11.5;
double b = a - 10; //结果:1.5

3.乘法运算符

double a = 11.5;
double b = a * 10; //结果为:115.0

4.除法运算符

double a = 10 / 3; //a的值为3.0

除法运算符有些特殊,被除数、除数若都是整型,则结果就为整型,其结果以截断方式取整;如果给变量赋值时,系统自动将int类型转换为double类型;若被除数或除数是浮点型,则结果就是浮点型。

System.out.println(10/3); //结果:3, 直接算结果为整型
System.out.println(-10.5/3); //结果:-3.5
System.out.println(8.53/1.7); //结果:5.017647058823529

如果除数是0,被除数是整数,则汇报ArithmericException异常;如果除数是0且被除数是浮点型或除数是0.0时,则不会报异常,得到的结果是Infinity。

5.取模运算符
取模运算类似于数学中的求余数。经常用%来判断能否被除尽的情况。

double a = 10 % 3; //a的值为:1.0
// 10 % 3的结果为int类型1,赋值时,系统自动将数据类型转换为double类型。
System.out.println(10 % 3); //结果:1
System.out.println(-10.5 % 3); //结果:-1.5
System.out.println(8.53 % 1.7); //结果:0.029999...

6.自增运算

自增运算可以实现变量值自加1运算。自增运算符是单目运算符,运算符可以出现在操作数的左边,如i,也可以出现在操作数的右边,如i。自增运算符即可以当作独立语句使用,又可以作为复杂表达式的一部分使用。自增1不会改变本身变量的数据类型。
a)、当自增运算作为独立语句使用时,自增运算符++在前或在后没区别。
b)、当自增运算作为表达式一部分使用时,自增运算符++在前或在后是有区别的。

  • 操作数在左边:先自增1,再取变量的值做其他运算,即参与运算的是自增之后的值。
  • 操作数在右边:先取变量的值放到操作数栈中,随后自增变量增1,然后计算是用自增之前取的值进行运算。

7.自减运算符
自减运算符可以实现自减变量值自减1运算。自减运算符的使用方法同自增运算符,仅是把增换成了减。

8.字符串连接
String字符串可以和八种基本数据类型变量做运算,切运算只能是连接运算"+",运算结果仍然是String类型。

1.8.2 赋值运算符

赋值运算符的功能是为变量赋值。最基本的赋值运算符是"="。赋值运算符的运算顺序是从右往左,即把等号右边的值赋给等号左边的变量。赋值运算符也是二元运算符。

需要指出的是复合赋值运算符。复合赋值运算符由赋值运算符与算术运算符或位运算符组合而成,如:+=、-=、*=、/=、%=、&=、|=、^=、<<=、>>=、>>>=等都是复合赋值运算符。

运算符运算范例结果
=赋值a=3;b=2;a=3;b=2;
+=加等于a=3;b=2;a+=b;a=5;b=2;
-=减等于a=3;b=2;a-=b;a=1;b=2;
*=乘等于a=3;b=2;a*=b;a=6;b=2;
/=除等于a=3;b=2;a/=b;a=1;b=2;
%=模等于a=3;b=2;a%=b;a=1;b=2;

总结:

  1. 赋值符号包含基本赋值运算符"=“和复合赋值运算符”+="等。
  2. 赋值操作一定是最后进行运算的。
  3. "="右边的形式可以实常量值、变量、表达式。
  4. "="左边只能是变量。
  5. 使用复合赋值运算符时,当结果超过左边变量的类型时,会自动进行类型转换,所以要考虑结果溢出等风险。

强制类型转换
在为变量赋值时,当两种类型彼此不兼容,或者目标类型取值范围小于源类型时,需要进行强制类型转换。例如,将一个int类型的值赋给一个short类型的变量,需要进行强制类型转换。然而在使用+=、-=、*=、/=、%= 运算符进行赋值时,强制类型转换会自动完成,程序不需要做任何显式地声明。

1.8.3 比较运算符

比较运算符属于二元运算符,用以进行关系比较,比较运算符的运算结果类型为布尔型,往往用于if结构、循环结构条件中,比较运算符的运算顺序是从左往右的。

运算符运算范例(a=4,b=3)结果
==等于a==bfalse
!=不等于a!=btrue
<小于a<bfalse
>大于a>btrue
<=小于等于a<=bfalse
>=大于等于a>=btrue

注意:"=="既可用于判断两个基本数据类型变量又可以用于判断两个引用类型变量。在判断时要求两个操作数的类型一致或兼容,兼容是指可以通过自动类型提升实现的类型,否则编译报错!

  • 如果两个操作数为基本数据类型,则"=="判断的是值是否相等。
  • 如果两个操作数为引用类型,则"=="判断的是两个引用是否指向同一个对象实体或数组实体。

示例:

int a = 3;
int b = 1;
System.out.println(a == b);
System.out.println(a > b);
System.out.println(a % 2 == 0);

1.8.4 逻辑运算符

Java的逻辑运算符用于表示两个或更多个条件之间的关系。逻辑运算符的操作数都是布尔型的值或者表达式,逻辑运算符的表达式往往用于if结构、循环结构条件中。逻辑运算顺序是从左往右的。逻辑运算符除逻辑非,其余都是二元运算符。

运算符格式结果说明
&&a&&btrue && true 结果 true短路与,如果a为false,则b不会再进行判断
true && false 结果 false
false && true 结果 false
false && false 结果 false
&a & btrue & true 结果 true逻辑与,当a和b都为true时,结果为true,不管a是否为false都会继续判断b
true & false 结果 false
false & true 结果 false
false & false 结果 false
||a || btrue || true 结果 true短路或,如果a为true,则b不会再进行判断
true || false 结果 true
false || true 结果 true
false || false 结果 false
|a | btrue | true 结果 true逻辑或,不管a是否为true,都会判断b
true | false 结果 true
false | true 结果 true
false | false 结果 false
^a ^ btrue ^ true 结果 false逻辑异或,当a和b相同时,结果为false;当a和b不同时,结果为true
true ^ false 结果 true
false ^ true 结果 true
false ^ false 结果 false
!!a!true 结果false逻辑非,如果a为true,结果为false,反之结果为true
!false 结果 true

&和&&、||和|的区别:

  • &&:短路与,如果左边为false,则右边不参与运算,效率较高;
  • &:逻辑与,不管左边是否为false,右边都要参加与运算,效率较低;
  • ||:短路与,如果左边为true,则右边不参与运算,效率较高;
  • |:逻辑与,不管左边是否为true,右边都要参与运算,效率较低。

示例:

public class TestLogicalOperation{
    public static void main(String[] args){
        int i = 100;
        int j = 9;
        System.out.println(++i +i);
        System.out.println(++i > 100 && j-- < 9);
        System.out.println(i + "\t" + j);
        System.out.println(i++ > 100 || j-- < 9);
        System.out.println(i + "\t" + j);
    }
}

示例:

public class Example06 {
2	public static void main(String[] args) {
3		int x = 0; 			// 定义变量x,初始值为0
4		int y = 0; 			// 定义变量y,初始值为0
5		int z = 0; 			// 定义变量z,初始值为0
6		boolean a, b; 			// 定义boolean变量a和b
7		a = x > 0 & y++ > 1; 		// 逻辑运算符&对表达式进行运算
8		System.out.println(a);
9		System.out.println("y = " + y);
10		b = x > 0 && z++ > 1; 		// 逻辑运算符&&对表达式进行运算
11		System.out.println(b);
12		System.out.println("z = " + z);
13	}
14 }

上述代码中,第3~5行代码定义了三个整型变量x、y、z,初始值都为0;第6行代码定义了两个布尔类型的变量a和b。第7行代码使用“&”运算符对两个表达式进行逻辑运算,左边表达式x>0的结果为false,这时无论右边表达式y++>1的比较结果是什么,整个表达式x > 0 & y++ > 1的结果都会是false。由于使用的是运算符“&”,运算符两边的表达式都会进行运算,因此变量y会进行自增,整个表达式运算结束之后,y的值为1。
第10行代码是逻辑“&&”运算,运算结果和第7行代码一样为false,区别在于,第10行代码使用了短路与“&&”运算符,当左边为false时,右边的表达式不进行运算,因此变量z的值仍为0。

使用逻辑运算符需要注意的问题总结:
(1)逻辑运算符可以针对结果为布尔值的表达式进行运算。例如,x > 3 && y != 0。
(2)运算符“&”和“&&”都表示与操作,当且仅当运算符两边的操作数都为true时,其结果才为true,否则结果为false。虽然运算符“&”和“&&”都表示与操作,但两者在使用上还有一定的区别。在使用“&”进行运算时,不论左边为true或者false,右边的表达式都会进行运算。在使用“&&”进行运算,当左边为false时,右边的表达式就不再进行运算,因此“&&”被称作短路与。

1.8.5 位运算符

位运算时指按照二进制的规则进行相关运算的运算符,共有七个运算符。

1.8.6 条件运算符

条件运算是唯一的三元运算符,可以实现简单的条件判断。条件运算符的运算顺序是从左到右的。条件运算符的格式如下:

(条件表达式) ? 表达式1:表达式2;

当使用条件运算符时,要求表达式1和表达式2是同种类型或可以按自动类型提升为统一类型的,否则编译报错。

示例:

int a = 3;
double b = 2.0;
System.out.println(a>b?a:b); //输出结果:3.0

练习:使用条件运算符求出三个数中的最大值

public class TestMax{
    public static void main(String[] args){
        int a = 12;
        int b = 30;
        int c = -43;
        
        int max = (a > b) ? a : b;
        max = (max > c) ? max : c;
        System.out.println("三个数中的最大值为:" + max);
    }
}

1.8.7 运算符的优先级

在对一些比较复杂的表达式进行运算时,要明确表达式中所有运算符参与运算的先后顺序,通常把这种顺序称作运算符的优先级。

优先级运算符
1. [] ()
2++ – ~ ! (数据类型)
3* / %
4+ -
5<< >> >>>
6< > <= >=
7== !=
8&
9^
10|
11&&
12||
13?:
14= *= /= %= += -= <<= >>= >>>= &= ^= |=

单目运算排第一;
乘除余二加减三;
移位四,关系五;
等和不等排第六;
位与、异或和位或;
依次从七到十一;
条件排在第十二;
赋值一定是最后;
小括号的优先算。

1.8.8 标点符号

  • 小括号用于强制类型转换、表示优先运算表达式、方法参数列表。
  • 大括号用于数组元素列表、类体、方法体、复合语句代码块边界符。
  • 中括号用于数组。
  • 分号用于结束语句。
  • 逗号用于多个赋值表达式的分隔符和方法参数列表分隔符。
  • 英文句号用于成员访问和包目录结构分隔符。
  • 应为省略号用于可变参数。
  • "@"用于注解。
  • 双冒号用于方法引用。
  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值