1 Java简介

1.1 Java简介

Java 是由 Sun Microsystems 公司于 1995 年 5 月推出的 Java 面向对象程序设计语言和 Java 平台的总称。由 James Gosling和同事们共同研发,并在 1995 年正式推出。后来 Sun 公司被 Oracle (甲骨文)公司收购,Java 也随之成为 Oracle 公司的产品。

Java分为三个体系:

  • JavaSE(J2SE)(Java2 Platform Standard Edition,java平台标准版)

  • JavaEE(J2EE)(Java 2 Platform,Enterprise Edition,java平台企业版)

  • JavaME(J2ME)(Java 2 Platform Micro Edition,java平台微型版)。

2005 年 6 月,JavaOne 大会召开,SUN 公司公开 Java SE 6。此时,Java 的各种版本已经更名,以取消其中的数字 "2":J2EE 更名为 Java EE,J2SE 更名为Java SE,J2ME 更名为 Java ME。

1.2 Java主要特性

  • Java 语言是面向对象的:

Java 语言提供类、接口和继承等面向对象的特性,为了简单起见,只支持类之间的单继承,但支持接口之间的多继承,并支持类与接口之间的实现机制(关键字为 implements)。Java 语言全面支持动态绑定,而 C++语言只对虚函数使用动态绑定。总之,Java语言是一个纯的面向对象程序设计语言。

  • Java 语言是健壮的:

Java 的强类型机制、异常处理、垃圾的自动收集等是 Java 程序健壮性的重要保证。对指针的丢弃是 Java 的明智选择。Java 的安全检查机制使得 Java 更具健壮性。

  • Java 语言是跨平台性的:

一个编译好的.class文件可以在多个系统下运行,这种特性称为跨平台

  • Java 语言是解释型的:

Java 程序在 Java 平台上被编译为字节码格式,然后可以在实现这个 Java 平台的任何系统中运行。在运行时,Java 平台中的 Java 解释器对这些字节码进行解释执行,执行过程中需要的类在联接阶段被载入到运行环境中。

解释性语言:JavaScript, PHP, Java等

编译性语言:C, C++等

解释性语言,编译后的代码,不能直接被机器执行,需要解释器来执行,编译性语言,编译后的代码,可以直接被机器执行

1.3 Java运行机制及运行过程

Java核心机制——Java虚拟机(JVM Java Virtual Machine)

  • JVM是一个虚拟的计算机,具有指令集并使用不用的存储区域。负责执行指令,管理数据、内存、寄存器,包含在JDK中

  • 对于不同的平台,有不同的虚拟机

  • Java虚拟机机制屏蔽了底层运行平台的差别,实现了“一次编译,到处运行”。

JDK(Java Development Kit, Java开发工具包)

  • JDK = JRE + Java的开发工具(Java、Javac、Javadoc、Javap等)

  • JDK是提供给Java开发人员使用的,其中包含了Java开发工具,也包括了JRE,所以安装了JDK,就不用单独安装JRE了

JRE(Java Runtime Environment,Java运行环境)

  • JRE = JVM + Java的核心类(库)

  • 包括Java虚拟机和Java程序所需的核心类库等,如果想要运行一个开发好的Java程序,计算机中只需安装JRE即可

1.4 Java的安装

首先我们需要下载 java 开发工具包 JDK,下载地址:https://www.oracle.com/java/technologies/downloads/,在下载页面中根据自己的系统选择对应的版本(一般Java8 或者 Java11)

下载后 JDK 的安装根据提示进行,还有安装 JDK 的时候也会安装 JRE,一并安装就可以了。

1.5 环境变量的配置

安装完成后,右击"我的电脑",点击"属性",选择"高级系统设置";在 "系统变量" 中设置 3 项属性,JAVA_HOME、PATH、CLASSPATH(大小写无所谓),若已存在则点击"编辑",不存在则点击"新建"。

变量名:JAVA_HOME
变量值:C:\Program Files (x86)\Java\jdk1.8.0_91        // 要根据自己的实际路径配置
​
变量名:CLASSPATH
变量值:.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;         //记得前面有个"."
​
变量名:Path
变量值:%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin;

1.6 JAVA开发工具

