Java—基础语法

一、计算机基础知识

1.1 二进制

计算机中的数据不同于人们生活中的数据,人们生活采用十进制数,而计算机中全部采用二进制数表示,它只包含 0、1两个数,逢二进一,1+1=10。每一个0或者每一个1,叫做一个bit(比特)。

1.2 字节

字节是计算机中小存储单元。计算机存储任何的数据,都是以字节的形式存储。

8个bit(二进制位) 0000-0000表示为1个字节,写成1 byte或者1 B

  • 8 bit = 1 B
  • 1024 B = 1KB
  • 1024 KB = 1MB
  • 1024 MB = 1GB
  • 1024 GB = 1TB

1.3 内存

内存是计算机中的重要原件,临时存储区域,作用是运行程序。我们编写的程序是存放在硬盘中的,在硬盘中的程序是不会运行的,必须放进内存中才能运行,运行完毕后会清空内存。Java虚拟机要运行程序,必须要对内存进行空间的分配和管理。

二、Java开发环境

2.1 Java虚拟机(JVM)、JRE、JDK

  • JVM(Java Virtual Machine):是运行所有Java程序的假想计算机,是Java程序的 运行环境。我们编写的Java代码,都运行在 JVM 之上。
  • JRE(Java Runtime Environment):Java程序运行时环境,包括JVM和运行时所需要的核心类库
  • JDK(Java Development Kit):Java程序开发工具包,包括JRE和开发人员使用的工具。

三者关系:JDK > JRE > JVM
在这里插入图片描述
在这里插入图片描述

2.2 环境变量的配置

开发Java程序,需要使用JDK中提供的工具,工具在JDK安装目录的 bin 目录下。

为了开发方便,我们想在任意的目录下都可以使用JDK的开发工具,则必须要配置环境变量,配置环境变量的意义 在于告诉操作系统,我们使用的JDK开发工具在哪个目录下。

环境变量:
变量名:JAVA_HOME 变量值:JDK安装路径
变量名:Path 变量值:%JAVA_HOME%\bin

2.3 JVM的内存划分

为了提高运算效率,就对空间进行了不同区域的划分,因为每一片区域都有特定的处理数据方式和内存管理方式。

区域名称作用
寄存器
(PC Register)
给CPU使用,和我们开发无关
本地方法栈
(Native Method Stack)
JVM在使用操作系统功能的时候使用,和我们开发无关
方法区
(Method Area)
存储.class相关信息,包括方法的信息

(Stack)
存放的都是方法中的局部变量,方法的运行一定要在栈中运行,比如main方法运行,进入栈中执行
局部变量:方法的参数,或者是方法{}内部的变量
作用域:一旦超出作用域,立刻从栈内存中消失

(Heap)
存储对象或者数组,凡是new出来的东西都在堆中
堆内存里面的东西都有一个地址值:16进制
堆内存里面的数据都有默认值,规则:
整数   默认为0
浮点数  默认为0.0
字符  默认为’\u0000’
布尔  默认为false
引用类型  默认为null

三、入门说明

  • 编译Java源文件class文件

javac 命令进行编译(javac Java源文件名.后缀名)

  • 运行:class文件交给JVM运行。

java 命令进行运行(java 类名字(后缀是.class,但不要写))

  • main方法:称为主方法,固定格式,程序的入口或起点,JVM在运行的时候都会从main方法开始执行。
// 第一行的第三个单词必须和所在的文件名称完全一样,大小写也要一样
// public class后面代表定义一个类的名称,类是Java当中所有源代码的基本组织单位。
public class HelloWorld {
	// 第二行的内容是万年不变的固定写法,代表main方法
	// 这一行代表程序执行的起点
	public static void main(String[] args) {
		// 第三行代表打印输出语句(其实就是屏幕显示)
		// 希望显示什么东西,就在小括号当中填写什么内容
		System.out.println("Hello, World!!!");
	}
}
  • 关键字:是指在程序中,Java已经定义好的单词,具有特殊含义。 eg:publicclassstaticvoid等(全部都是小写字母)。

  • 标识符:在程序中,我们自己定义内容。比如类的名字、方法的名字和变量的名字等等,都是标识符。

命名规则

  1. 可以包含 英文字母26个(区分大小写) 、 0-9数字 、 $(美元符号) 和 _(下划线)
  2. 不能以数字开头
  3. 不能是关键字

命名规范

  1. 类名规范:首字母大写,后面每个单词首字母大写(大驼峰式)。
  2. 方法名规范: 首字母小写,后面每个单词首字母大写(小驼峰式)。
  3. 变量名规范:全部小写

四、常量

4.1 概述

常量:在Java程序中固定不变的数据。

4.2 常量分类