1.7 Java快速入门

1.7.1 第一个Java程序

public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello World");
    }
}
  • public class HelloWorld表示HelloWorld是一个类,是一个公有(public)的类

  • HelloWorld{ }表示一个类的开始和结束

  • public static void main(String[] args)表示一个主方法,即我们程序的入口

  • main() {}表示方法的开始和结束

  • System.out.println("Hello World");表示输出"Hello World"到屏幕

  • ;表示语句结束

1.7.2 运行Java程序

$ javac HelloWorld.java     # 编译
$ java HelloWorld           # 执行
Hello World
  • javac 后面跟着的是java文件的文件名,例如 HelloWorld.java。 该命令用于将 java 源文件编译为 class 字节码文件

  • 运行javac命令后,如果成功编译没有错误的话,会出现一个 HelloWorld.class 的文件。

  • java 后面跟着的是java文件中的类名,例如 HelloWorld 就是类名,如: java HelloWorld

1.8 注意事项

  • Java源文件以.java为扩展名,源文件的基本组成部分是类(class)

  • Java应用程序的执行入口是main()方法。它有固定的书写格式public static void main(String[] args) {...}

  • Java语言严格区分大小写

  • Java方法由一条条语句构成,每个语句以;结束

  • 大括号都是成对出现的,缺一不可

  • 一个源文件最多只能由一个public类。其他类的个数不限,编译后,每一个类,都对应一个.class文件。也可以将main方法写在非public类中,然后指定运行非public类,这样入口方法就是非publicmain方法

  • 如果源文件包含一个public类,则文件名必须按该类名命名

1.9 Java 包

包主要用来对类和接口进行分类。当开发 Java 程序时,可能编写成百上千的类,因此很有必要对类和接口进行分类。

在 Java 中,如果给出一个完整的限定名,包括包名、类名,那么 Java 编译器就可以很容易地定位到源代码或者类。import 语句就是用来提供一个合理的路径,使得编译器可以找到某个类。

下面的命令行将会命令编译器载入 java_installation/java/io 路径下的所有类

import java.io.*;

1.10 转义字符的使用

转义字符

说明

\t

一个制表位,实现对齐的功能

\n

换行符

\\

一个\

\"

一个"

\'

一个'

\r

一个回车

1.11 注释

1.11.1 单行注释和多行注释

用于注解说明解释程序的文字就是注释,注释提高了代码的阅读性(可读性);注释是一个程序员必须要具有的良好编程习惯。将自己的思想通过注释先整理出来,再用代码去体现

//单行注释
​
/* 
多行注释
多行注释
*/
  • 被注释的文字,不会被JVM(java 虚拟机)解释执行

  • 多行注释里面不允许有多行注释嵌套

1.11.2 文档注释

注释内容可以被 JDK 提供的工具 javadoc 所解析 , 生成一套以网页文件形式体现的该程序的说明文档 , 一般写在类

/**
 * @Author: AdRainty 
 * @Date: 2022-04-25 20:28:19 
 */

生成网页文档:

javadoc -d 文件夹名 -xx -yy Demo.java

例如

javadoc -d d:\\test -author -date Demo.java

2 Java基础语法

2.1 变量

  • 变量是程序的基本组成单位

  • 变量有三个基本要素:类型 + 名称 + 值

class Test {
    public static void main(String []args){
        int a = 1;  // 定义一个变量,类型为int整形,名称a,值1
        System.out.println(a);  //输出a变量的值
    }
}
  • 变量表示内存中的一个存储区域,不同的变量,类型不同,占用的空间大小不同。例如int 4字节,double 8字节

  • 该区域有字节的变量名称和类型

  • 变量必须先声明,后使用

  • 该区域的数据可以在同一类型范围内不断变化

  • 变量在同一个作用域内不能重名

2.2 +号的使用

  • 当左右两边都是数值型时,则做加法运算

  • 当左右两边有一方为字符串,则做拼接运算

  • 运算顺序是从左到右

System.out.println(100 + 98);   //198
System.out.println("100" + 98);     //10098
System.out.println(100 + 3 + "hello");  //103hello
System.out.println("hello" + 100 + 3);  //hello1003

2.3 数据类型

每一种数据都定义了明确的数据类型,在内存中分配了不同大小的内存空间(字节)。

2.3.1 整数类型

Java 的整数类型就是用于存放整数值的,比如12 , 30, 3456 等等

类型

占用存储空间

范围

byte(字节)

1字节

-128-127

short(短整型)

2字节

-(215)-215-1

int(整形)

4字节

-(231)-231-1

long(长整型)

8字节

-(263)-263-1

  • Java各整数类型有固定的范围和字段长度,不受具体OS的影响,以保证Java程序的可移植性

  • Java的整型常量默认为int型,声明long型常量需后加lL

  • Java程序中的变量常声明为int型,除非不足以表示大数,才使用long

  • bit为计算机中的最小存储单位。byte为计算机中基本存储单元,1byte = 8 bit

2.3.2 浮点类型

Java 的浮点类型可以表示一个小数,比如123.4 ,7.8 ,0.12 等等

类型

占用存储空间

范围

单精度float

4字节

-3.403E38-3.403E38

双精度double

8字节

-1.798E308-1.798E308

  • 关于浮点数在机器中存放形式的简单说明,浮点数=符号位+指数位+尾数位

  • 尾数部分可能丢失,造成精度损失(小数都是近似值)。

  • 与整数类型类似,Java浮点类型有固定的范围和字段长度,不受具体OS的影响

  • Java浮点类型常量默认为double,声明float型,后面需要加fF

  • 通常情况下应该使用double型,因为比float型更精确

2.3.3 字符类型

字符类型可以表示单个字符,字符类型是char,char 是两个字节(可以存放汉字),多个字符我们用字符串String(我们后面详细讲解String)

  • 字符常量是用单引号''括起来的单个字符,例如char c1 = 'a';

  • Java中还允许使用转义字符\来将其后面的字符转化为特殊字符型常量

  • 在Java中,char的本质是一个整数,在输出时,是Unicode码对应的字符

  • 可以直接将char赋一个整数,然后输出时,会按照对应的Unicode字符输出

  • char类型是可以进行运算的,相当于一个整数,因为它都对应有Unicode码

字符和码值的对应关系是通过字符编码表决定的

  • ASCII,一个字节表示,实际上一个字节可以表示256个字符,只用了128个

  • Unicode,固定大小的编码,使用两个字节表示字符,字母和汉字统一都是占用两个字节

  • utf-8,编码表,大小可变的编码,字母使用1个字节,汉字使用3个字节

  • gbk,可以表示汉字,而且范围广,字母使用1个字节,汉字使用2个字节

  • gb2312,可以表示汉字,gb2312<gk

  • big5,繁体中文

2.3.4 布尔类型

  • 布尔类型也叫Boolean类型, Boolean类型数据只允许取址true和false,无null

  • Boolean类型占一个字节

  • Boolean类型适于逻辑运算,一遍用于程序流程控制

2.4 基本数据类型转换

2.4.1 自动类型转换

当Java程序在进行赋值或者运算时,精度小的类型会自动转化为精度大的数据类型,这个就是自动类型转化

  • 有多种类型的数据混合运算时,系统首先自动将所有数据转化成容量最大的那种数据类型,然后再进行计算

  • 当我们把精度大的数据类型赋值给精度小的数据类型时,就会报错,反之就会进行自动类型转换

  • (byte,short)和char之间不会相互自动转换

  • byte,short,char他们可以计算,在计算时首先转换为int类型

  • Boolean不参与转化

  • 表达式结果的类型自动提升为操作数中最大的类型

2.4.2 强制类型转换

自动类型转换的逆过程,将容量大的数据类型转换为容量小的数据类型。使用时要加上强制转换符( ),但可能造成精度降低或溢出,格外要注意。

int i = (int)1.9;
int j = 100;
byte b1 = (byte)j

2.4.3 基本数据类型和String 类型的转换

在程序开发中,我们经常要将基本数据类型转成String类型,或者将String类转成基本数据类型。

  • 基本类型转String类型

将基本类型的值 + “”即可

int n1 = 100;
String str1 = n1 + ""
  • String类型转基本数据类型

通过基本类型的包装类调用praseXX方法即可