类型含义举例
整数常量所有的整数0,1, 567, -9
小数常量所有的小数0.0, -0.1, 2.55
字符常量单引号引起来,只能写一个字符,必须有内容‘a’ , ’ ', ‘好’
字符串常量双引号引起来,可以写多个字符,也可以不写“A” ,“Hello” ,“你好” ,""
布尔变量只有两个值(流程控制中讲解)true , false
空变量只有一个值null

五、变量和数据类型

5.1 变量概述

变量:在程序中可以变化的量称为变量。

5.2 数据类型

5.2.1 数据类型分类
  • 基本数据类型:整数浮点数字符布尔
  • 引用数据类型:字符串数组接口

注意

  1. 字符串不是基本类型,而是引用类型。
  2. 浮点型可能只是一个近似值,并非精确的值。
  3. 数据范围与字节数不一定相关,例如float数据范围比long更加广泛,但是float是4字节,long是8字节。
5.2.2 基本数据类型
数据类型关键字内存占用取值范围
字节型byte1个字节-128~127
短整型short2个字节-32768~32767
整形int(默认)4个字节-231 ~231-1
长整形long8个字节-263~263-1
单精度浮点数float4个字节1.4013E-45~3.4028E+38
双精度浮点数double(默认)8个字节4.9E-324~1.7977E+308
字符型char2个字节0~65535
布尔类型boolean1个字节true、false

Java中的默认类型:整数类型是 int 、浮点类型是 double 。

5.3 变量的定义

格式

  1. 创建一个变量并且使用的格式:
数据类型 变量名称;  //创建了一个变量
变量名称 = 数据值;  //赋值,将右边的数据值,赋值交给左边的变量
  1. 一步到位的格式:
数据类型 变量名 = 数据值;  //在创建一个变量的同时,立刻放入指定的数据值

eg:

public class Variable{
	public static void main(String[] args) {
		// 创建一个变量
		// 格式:数据类型 变量名称;
		int num1;
		// 向变量当中存入一个数据
		// 格式:变量名称 = 数据值;
		num1 = 10;
		// 当打印输出变量名称的时候,显示出来的是变量的内容
		System.out.println(num1); // 10
		
		// 改变变量当中本来的数字,变成新的数字
		num1 = 20;
		System.out.println(num1); // 20
		
		// 使用一步到位的格式来定义变量
		// 格式:数据类型 变量名称 = 数据值;
		int num2 = 25;
		System.out.println(num2); // 25
		
		num2 = 35;
		System.out.println(num2); // 35
		System.out.println("===============");
		
		byte num3 = 30; // 注意:右侧数值的范围不能超过左侧数据类型的取值范围
		System.out.println(num3); // 30
		
		// byte num4 = 400; // 右侧超出了byte数据范围,错误!
		
		short num5 = 50;
		System.out.println(num5); // 50
		
		long num6 = 3000000000L;
		System.out.println(num6); // 3000000000
		
		float num7 = 2.5F;
		System.out.println(num7); // 2.5
		
		double num8 = 1.2;
		System.out.println(num8); // 1.2
		
		char zifu1 = 'A';
		System.out.println(zifu1); // A
		
		zifu1 = '中';
		System.out.println(zifu1); // 中
		
		boolean var1 = true;
		System.out.println(var1); // true
		
		var1 = false;
		System.out.println(var1); // false
		
		// 将一个变量的数据内容,赋值交给另一个变量
		// 右侧的变量名称var1已经存在,里面装的是false布尔值
		// 将右侧变量里面的false值,向左交给var2变量进行存储
		boolean var2 = var1;
		System.out.println(var2); // false
	}
}

注意:

  1. 在同一个大括号范围内,变量的名字不可以相同。
  2. 对于float和long类型来说,字母后缀F和L不要丢掉。
  3. 右侧的数据值不能超过左侧类型的范围。
  4. 没有进行赋值的变量,不能直接使用;一定要赋值之后,才能使用。
  5. 变量使用不能超过作用域的范围。
    【作用域】:从定义变量的一行开始,一直到直接所属的大括号结束为止。
  6. 可以通过一个语句来创建多个变量,但是一般情况不推荐这么写。

5.4 数据类型的转换

5.4.1 自动转换

自动转换:(隐式)将取值范围小的的类型自动提升为取值范围大的类型

特点:代码不需要进行特殊处理,自动完成。
转换规则:范围小的类型向范围大的类型提升,byteshortchar 运算时直接提升为 int
byteshortcharintlongfloatdouble

eg:

public static void main(String[] args){
	int i = 1;
	byte b = 2;
	// byte x = b + i; // 报错
	int j = b + i;
	System.out.println(j);
}