Integer.parseInt("123");
Boolean.parseBoolean("true");
Float.parseFloat("123.45");
  • 在将String 类型转成基本数据类型时,要确保String类型可以转化成有效的数据 ,比如我们可以把"123" , 转成一个整数,但是不能把"hello" 转成一个整数

  • 如果格式不正确,就会抛出异常,程序就会终止,

2.5 修饰符

2.5.1 访问控制修饰符

Java语言提供了很多修饰符,主要分为以下两类:

  • 访问修饰符

  • 非访问修饰符

修饰符用来定义类、方法或者变量,通常放在语句的最前端。

public class ClassName {
   // ...
}
private boolean myFlag;
static final double weeks = 9.5;
protected static final int BOXWIDTH = 42;
public static void main(String[] arguments) {
   // 方法体
}
  • default (即默认,什么也不写): 在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法。

  • private : 在同一类内可见。使用对象:变量、方法。 注意:不能修饰类(外部类)

私有访问修饰符是最严格的访问级别,所以被声明为 private 的方法、变量和构造方法只能被所属类访问,并且类和接口不能声明为 private。声明为私有访问类型的变量只能通过类中公共的 getter 方法被外部类访问。Private 访问修饰符的使用主要用来隐藏类的实现细节和保护类的数据。

  • public : 对所有类可见。使用对象:类、接口、变量、方法

被声明为 public 的类、方法、构造方法和接口能够被任何其他类访问。如果几个相互访问的 public 类分布在不同的包中,则需要导入相应 public 类所在的包。由于类的继承性,类所有的公有方法和变量都能被其子类继承。

  • protected : 对同一包内的类和所有子类可见。使用对象:变量、方法。 注意:不能修饰类(外部类)

    • 子类与基类在同一包中:被声明为 protected 的变量、方法和构造器能被同一个包中的任何其他类访问;

    • 子类与基类不在同一包中:那么在子类中,子类实例可以访问其从基类继承而来的 protected 方法,而不能访问基类实例的protected方法。

2.5.2 非访问修饰符

为了实现一些其他的功能,Java 也提供了许多非访问修饰符。

  • static 修饰符,用来修饰类方法和类变量。

    • 静态变量:static 关键字用来声明独立于对象的静态变量,无论一个类实例化多少对象,它的静态变量只有一份拷贝。 静态变量也被称为类变量。局部变量不能被声明为 static 变量。

    • 静态方法:static 关键字用来声明独立于对象的静态方法。静态方法不能使用类的非静态变量。静态方法从参数列表得到数据,然后计算这些数据。

  • final 修饰符,用来修饰类、方法和变量,final 修饰的类不能够被继承,修饰的方法不能被继承类重新定义,修饰的变量为常量,是不可修改的。

    • final 变量:final 表示"最后的、最终的"含义,变量一旦赋值后,不能被重新赋值。被 final 修饰的实例变量必须显式指定初始值。final 修饰符通常和 static 修饰符一起使用来创建类常量。

    • final 方法:父类中的 final 方法可以被子类继承,但是不能被子类重写。声明 final 方法的主要目的是防止该方法的内容被修改。

    • final 类:final 类不能被继承,没有类能够继承 final 类的任何特性。

  • abstract 修饰符,用来创建抽象类和抽象方法。

    • 抽象类:抽象类不能用来实例化对象,声明抽象类的唯一目的是为了将来对该类进行扩充。一个类不能同时被 abstract 和 final 修饰。如果一个类包含抽象方法,那么该类一定要声明为抽象类,否则将出现编译错误。抽象类可以包含抽象方法和非抽象方法。

    • 抽象方法:抽象方法是一种没有任何实现的方法,该方法的具体实现由子类提供。抽象方法不能被声明成 final 和 static。任何继承抽象类的子类必须实现父类的所有抽象方法,除非该子类也是抽象类。如果一个类包含若干个抽象方法,那么该类必须声明为抽象类。抽象类可以不包含抽象方法。抽象方法的声明以分号结尾,例如:public abstract sample();

  • synchronized 和 volatile 修饰符,主要用于线程的编程。synchronized 关键字声明的方法同一时间只能被一个线程访问。synchronized 修饰符可以应用于四个访问修饰符。

  • transient 修饰符:序列化的对象包含被 transient 修饰的实例变量时,java 虚拟机(JVM)跳过该特定的变量。该修饰符包含在定义变量的语句中,用来预处理类和变量的数据类型。

  • volatile 修饰符:volatile 修饰的成员变量在每次被线程访问时,都强制从共享内存中重新读取该成员变量的值。而且,当成员变量发生变化时,会强制线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。

2.5 运算符

运算符是一种特殊的符号,用以表示数据的运算、赋值和比较等。

  • 算术运算符

  • 赋值运算符

  • 关系运算符[比较运算符]

  • 逻辑运算符

  • 位运算符[需要二进制基础]

  • 三元运算符

2.5.1 算术运算符

算术运算符是对数值类型的变量进行运算的,在Java 程序中使用的非常多。

运算符

运算

+

正号

-

负号

+

-

*

/

%

取模

++ ++

自增(前):先运算后取值 自增(后):先取值后运算

-- --

自减(前):先运算后取值 自减(后):先取值后运算

+

字符串相加

2.5.2 关系运算符

  • 关系运算符的结果都是boolean 型,也就是要么是true,要么是false

  • 关系表达式经常用在if 结构的条件中或循环结构的条件中

运算符

运算

==

相等于

!=

不等于

<

小于

>

大于

<=

小于等于

>=

大于等于

instanceof

检查是否是类的对象

2.5.3 逻辑运算符

用于连接多个条件(多个关系表达式),最终的结果也是一个boolean 值。

1) a&b : &叫逻辑与:规则:当a 和b 同时为true ,则结果为true, 否则为false 2) a&&b : && 叫短路与:规则:当a 和b 同时为true ,则结果为true,否则为false 3) a|b : | 叫逻辑或,规则:当a 和b ,有一个为true ,则结果为true,否则为false 4) a||b : || 叫短路或,规则:当a 和b ,有一个为true ,则结果为true,否则为false 5) !a : 叫取反,或者非运算。当a 为true, 则结果为false, 当a 为false 是,结果为true 6) a^b: 叫逻辑异或,当a 和b 不同时,则结果为true, 否则为false

2.5.4 赋值运算符

赋值运算符就是将某个运算后的值,赋给指定的变量。可以分为

  • 基本赋值运算符=,如 int a = 10;

  • 复合赋值运算符+=-=*=/=%= 等,a += b; [等价a = a + b; ]

赋值运算符特点

  • 运算顺序从右往左

  • 赋值运算符的左边只能是变量,右边可以是变量、表达式、常量值

  • 复合赋值运算符等价于下面的效果

  • 复合赋值运算符会进行类型转换。

2.5.5 三元运算符

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

  • 如果条件表达式为true,运算后的结果是表达式1;

  • 如果条件表达式为false,运算后的结果是表达式2;

表达式1 和表达式2 要为可以赋给接收变量的类型(或可以自动转换)

2.5.6 位运算符

  • >>算术右移:低位溢出,符号位不变,并用符号位补溢出的高位

  • <<算术左移:符号位不变,低位补0

  • >>>逻辑右移:低位溢出,高位补0

2.6 标识符

Java 所有的组成部分都需要名字。类名、变量名以及方法名都被称为标识符。

  • 有的标识符都应该以字母(A-Z 或者 a-z),美元符($)、或者下划线(_)开始

  • 首字符之后可以是字母(A-Z 或者 a-z),美元符($)、下划线(_)或数字的任何字符组合

  • 关键字不能用作标识符

  • 标识符是大小写敏感的

  • 合法标识符举例:age、$salary、_value、__1_value

  • 非法标识符举例:123abc、-salary

2.7 Java关键字

类别

关键字

说明

访问控制

rivate

私有的

protected

受保护的

public

公共的

default

默认

类、方法和变量修饰符

abstract

声明抽象

class

extends

扩充,继承

final

最终值,不可改变的

implements

实现(接口)

interface

接口

native

本地,原生方法(非 Java 实现)

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 保留字:现有Java 版本尚未使用,但以后版本可能会作为关键字使用。自己命名标识符时要避免使用这些保留字

2.8 键盘输入语句