原理图解
byte类型内存占有1个字节,在和int类型进行运算时会提升为int类型,自动补充3个字节,因此计算后的结果还是int类型。
在这里插入图片描述

5.4.2 强制转换

强制转换:(显式)将取值范围大的类型强制转换成取值范围小的类型

特点:代码需要进行特殊的格式处理,不能自动完成。

转换格式

数据类型 变量名 = (数据类型)被转数据值

eg:

public static void main(String[] args) {
//short类型变量,内存中2个字节
short s = 1;
/*
出现编译失败
s和1做运算的时候,1是int类型,s会被提升为int类型
s+1后的结果是int类型,将结果在赋值会short类型时发生错误
short内存2个字节,int类型4个字节
必须将int强制转成short才能完成赋值
*/
s = s + 1//编译失败
s = (short)(s+1);//编译成功
}

原理图解
在这里插入图片描述

public static void main(String[] args) {
		// 左边是int类型,右边是long类型,不一样
		// long --> int,不是从小到大
		// 不能发生自动类型转换!
		// 格式:范围小的类型 范围小的变量名 = (范围小的类型) 原本范围大的数据;
		int num = (int) 100L;
		System.out.println(num);
		
		// long强制转换成为int类型
		int num2 = (int) 6000000000L;
		System.out.println(num2); // 1705032704
		
		// double --> int,强制类型转换
		int num3 = (int) 3.99;
		System.out.println(num3); // 3,这并不是四舍五入,所有的小数位都会被舍弃掉
		
		char zifu1 = 'A'; // 这是一个字符型变量,里面是大写字母A
		System.out.println(zifu1 + 1); // 66,也就是大写字母A被当做65进行处理
		// 计算机的底层会用一个数字(二进制)来代表字符A,就是65
		// 一旦char类型进行了数学运算,那么字符就会按照一定的规则翻译成为一个数字
		
		byte num4 = 40; // 注意!右侧的数值大小不能超过左侧的类型范围
		byte num5 = 50;
		// byte + byte --> int + int --> int
		int result1 = num4 + num5;
		System.out.println(result1); // 90
		
		short num6 = 60;
		// byte + short --> int + int --> int
		// int强制转换为short:注意必须保证逻辑上真实大小本来就没有超过short范围,否则会发生数据溢出
		short result2 = (short) (num4 + num6);
		System.out.println(result2); // 100
	}

注意

  1. 强制类型转换一般不推荐使用,因为有可能发生精度损失、数据溢出。
  2. byte/short/char这三种类型都可以发生数学运算,例如加法“+”。
  3. byte/short/char这三种类型在运算的时候,都会被首先提升成为int类型,然后再计算。
  4. boolean类型不能发生数据类型转换
5.4.3 编码表
  • ASCII编码表:(American Standard Code for Information Interchange,美国信息交换标准代码)将所有的英文字母,数字,符号都和十进制进行了对应。

常用:

字符数值
048
957
A65
Z90
a97
z122
  • Unicode码表:万国码。也是数字和符号的对照关系,开头0-127部分和ASCII完全一样,但是从128开始包含有更多字符。
public static void main(String[] args) {
		char zifu1 = '1';
		System.out.println(zifu1 + 0); // 49
		
		char zifu2 = 'A'; // 其实底层保存的是65数字
		
		char zifu3 = 'c';
		// 左侧是int类型,右边是char类型,
		// char --> int,确实是从小到大
		// 发生了自动类型转换
		int num = zifu3;
		System.out.println(num); // 99
		
		char zifu4 = '中'; // 正确写法
		System.out.println(zifu4 + 0); // 20013
	}

六、运算符

6.1 算术运算符

算术运算符
+加法运算、字符串连接运算
-减法运算
*乘法运算
/除法运算
%取模运算、两个数字相除取余数
++--自增自减运算

注意

  1. 对于一个整数的表达式来说,除法用的是整除,整数除以整数,结果仍然是整数,只看商,不看余数。
  2. 只有对于整数的除法来说,取模运算符才有余数的意义。
  3. Java中,整数使用以上运算符,无论怎么计算,也不会得到小数。
  4. 一旦运算当中有不同类型的数据,那么结果将会是数据类型范围大的那种。
  • 加号+ 有常见的三种用法:
  1. 对于数值来说,那就是加法。
  2. 对于字符char类型来说,在计算之前,char会被提升成为int,然后再计算。(char类型字符,和int类型数字,之间的对照关系表:ASCII、Unicode)
  3. 对于字符串String(首字母大写,并不是关键字)来说,加号代表字符串连接操作,任何数据类型和字符串进行连接的时候,结果都会变成字符串

eg:

public static void main(String[] args) {
		// 字符串类型的变量基本使用
		// 数据类型 变量名称 = 数据值;
		String str1 = "Hello";
		System.out.println(str1); // Hello
		
		System.out.println("Hello" + "World"); // HelloWorld
		
		String str2 = "Java";
		// String + int --> String
		System.out.println(str2 + 20); // Java20
		
		// 优先级问题
		// String + int + int
		// String		+ int
		// String
		System.out.println(str2 + 20 + 30); // Java2030
		
		System.out.println(str2 + (20 + 30)); // Java50
	}
  • ++--运算:++使变量自己增长1,--使变量自己减1,两个运算符用法一样。
  1. 独立运算:前++和后++没有任何区别,也就是:++num;num++;是完全一样的。
  2. 混合运算
    A. 如果是【前++】,那么变量【立刻马上+1】,然后拿着结果进行使用。 【先加后用】
    B. 如果是【后++】,那么首先使用变量本来的数值,【然后再让变量+1】。 【先用后加】

注意
只有变量才能使用自增、自减运算符。常量不可发生改变,所以不能用。

eg:

public static void main(String[] args) {
		int num1 = 10;
		System.out.println(num1); // 10
		++num1; // 单独使用,前++
		System.out.println(num1); // 11
		num1++; // 单独使用,后++
		System.out.println(num1); // 12
		System.out.println("=================");
		
		// 与打印操作混合的时候
		int num2 = 20;
		// 混合使用,先++,变量立刻马上变成21,然后打印结果21
		System.out.println(++num2); // 21
		System.out.println(num2); // 21
		System.out.println("=================");
		
		int num3 = 30;
		// 混合使用,后++,首先使用变量本来的30,然后再让变量+1得到31
		System.out.println(num3++); // 30
		System.out.println(num3); // 31
		System.out.println("=================");
		
		int num4 = 40;
		// 和赋值操作混合
		int result1 = --num4; // 混合使用,前--,变量立刻马上-1变成39,然后将结果39交给result1变量
		System.out.println(result1); // 39
		System.out.println(num4); // 39
		System.out.println("=================");
		
		int num5 = 50;
		// 混合使用,后--,首先把本来的数字50交给result2,然后我自己再-1变成49
		int result2 = num5--;
		System.out.println(result2); // 50
		System.out.println(num5); // 49
		System.out.println("=================");
		
		int x = 10;
		int y = 20;
		// 11 + 20 = 31
		int result3 = ++x + y--;
		System.out.println(result3); // 31
		System.out.println(x); // 11
		System.out.println(y); // 19
		
		// 30++; // 错误写法!常量不可以使用++或者--
	}

扩展:
常量和变量的运算

public static void main(String[] args){
	byte b1 = 1;
	byte b2 = 2;
	byte b3 = 1 + 2;
	byte b4 = b1 + b2;
	System.out.println(b3); //3
	System.out.println(b4); //错误
}

分析b3 = 1 + 212 是常量,为固定不变的数据,在编译的时候(编译器javac),已经确定了 1+2 的结果并没 有超过byte类型的取值范围,可以赋值给变量 b3 ,因此 b3=1 + 2 是正确的。
反之, b4 = b2 + b3b2b3 是变量,变量的值是可能变化的,在编译的时候,编译器javac不确定b2+b3的结果是什 么,因此会将结果以int类型进行处理,所以int类型不能赋值给byte类型,因此编译失败。

6.2 赋值运算符

赋值运算符的作用就是将符号右边的值,赋给左边的变量。

基本赋值运算符
=等于号
复合赋值运算符
+=加等于a += 3   相当于   a = a + 3
-=减等于b -= 4   相当于   b = b - 4
*=乘等于c *= 5   相当于   c = c * 5
/=除等于d /= 6   相当于   d = d / 6
%=取模等e %= 7   相当于   e = e % 7

注意

  1. 只有变量才能使用赋值运算符,常量不能进行赋值。
  2. 复合赋值运算符其中隐含了一个强制类型转换。
    byte num = 30;
    // num = num + 5;
    // num = byte + int
    // num = int + int
    // num = int
    // num = (byte) int
    num += 5;
  3. 对于byte/short/char三种类型来说,如果右侧赋值的数值没有超过范围,
    那么javac编译器将会自动隐含地为我们补上一个(byte)(short)(char)。

6.3 比较运算符

比较运算符
==比较符号两边数据是否相等,相等结果是true
<比较符号左边的数据是否小于右边的数据,如果小于结果是true
>比较符号左边的数据是否大于右边的数据,如果大于结果是true
<=比较符号左边的数据是否小于或者等于右边的数据,如果小于结果是true
>=比较符号左边的数据是否大于或者等于右边的数据,如果小于结果是true
!=不等于符号 ,如果符号两边的数据不相等,结果是true