在编程中,需要接收用户输入的数据,就可以使用键盘输入语句来获取。Input.java , 需要一个扫描器(对象), 就是Scanner

import java.util.Scanner;   //表示把java.util下的Scanner类导入
​
public class Input {
    public static void main(String[] args) {
        // 1. 引入Scanner类所在的包
        // 2. 创建Scanner对象,new创建一个对象
        Scanner myScanner = new Scanner(System.in);
        // 3. 接收用户输入
        System.out.println("请输入名字:");
        // 接收用户输入
        String name = myScanner.next();  
        // String name = myScanner.nextLine();
        System.out.println("输入的数据为:" + name);
        myScanner.close();
    }
}

next() 与 nextLine() 区别:

next():

  • 一定要读取到有效字符后才可以结束输入。

  • 对输入有效字符之前遇到的空白,next() 方法会自动将其去掉。

  • 只有输入有效字符后才将其后面输入的空白作为分隔符或者结束符。

  • next() 不能得到带有空格的字符串。

nextLine() :

  • 以Enter为结束符,也就是说 nextLine()方法返回的是输入回车之前的所有字符。

  • 可以获得空白。

如果要输入 int 或 float 类型的数据,在 Scanner 类中也有支持,但是在输入之前最好先使用 hasNextXxx() 方法进行验证,再使用nextXxx() 来读取:

System.out.print("输入整数:");
if (scan.hasNextInt()) {
    // 判断输入的是否是整数
    i = scan.nextInt();
    // 接收整数
    System.out.println("整数数据:" + i);
} else {
    // 输入错误的信息
    System.out.println("输入的不是整数!");
}

3 程序控制结构

3.1 顺序控制

程序从上到下逐行地执行,中间没有任何判断和跳转

public class Test{
    int num1 = 12;
    int num2 = num1 + 2;
    System.out.println("num2");
}

3.2 分支控制if-else

让程序有选择的的执行,分支控制有三种

  • 单分支if

  • 双分支if-else

  • 多分支if-else if -....-else

3.2.1 单分支

if(条件表达式){
    执行代码块;
}

当条件表达式为true时,就会执行{}的代码。如果为false,就不执行。如果{}中只有一条语句,可以不用{},否则不能省略

3.2.2 双分支

if(条件表达式){
    执行代码块1;
} else{
    执行代码块2;
}

当条件表达式成立,即执行代码块1,否则执行代码块2.如果{}中只有一条语句,可以不用{},否则不能省略

3.2.3 嵌套分支

在一个分支结构中又完整的嵌套了另一个完整的分支结构,里面的分支的结构称为内层分支外面的分支结构称为外层分支。

if(条件表达式1){
    if (条件表达式2) {
        // if -else
    } else{
        // if -else
    }
}

3.3 switch 分支结构

switch(表达式){
    case 常量1:
        语句块1;
        break;
    case 常量2:
        语句块2;
        break;
    default:
        default语句块;
        break;
}
  • switch关键字,表示switch分支

  • 表达式对应一个值

  • 当表达式的值等于常量1,则执行语句块1

  • break表示退出switch

  • 如果case 常量1匹配,执行语句块1,否则继续匹配case 常量2

  • 如果一个都没有匹配上,执行default

  • 表达式的数据类型,应和case后的常量类型一致,或者是可以自动转成可以相互比较的类型

  • switch表达式的返回值必须是(byte, short, int, char, enum[枚举], String)

  • case子句中的值必须是常量,而不能是变量

  • default字句是可选的,没有匹配的case时,执行default

  • break语句用来执行一个case分支后使程序跳出switch语句块,如果没有写break,程序会顺序执行到switch结尾,除非遇到break

3.4 for 循环控制

for (循环变量初始化; 循环条件; 循环变量迭代){
    循环操作;
}
  1. for 关键字,表示循环控制

  2. for 有四要素: (1)循环变量初始化(2)循环条件(3)循环操作(4)循环变量迭代

  3. 循环操作, 这里可以有多条语句,也就是我们要循环执行的代码

  4. 如果循环操作(语句) 只有一条语句,可以省略{}, 建议不要省略

例如

for (int i = 1; i <= 10; i++){
    System.out.println(i);
}

1) 循环条件是返回一个布尔值的表达式 2) for(;循环判断条件;)中的初始化和变量迭代可以写到其它地方,但是两边的分号不能省略。 3) 循环初始值可以有多条初始化语句,但要求类型一样,并且中间用逗号隔开,循环变量迭代也可以有多条变量迭代 语句,中间用逗号隔开。

3.5 while 循环控制

while (循环条件){
    循环体;
    循环变量迭代;
}

1) 循环条件是返回一个布尔值的表达式 2) while 循环是先判断再执行语句

3.6 do..while 循环控制

循环变量初始化;
do{
    循环体(语句);
    循环变量迭代;
}while(循环条件);
  1. do while 是关键字

  2. 也有循环四要素, 只是位置不一样

  3. 先执行,再判断,也就是说,一定会至少执行一次

  4. 最后有一个分号;

3.7 跳转控制语句-break

break 语句用于终止某个语句块的执行,一般使用在switch 或者循环[for , while , do-while]中

  • break语句出现在多层嵌套的语句块中时,可以通过标签指明要中止的是那一层语句块

标签的基本使用:

label1: {   ......
    label2:{    ......
        label3:{
            ......
            break;
            ......
        }
    }
}

例如:

label1:
for (int j = 0; j < 4; j++){
    label2:
    for(int i = 0; i<10; i++){
        if (i == 2){
            break label1;
        }
    System.out.println("i=" + i);
    }
}
  • break 语句可以指定退出哪层

  • label1是标签,名字由程序员指定

  • break后指定到哪个label就退出到哪里

  • 如果没有指定break,默认退出最近的循环体

3.8 跳转控制语句-continue

  • continue 语句用于结束本次循环,继续执行下一次循环。

  • continue 语句出现在多层嵌套的循环语句体中时,可以通过标签指明要跳过的是哪一层循环, 这个和前面的标签的使用的规则一样.

3.9 跳转控制语句-return

return 使用在方法,表示跳出所在的方法

4 数组

4.1 数组介绍

数组可以存放多个同一类型的数据。数组也是一种数据类型,是引用类型。

public class Array01{
    public static void main(String[] args) {
        //1. double[] 表示是double 类型的数组, 数组名hens
        //2. {3, 5, 1, 3.4, 2, 50} 表示数组的值/元素,依次表示数组的第几个元素
        double[] hens = {3, 5, 1, 3.4, 2, 50, 7.8, 88.8,1.1,5.6,100};
        double totalWeight = 0;
        for( int i = 0; i < hens.length; i++) {
            //3. 我们可以通过hens[下标] 来访问数组的元素
            // 下标是从0 开始编号的比如第一个元素就是hens[0]
            totalWeight += hens[i];
        }
        System.out.println("总体重=" + totalWeight+ "平均体重=" + (totalWeight / hens.length) );
    }
}

4.2 数组的初始化

4.2.1 动态初始化

  • 先声明数组:语法:数据类型数组名[]; 也可以数据类型[] 数组名; 如int a[]; 或者int[] a;

  • 创建数组:语法: 数组名=new 数据类型[大小];如a=new int[10];

//(1) 第一种动态分配方式
double scores[] = new double[5];
//(2) 第2 种动态分配方式, 先声明数组,再new 分配空间
double scores[] ; //声明数组, 这时scores 是null
scores = new double[5]; // 分配内存空间,可以存放数据

4.2.2 静态初始化

//int[] arr1 = {1, 2, 3, 60,"hello"};//String ->int
double[] arr2 = {1.1, 2.2, 3.3, 60.6, 100};//int ->double

4.3 数组使用注意事项和细节

  • 数组是多个相同类型数据的组合,实现对这些数据的统一管理

  • 数组中的元素可以是任何数据类型,包括基本类型和引用类型,但是不能混用。

  • 数组创建后,如果没有赋值,有默认值 int 0,short 0, byte 0, long 0, float 0.0,double 0.0,char \u0000,boolean false,String null

  • 使用数组的步骤1. 声明数组并开辟空间2 给数组各个元素赋值3 使用数组

  • 数组的下标是从0 开始的。

  • 数组下标必须在指定范围内使用,否则报:下标越界异常

  • 数组属引用类型,数组型数据是对象(object)