注意

  1. 比较运算符的结果一定是一个boolean值,成立就是true,不成立就是false。
  2. 如果进行多次判断,不能连着写。数学当中的写法,例如:1 < x < 3,
    程序当中【不允许】这种写法。

6.4 逻辑运算符

逻辑运算符
&&1. 两边都是true,结果是true
2. 一边是false,结果是false
短路特点:符号左边是false,右边不再运算
||1. 两边都是false,结果是false
2. 一边是true,结果是true
短路特点: 符号左边是true,右边不再运算
! 取反1. ! true 结果是false
2. ! false结果是true

注意

  1. 逻辑运算符只能用于boolean值。
  2. 与、或需要左右各自有一个boolean值,但是取反只要有唯一的一个boolean值即可。
  3. 与、或两种运算符,如果有多个条件,可以连续写。
    两个条件:条件A && 条件B
    多个条件:条件A && 条件B && 条件C

6.5 三元运算符

Tips:
一元运算符:只需要一个数据就可以进行操作的运算符。例如:取反!、自增++、自减- -;
二元运算符:需要两个数据才可以进行操作的运算符。例如:加法+、赋值=;
三元运算符:需要三个数据才可以进行操作的运算符。

格式

数据类型 变量名 = 布尔类型表达式(条件判断) ? 结果1 : 结果2

计算方式

  • 布尔类型表达式结果是true,三元运算符整体结果为结果1,赋值给左侧的变量。
  • 布尔类型表达式结果是false,三元运算符整体结果为结果2,赋值给左侧的变量。

注意

  1. 必须同时保证结果1和结果2都符合左侧数据类型的要求。
  2. 三元运算符的结果必须被使用。

七、方法

方法:就是将一个功能抽取出来,把代码单独定义在一个大括号内,形成一个单独的功能。

7.1 方法的定义

定义格式

修饰符   返回值类型   方法名   (参数列表) {
       代码
       return;
}

注意

  1. 定义位置:类中方法外面。
  2. 方法定义的先后顺序无所谓。
  3. 方法的定义不能产生嵌套包含关系。
  4. 方法定义好了之后,不会执行的。如果要想执行,一定要进行方法的【调用】。
  5. 返回值类型,必须要和 return 语句返回的类型相同,否则编译失败 。
  6. 任何数据类型都能作为方法的参数类型,或者返回值类型。
  7. 方法的参数为基本类型时,传递的是数据值; 方法的参数为引用类型时,传递的是地址值

7.2 方法的调用

  1. 单独调用:方法名称(参数);
  2. 打印调用:System.out.println(方法名称(参数));
  3. 赋值调用:数据类型 变量名称 = 方法名称(参数);

注意
返回值类型为void,这种方法只能够单独调用,不能进行打印调用或者赋值调用。

7.2 方法的重载

方法重载:指在同一个类中,允许存在一个以上的同名方法,只要它们的**参数列表不同(个数不同/数据类型不同/顺序不同)**即可,与修饰符和返回值类型无关。

重载方法调用:JVM通过方法的参数列表,调用不同的方法。

7.3 可变参数

可变参数:这是在JDK1.5之后出现的新特性,定义一个可以接受个数不确定但类型一致的参数的方法。

使用前提:当方法的参数列表数据类型已经确定,但是参数的个数不确定,就可以使用可变参数。

格式:定义方法时使用

修饰符 返回值类型 方法名(参数类型... 形参名){}
/*
	这个写法完全等价于:修饰符 返回值类型 方法名(参数类型[] 形参名){},只是这种定义在调用时必须传递数组,而前者可以直接传递数据即可。
*/
// 可变参数的特殊(终极)写法
修饰符 返回值类型 方法名(Object... 形参名){}

可变参数的原理:可变参数底层就是一个数组,根据传递参数个数不同,会创建不同长度的数组,来存储这些参数;传递的参数的个数,可以是0个(不传递),1,2…多个。

注意

  1. 一个方法的参数列表,只能有一个可变参数。
  2. 如果方法的参数有多个,那么可变参数必须写在参数列表的末尾。

eg:

public class Demo01VarArgs {
    public static void main(String[] args) {
        //int i = add();
        //int i = add(10);
        int i = add(10,20);
        //int i = add(10,20,30,40,50,60,70,80,90,100);
        System.out.println(i);

        method("abc",5.5,10,1,2,3,4);
    }

    //可变参数的特殊(终极)写法
    public static void method(Object...obj){

    }

    /*
        定义计算(0-n)整数和的方法
        已知:计算整数的和,数据类型已经确定int
        但是参数的个数不确定,不知道要计算几个整数的和,就可以使用可变参数
        add(); 就会创建一个长度为0的数组, new int[0]
        add(10); 就会创建一个长度为1的数组,存储传递来过的参数 new int[]{10};
        add(10,20); 就会创建一个长度为2的数组,存储传递来过的参数 new int[]{10,20};
        add(10,20,30,40,50,60,70,80,90,100); 就会创建一个长度为2的数组,存储传递来过的参数 new int[]{10,20,30,40,50,60,70,80,90,100};
     */
    public static int add(int...arr){
        //System.out.println(arr);//[I@2ac1fdc4 底层是一个数组
        //System.out.println(arr.length);//0,1,2,10
        //定义一个初始化的变量,记录累加求和
        int sum = 0;
        //遍历数组,获取数组中的每一个元素
        for (int i : arr) {
            //累加求和
            sum += i;
        }
        //把求和结果返回
        return sum;
    }

    //定义一个方法,计算三个int类型整数的和
    /*public static int add(int a,int b,int c){
        return a+b+c;
    }*/

    //定义一个方法,计算两个int类型整数的和
    /*public static int add(int a,int b){
        return a+b;
    }*/
}

八、判断语句

8.1 if

格式

if(关系表达式){
	语句体;	
}

执行流程

  1. 首先判断关系表达式看其结果是true还是false。
  2. 如果是true就执行语句体;是false就不执行语句体。
    在这里插入图片描述

8.2 if…else

格式

if(关系表达式){
	语句体1;
}else{
	语句体2;
}

执行流程

  1. 首先判断关系表达式看其结果是true还是false。
  2. 如果是true就执行语句体1;是false就执行语句体2。
    在这里插入图片描述
    扩展:if语句和三元运算符的互换
public static void main(String[] args){
	int a = 10;
	int b = 20;
	int c;
	//定义变量,保存a和b的较大值
	if(a > b){
		c = a;
	}else{
		c = b;
	}
	//上述功能改写为三元运算符形式
	c = a > b ? a:b;
}

8.3 if…else if…else

格式

if(判断条件1){
   执行语句1;    
   } else if (判断条件2) {    
   执行语句2;    
   } 
   ... 
   }else if (判断条件n) {   
   执行语句n;     
   } else {    
   执行语句n+1;
}

执行流程

  1. 首先判断关系表达式看其结果是true还是false。
  2. 如果是true就执行语句体1。
  3. 如果是false就继续判断关系表达式2看其结果是true还是false。
  4. 如果是true就执行语句体2。
  5. 如果是false就继续判断关系表达式…看其结果是true还是false。
  6. 如果没有任何关系表达式为true,就执行语句体n+1。
    在这里插入图片描述

九、选择语句

9.1 switch

格式

switch(表达式){
	case 常量值1:
		语句体1;
		break;
	case 常量值2:
		语句体2;
		break;
	...
	default:
		语句体n+1;
		break;
}

执行流程

  1. 首先计算出表达式的值。
  2. 其次,和case依次比较,一旦有对应的值,就会执行相应的语句,在执行的过程中,遇到break就会结束。
  3. 最后,如果所有的case都和表达式的值不匹配,就会执行default语句体部分,程序结束。
    在这里插入图片描述

注意

  1. 多个case后面的数值不可以重复。
  2. switch后面小括号当中只能是下列数据类型:
    基本数据类型:byte/short/char/int
    引用数据类型:String字符串、enum枚举
  3. switch语句格式可以很灵活:前后顺序可以颠倒。

扩展:case的穿透性
在switch语句中,如果case的后面不写break,将出现穿透现象,也就是不会再判断下一个case的值,直接向后运 行,直到遇到break,或者整体switch结束

十、循环语句

循环结构的基本组成部分,一般可以分成四部分:

  1. 初始化语句:在循环开始最初执行,而且只做唯一一次。
  2. 条件判断:如果成立,则循环继续;如果不成立,则循环退出。
  3. 循环体:重复要做的事情内容,若干行语句。
  4. 步进语句:每次循环之后都要进行的扫尾工作,每次循环结束之后都要执行一次。

10.1 for

格式

for(初始表达式①;布尔表达式②;步进表达式④){
	循环体③
}

执行流程

  • 执行顺序:①②③④>②③④>②③④…②不满足为止。
    在这里插入图片描述

10.2 while

格式

初始化表达式①
while(布尔表达式②){
	循环体③
	步进表达式④
}

执行流程

  • 执行顺序:①②③④>②③④>②③④…②不满足为止。
    在这里插入图片描述

10.3 do…while

格式

初始化表达式①
do{
	循环体③
	步进表达式④
}while(布尔表达式②);

特点:无条件执行一次循环体,即使我们将循环条件直接写成false,也依然会循环一次。