4.4 数组赋值

1) 基本数据类型赋值,这个值就是具体的数据,而且相互不影响。int n1 = 2; int n2 = n1; 2) 数组在默认情况下是引用传递,赋的值是地址。

int[] arr1 = {1,2,3};
int[] arr2 = arr1;

4.5 数组拷贝

public static void main(String[] args) {
    int[] A = {1,2,3,4,5};
    int[] B = new int[A.length];
    // 1. for循环拷贝  (拷贝数值类型) ---深拷贝
    for (int i = 0; i < A.length; i++) {
        B[i] = A[i];
    }
    // 2. copyof / copyOfRange
    // Arrays.copy(原数组,自定义新数组长度);
    // Arrays.copyOfRange(原数组,from,to);
    // 注意拷贝截取的范围是左闭右开的[from,to)
    int[] A = {1,2,3,4,5};                  //A : [1, 2, 3, 4, 5]
    int[] B = Arrays.copyOf(A,A.length);    //B : [1, 2, 3, 4, 5]
    int[] C = Arrays.copyOfRange(A,1,3);    //C : [2, 3]
    // 3. arraycopy
    // System.arraycopy(源数组, 源数组要复制的起始位置 目标数组, 目标数组复制的起始位置, 复制的长度);
    int[] A = {1,2,3,4,5};
    int[] B = new int[A.length];
    System.arraycopy(A,1,B,2,2);            ////B : [0, 0, 2, 3, 0]
    // 4. clone
    int[] A = {1,2,3,4,5};
    int[] B = A.clone();
}

当数组中存放的元素为基本数据类型时,此时发生的是深拷贝;当数组中存放的元素为引用数据类型时,此时发生的是浅拷贝;

深拷贝:拷贝后,修改原数组,不会影响到新数组;

浅拷贝:拷贝后,修改原数组,新数组也会相应的发生改变;

4.6 二维数组

  1. 直接为每一维分配空间,格式如下:

type[][] typeName = new type[typeLength1][typeLength2];

type 可以为基本数据类型和复合数据类型,typeLength1 和 typeLength2 必须为正整数,typeLength1 为行数,typeLength2 为列数。

例如

int[][] a = new int[2][3];
  1. 从最高维开始,分别为每一维分配空间,例如

String[][] s = new String[2][];
s[0] = new String[2];
s[1] = new String[3];
s[0][0] = new String("Good");
s[0][1] = new String("Luck");
s[1][0] = new String("to");
s[1][1] = new String("you");
s[1][2] = new String("!");

对二维数组中的每个元素,引用方式为 arrayName[index1][index2],例如:

num[1][0];

4.7 Array类

java.util.Arrays 类能方便地操作数组,它提供的所有方法都是静态的。

  • 给数组赋值:通过 fill 方法。

  • 对数组排序:通过 sort 方法,按升序。

  • 比较数组:通过 equals 方法比较数组中元素值是否相等。

  • 查找数组元素:通过 binarySearch 方法能对排序好的数组进行二分查找法操作。

方法

说明

public static int binarySearch(Object[] a, Object key)

用二分查找算法在给定数组中搜索给定值的对象(Byte,Int,double等)。数组在调用前必须排序好的。如果查找值包含在数组中,则返回搜索键的索引;否则返回 (-(插入点) - 1)。

public static boolean equals(long[] a, long[] a2)

如果两个指定的 long 型数组彼此相等,则返回 true。如果两个数组包含相同数量的元素,并且两个数组中的所有相应元素对都是相等的,则认为这两个数组是相等的。换句话说,如果两个数组以相同顺序包含相同的元素,则两个数组是相等的。同样的方法适用于所有的其他基本数据类型(Byte,short,Int等)。

public static void fill(int[] a, int val)

将指定的 int 值分配给指定 int 型数组指定范围中的每个元素。同样的方法适用于所有的其他基本数据类型(Byte,short,Int等)。

public static void sort(Object[] a)

对指定对象数组根据其元素的自然顺序进行升序排列。同样的方法适用于所有的其他基本数据类型(Byte,short,Int等)。