执行流程

  • 执行顺序:①③④>②③④>②③④…②不满足为止。
    在这里插入图片描述

eg:

public static void main(String[] args){
	do{
		System.out.println("无条件执行一次");
	}while(false);
}

10.4 for 和 while 的区别

  • 控制条件语句所控制的那个变量,在for循环结束后,就不能再被访问到了,而while循环结束还可以继 续使用,如果你想继续使用,就用while,否则推荐使用for。原因是for循环结束,该变量就从内存中消 失,能够提高内存的使用效率。
  • 在已知循环次数的时候使用推荐使用for,循环次数未知的时推荐使用while。

10.5 跳出语句

10.5.1 break
  1. 可以用在switch语句当中,一旦执行,整个switch语句立刻结束。
  2. 还可以用在循环语句当中,一旦执行,整个循环语句立刻结束。打断循环。

eg:

public static void mian(String[] args){
	for(int i = 1;i<=10;i++){
		//需求:打印完两次HelloWorld之后结束循环
		if(i == 3){
		break;
	}
	System.out.println("HelloWorld"+i);
}
10.5.2 continue

一旦执行,立刻跳过当前次循环剩余内容,马上开始下一次循环。

eg:

public static void mian(String[] args){
	for(int i = 1;i<=10;i++){
		//需求:不打印第三次HelloWorld
		if(i == 3){
		continue;
	}
	System.out.println("HelloWorld"+i);
}

10.6 死循环

死循环:循环中的条件永远为true,死循环是永不结束的循环。例如:while(true){}。

10.7 嵌套循环

循环嵌套:指一个循环的循环体是另一个循环。总共的循环次数=外循环次数*内循环次数

格式

for(初始化表达式①; 循环条件②; 步进表达式⑦) {     
	for(初始化表达式③; 循环条件④; 步进表达式⑥) {        
		执行语句⑤;        
	}
}

执行流程

  • 执行顺序:①②③④⑤⑥>④⑤⑥>⑦②③④⑤⑥>④⑤⑥
  • 外循环一次,内循环多次。

eg:

public static void main(String[] args) {     
	//5*8的矩形,打印5行*号,每行8个     
	//外循环5次,内循环8次     
	for(int i = 0; i < 5; i++){         
		for(int j = 0; j < 8; j++){             
			//不换行打印星号
			System.out.print("*");         
		}         
		//内循环打印8个星号后,需要一次换行
		System.out.println();     
	}
}

十一、数组

数组:数组就是存储数据长度固定的容器,可以同时存放多个数据值。

特点

  1. 数组是一种引用数据类型。
  2. 数组当中的多个数据,类型必须统一。
  3. 数组的长度在程序运行期间不可改变。

11.1 数组的定义

数组的初始化:在内存当中创建一个数组,并且向其中赋予一些默认值。

两种常见的初始化方式:

  1. 动态初始化(指定长度)
    格式
数据类型[] 数组名称 = new 数据类型[数组长度];
  1. 静态初始化(指定内容)
    标准格式
数据类型[] 数组名称 = new 数据类型[] { 元素1, 元素2, ... };

省略格式

数据类型[] 数组名称 = { 元素1, 元素2, ... };

注意

  1. 静态初始化没有直接指定长度,但是仍然会自动推算得到长度。
  2. 静态初始化标准格式可以拆分成为两个步骤。
  3. 动态初始化也可以拆分成为两个步骤。
  4. 静态初始化一旦使用省略格式,就不能拆分成为两个步骤了。
  5. 使用动态初始化数组的时候,其中的元素将会自动拥有一个默认值。规则如下:
    如果是整数类型,那么默认为0;
    如果是浮点类型,那么默认为0.0;
    如果是字符类型,那么默认为’\u0000’;
    如果是布尔类型,那么默认为false;
    如果是引用类型,那么默认为null。
  6. 静态初始化其实也有默认值的过程,只不过系统自动马上将默认值替换成为了大括号当中的具体数值。
public static void main(String[] args) {
        // 省略格式的静态初始化
        int[] arrayA = { 10, 20, 30 };

        // 静态初始化的标准格式,可以拆分成为两个步骤
        int[] arrayB;
        arrayB = new int[] { 11, 21, 31 };

        // 动态初始化也可以拆分成为两个步骤
        int[] arrayC;
        arrayC = new int[5];

        // 静态初始化的省略格式,不能拆分成为两个步骤。
//        int[] arrayD;
//        arrayD = { 10, 20, 30 };
    }

11.2 数组的访问

格式

数组名[索引]

索引:一个int数字,代表数组当中元素的编号。

注意

  1. 直接打印数组名称,得到的是数组对应的:内存地址哈希值。
  2. 每个数组都具有长度,而且是固定的,获取到数组长度的语句为: 数组名.length ,属性length的执行结果是数组的长度,int类型结果。
  3. 索引值从0开始,一直到“数组的长度-1”为止。

索引访问数组中的元素

  • 数组名[索引] = 数据,为数组中的元素赋值
  • 变量 = 数组名[索引],获取数组的元素

11.3 数组原理内存图

一个数组的内存图:
在这里插入图片描述
两个独立数组的内存图:
在这里插入图片描述
两个引用指向同一个数组的内存图:
在这里插入图片描述
数组的长度在运行时不可改变:
在这里插入图片描述

11.4 数组的常见操作

11.4.1 数组索引越界异常(ArrayIndexOutOfBoundsException)
public static void main(String[] args) {
        int[] array = { 15, 25, 35 };
        
        System.out.println(array[0]); //15
        System.out.println(array[1]); // 25
        System.out.println(array[2]); // 35

        // 错误写法
        // 并不存在3号元素,所以发生异常
        System.out.println(array[3]);
    }

分析:如果访问数组元素的时候,索引编号并不存在,那么将会发生数组索引越界异常。

11.4.2 数组空指针异常
public static void main(String[] args) {
        int[] array = null;
//        array = new int[3];
        System.out.println(array[0]);
    }

分析:数组必须进行new初始化才能使用其中的元素。
如果只是赋值了一个null,没有进行new创建,就不允许再操作数组了,不然将会发生空指针异常。

11.4.3 数组遍历
public static void main(String[] args) {
        int[] array = { 15, 25, 30, 40, 50, 60, 75 };
        // 首先使用原始方式
        System.out.println(array[0]); // 15
        System.out.println(array[1]); // 25
        System.out.println(array[2]); // 30

        // 使用循环,次数其实就是数组的长度。
        for (int i = 0; i < 6; i++) {
            System.out.println(array[i]);
        }

//        int len = array.length; // 长度
        for (int i = 0; i < array.length; i++) {
            System.out.println(array[i]);
        }
    }
11.4.4 数组获取最大值元素
public static void main(String[] args) {     
	int[] arr = { 5, 15, 2000, 10000, 100, 4000 };     
	//定义变量,保存数组中0索引的元素     
	int max = arr[0];     
	//遍历数组,取出每个元素     
	for (int i = 0; i < arr.length; i++) {       
	//遍历到的元素和变量max比较       
	//如果数组元素大于max       
		if (arr[i] > max) {         
		//max记录住大值         
		max = arr[i];       
		}     
	}     
	System.out.println("数组最大值是: " + max); 
}
11.4.4 数组反转

数组的反转:数组中的元素颠倒顺序。

思路:
把数组最小索引元素和数组的最大索引元素交换
把数组次小索引元素和数组的次大索引元素交换

定义两个索引,一个指向最小索引,一个指向最大索引
int min = 0; int max = arr.length - 1;
遍历数组,让两个索引变化
min++, max-- 条件 min<max
交换最小索引元素和最大索引元素,需要定义第三方变量
int temp = arr[min];
arr[min] = arr[max];
arr[max] = temp;

public static void main(String[] args) {     
	int[] arr = { 1, 2, 3, 4, 5 };     
	/*       
		循环中定义变量min=0最小索引       
		max=arr.length‐1最大索引       
		min++,max‐      */     
	for (int min = 0, max = arr.length ‐ 1; min <= max; min++, max‐‐) {       
		//利用第三方变量完成数组中的元素交换       
		int temp = arr[min];       
		arr[min] = arr[max];       
		arr[max] = temp;     
	}      
} 
11.4.5 数组作为方法参数和返回值

数组作为方法参数传递,传递的参数是数组内存的地址。

public static void main(String[] args) {     
	int[] arr = { 1, 3, 5, 7, 9 };     
	//调用方法,传递数组     
	printArray(arr); 
} 
/* 
创建方法,方法接收数组类型的参数      
进行数组的遍历      */ 
public static void printArray(int[] arr) {     
	for (int i = 0; i < arr.length; i++) {       
	System.out.println(arr[i]);     
	} 
} 

在这里插入图片描述

数组作为方法的返回值,返回的是数组的内存地址。

public static void main(String[] args) {     
	//调用方法,接收数组的返回值     
	//接收到的是数组的内存地址     
	int[] arr = getArray();     
	for (int i = 0; i < arr.length; i++) {       
		System.out.println(arr[i]);     
	} 
} 
/* 
	创建方法,返回值是数组类型      
	return返回数组的地址      
*/ 
public static int[] getArray() {     
	int[] arr = { 1, 3, 5, 7, 9 };     
	//返回数组的地址,返回到调用者     
	return arr; 
} 

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值