Java基础
一、Java概述
程序:计算机执行某些操作或解决某个问题而编写的一系列有序指令的集合
Java技术体系平台
版本 | 描述 |
---|---|
Java SE(标准版) | 支持面向桌面机应用(如Windows下的应用程序)的Java平台,提供了完整的Java核心API |
Java EE(企业版) | 是开发企业环境下的应用程序提供的一套解决方案,该技术体系中包含的技术如Servlet、Jsp等 |
Java ME(小型版) | 支持Java程序运行在移动终端(手机、PDA)上的平台,对Java API有所精简,并加入了针对移动终端的支持 |
Java重要特点
1.Java语言是面向对象的(oop)
2.Java语言是健壮的,Java的强类型机制、异常处理、垃圾的自动收集等是Java程序健壮性的重要保证
3.Java语言是跨平台性的(即:一个编译好的.class文件可以在多个系统下运行,这种就是跨平台)
4.Java语言是解释型的
- 解释型语言:编译后的代码,不能直接被机器执行,需要解释器来执行
- 编译型语言:编译后的代码,可以直接被机器执行,C/C++
Java运行机制及运行过程
Java核心机制——Java虚拟机(JVM)
基本介绍
- JVM是一个虚拟的计算机,具有指令集并使用不同的存储区域,负责执行指令,管理数据、内存、寄存器,包含在JDK中
- 对于不同的平台,有不同的虚拟机
- Java虚拟机机制屏蔽了底层运行平台的差别,实现了"一次编译,到处运行"
编译和运行过程
编译:
javac Hello.java
- 有了java源文件,通过编译器将其编译成JVM可以识别的字节码文件
- 在该源文件目录下,通过javac编译工具对Hello.java文件进行编译
- 如果程序没有错误,没有任何提示,但在当前目录下会出现一个Hello.class文件,该文件称为字节码文件,也是可以执行的java的程序
运行:
- 有了可执行的java程序(Hello.class字节码文件)
- 通过运行工具java.exe对字节码文件进行执行,本质就是.class装载到jvm机执行
对修改后的Hello.java源文件需要重新编译,生成新的class文件后,再进行执行,才能生效
JDK和JRE
JDK基本介绍:
- JDK的全称为Java开发工具包,JDK=JRE+java的开发工具
- JDK是提供给Java开发人员使用的,其中包含了java的开发工具,也包括了JRE,所以安装了JDK就不用再单独安装JRE了
JRE基本介绍:
- JRE(Java运行环境),JRE=JVM+Java的核心类库
- 包括Java虚拟机和Java程序所需的核心类库等,如果想要运行一个开发好的Java程序,计算机中国只需要安装JRE即可
二、基础知识
Java开发注意事项和细节说明
1.Java源文件以.java为扩展名,源文件的基本组成部分是类(class)
2.Java应用程序的执行入口是main()方法,它有固定的书写格式:
public static void main(String[] args) {...}
3.Java语言严格区分大小写
4.Java方法由一条条语句构成,每个语句以";"结束
5.大括号是成对出现的,缺一不可(习惯先写{}再写代码)
6.一个源文件中最多只能有一个public类,其他类的个数不限
编译后每一个类都对于一个.class文件
7.如果源文件包含一个public类,则文件名必须按该类命名
8.一个源文件中最多只能有一个public类,其他类的个数不限,也可以将main方法写在非public类中,然后指定运行非public类,这样入口方法就是非public的main方法
第一个Java代码:
//1.public class Demo1表示Demo1是一个类,是一个public公有的类
//2.Hello{}表示一个类的开始和结束
//3.public static void main(String[] args) 表示一个主方法,即我们程序的入口
//4.main(){} 表示方法的开始和结束
public class Demo01 {
public static void main(String[] args)
{
System.out.println("hello world");
}
}
Java容易犯的错误
1.找不到文件
- 解决办法:源文件不存在或者写错,或者当前路径错误
2.主类名和文件名不一致
- 解决办法:声明为public的主类应与文件名一致,否则编译失败
3.缺少分号
4.常见错误总结
- 最易犯的错误是语法错误
Java常见转义字符
转义字符 | 说明 |
---|---|
\t | 一个制表位,实现对齐的功能 |
\n | 换行符 |
\ \ | 一个\ |
\ ‘’ | 一个" |
\ ’ | 一个’ |
\r | 一个回车 |
注释
注释就是用于说明解释程序的文字,注释提高了代码的阅读性(可读性),注释是程序员应该具有的良好编程习惯,将自己的思想通过注释先整理出来,再用代码去体现
单行注释
基本格式: //注释文字
多行注释
基本格式: /* 注释文字 */
多行注释里面不允许有多行注释嵌套
文档注释
注释内容可以被JDK提供的工具Javadoc所解析,生成一套以网页文件形式体现的该程序的说明文档,一般写在类
命令: javadoc -d 文件夹 -xx -yy javadoc.java
代码:
具体命令:
Java代码规范
1)类、方法的注释,要以javadoc的方法来写
2)非Java doc的注释,往往是给代码的维护者看的,着重告述 读者为什么这样写,如何修改,注意什么问题
3)运算符和 = 两边习惯性各加一个空格
4)源文件使用utf-8编码
5)行宽度不要超过80字符
6)代码编写次行风格和行尾风格
Java API文档
API(Application Programming Interface,应用程序编程接口)是Java提供的基本编程接口(Java提供的类还有相关的方法)
Java语言提供了大量的基础类,因此Oracle公司也为这些基础类提供了相应的API文档,用于告诉开发者如何使用这些类,以及这些类里包含的方法
Java类的组织形式:
常见Dos命令
相对路径:从当前目录开始定位,形成的一个路径
绝对路径:从根目录/顶级目录开始定位,形成的一个路径
命令 | 说明 |
---|---|
dir | 查看当前目录是有什么 |
cd /D | 切换到其他盘下 |
cd… | 切换到上一级 |
cd \ | 切换到根目录 |
tree | 查看指定的目录下所有的子级目录 |
cls | 清屏 |
exit | 退出dos |
md | 创建目录 |
rd | 删除目录 |
标识符的命名规则和规范
标识符概念
1)Java对各种变量、方法和类等命名时使用的字符序列称为标识符
2)凡是自己可以起名字的地方都叫标识符
标识符的命名规则
1)由26个英文字母大小写,0-9,_或$组成
2)数字不可以开头
3)不可以使用关键字和保留字,但能包含关键字和保留字
4)Java中严格区分大小写,长度无限制
5)标识符中不能包含空格
6)包名:多单词组成时所有字母都小写
7)类名、接口名:多单词组成时,所有单词的首字母大写
8)变量名、方法名:多单词组成时,第一个单词首字母小写,第二个单词开始每个单词首字母大写
9)常量名:所有字母都大写,多单词时每个单词用下划线连接
关键字
定义:被Java语言赋予了特殊含义,用做专门用途的字符串
特点:关键字中所有字母都为小写
保留字
Java保留字:现有Java版本尚未使用,但以后版本可能会作为关键字使用,自己命名标识符时要避免使用这些保留字
键盘输入语句
在编程时,需要接受用户输入的数据,就可以使用键盘输入语句来获取,Input.java,需要一个扫描器(对象),就是Scanner
步骤:
1)导入该类的所在包,java.util,*
2)创建该类对象(声明变量)
3)调用里面的功能
import java.util.Scanner;//表示把java.util 下的Scanner 类导入
public class Input {
//编写一个main 方法
public static void main(String[] args) {
//演示接受用户的输入
//步骤
//Scanner 类表示简单文本扫描器,在java.util 包
//1. 引入/导入Scanner 类所在的包
//2. 创建Scanner 对象, new 创建一个对象,体会
// myScanner 就是Scanner 类的对象
Scanner myScanner = new Scanner(System.in);
//3. 接收用户输入了, 使用相关的方法
System.out.println("请输入名字");
//当程序执行到next 方法时,会等待用户输入~~~
String name = myScanner.next(); //接收用户输入字符串
System.out.println("请输入年龄");
int age = myScanner.nextInt(); //接收用户输入int
System.out.println("请输入薪水");
double sal = myScanner.nextDouble(); //接收用户输入double
System.out.println("人的信息如下:");
System.out.println("名字=" + name
+ " 年龄=" + age + " 薪水=" + sal);
}
}
三、变量和数据类型
变量
变量是程序的基本组合单位
不论是使用哪种高级程序语言编写程序,变量都是其程序的基本组成单位
概念
变量相当于内存中一个数据存储空间的表示,可以把变量看做是一个房间的门牌号,通过门牌号我们可以找到房间,而通过变量名可以访问到变量值
变量使用步骤
1)声明变量:int a;
2)赋值:a = 60;
3)使用System.out.println(a);
也可以一步到位int a = 60;
使用注意事项
1)变量表示内存中的一个存储区域:不同的变量,类型不同,占用的空间大小不同
2)该区域有自己的名称(变量名)和类型(数据类型)
3)变量必须先声明,后使用,即有顺序
4)该区域的数据/值可以在同一类型范围内不断变化
5)变量在同一个作用域内不能重名
6)变量 = 变量名 + 数据类型
public class VarDetail {
//编写一个main 方法
public static void main(String[] args) {
//变量必须先声明,后使用, 即有顺序
int a = 50;//int
System.out.println(a);//50
//该区域的数据/值可以在同一类型范围内不断变化
//a = "jack"; //×
a = 88; //对
System.out.println(a);//88
//变量在同一个作用域内不能重名
//int a = 77;//错误
}
}
class Dog {
public static void main(String[] args) {
int a = 666;//对
}
}
程序中的+号使用
- 当左右两边都是数值型时,则做加法运算
- 当左右两边有一方为字符串,则做拼接运算
数据类型
每一种数据都定义了明确的数据类型,在内存中分配了不同大小的内存空间
-
Java数据类型分为两大类:基本数据类型和引用类型
-
基本数据类型有8种数值型(byte,short,int,long,float,double) char,boolean
-
引用类型:类,接口,数组
整数型
Java的整数类型就是用于存放整数值的
整型的使用细节:
1)java各整数类型有固定的范围和字段长度,不受具体OS的影响,以保证java程序的可移植性
2)Java的整型变量默认为int型,声明long型常量后需要加’l’或’L’
3)java程序中变量常声明为int型,除非不足以表示大数,才使用long
4)bit:计算机中的最小存储单位,byte计算机中的基本存储单元,1byte=8bit
浮点型
Java的浮点类型可以表示一个小数
说明:
- 关于浮点数在机器中存放形式的简单说明,浮点数=符号位+指数位+尾数位
- 尾数部分可以会丢失,造成精度损失(小数都是近似值)
浮点型使用细节:
1)与整数类型相似,Java浮点类型也有固定的范围和字段长度,不受具体的操作系统影响
2)Java的浮点型常量默认为double型,声明float常量,须后加"f"或"F"
3)浮点型常量有两种表示形式
- 十进制形式:5.12,512.0f,.512(必须有小数点)
- 科学计数法形式:5.12e3
4)通常情况下,应该使用double型,因为它比float型更加精确
5)通常不要对运算结果是小数的进行相等判断比较,应该是以两个数的差值的绝对值在某个精度范围内判断
public class FloatDetail {
//编写一个main 方法
public static void main(String[] args) {
//Java 的浮点型常量(具体值)默认为double 型,声明float 型常量,须后加‘f’或‘F'
//float num1 = 1.1; //对不对?错误
float num2 = 1.1F; //对的
double num3 = 1.1; //对
double num4 = 1.1f; //对
//十进制数形式:如:5.12 512.0f .512 (必须有小数点)
double num5 = .123; //等价0.123
System.out.println(num5);
//科学计数法形式:如:5.12e2 [5.12 * 10 的2 次方] 5.12E-2 []
System.out.println(5.12e2);//512.0
System.out.println(5.12E-2);//0.0512
//通常情况下,应该使用double 型,因为它比float 型更精确。
//[举例说明]double num9 = 2.1234567851;float num10 = 2.1234567851F;
double num9 = 2.1234567851;
float num10 = 2.1234567851F;
System.out.println(num9);
System.out.println(num10);
//浮点数使用陷阱: 2.7 和8.1 / 3 比较
//看看一段代码
double num11 = 2.7;
double num12 = 2.7; //8.1 / 3; //2.7
System.out.println(num11);//2.7
System.out.println(num12);//接近2.7 的一个小数,而不是2.7
//得到一个重要的使用点: 当我们对运算结果是小数的进行相等判断是,要小心
//应该是以两个数的差值的绝对值,在某个精度范围类判断
if( num11 == num12) {
System.out.println("num11 == num12 相等");
}
//正确的写法, ctrl + / 注释快捷键, 再次输入就取消注释
if(Math.abs(num11 - num12) < 0.000001 ) {
System.out.println("差值非常小,到我的规定精度,认为相等...");
}
// 可以通过java API
System.out.println(Math.abs(num11 - num12));
//细节:如果是直接查询得的的小数或者直接赋值,是可以判断相等
}
}
字符型
基本介绍
字符类型可以表示单个字符,字符类型是char,char是两个字节(可以存放汉字),多个字符我们用字符串String
字符类型使用细节
1)字符常量是用单引号(’ ')括起来的单个字符,双引号引起来的是字符串
2)java中还允许使用转义字符’\ '来将其后的字符转变为特殊字型常量
3)在Java中,char的本质是一个整数,在输出时,是unicode码对应的字符
4)可以直接给char赋一个整数,然后输出时,会按照对应的unicode字符输出
5)char类型是可以进行运算的,相当于一个整数,因为它都对应有Unicode码
字符类型本质
1)字符型存储在计算机中,需要将字符对应的码值(整数)找出来
2)字符和码值的对应关系是通过字符编码表决定的
字符编码表
- ASCII:ASCII编码表 一个字节表示,一个128个字符,实际上一个字节可以表示256个字符,只用128个
- Unicode:Unicode编码表 固定大小的编码,使用两个字节来表示字符,字母和汉字统一都占用两个字节,这样浪费空间
- Utf-8:编码表,大小可变的编码,字母使用一个字节,汉字使用3个字节
- GBK:可以表示汉字,而且范围广,字母使用一个字节,汉字2个字节
布尔类型
基本介绍:
1)布尔类型也叫boolean类型,boolean类型数据只允许取值true和false,无null
2)boolean类型占1个字节
3)boolean类型适用于逻辑运算,一般用于程序流程控制
注意:不可以0或非0的整数代替false和true,这点和C语言不同
基本数据类型转换
自动类型转换
注意事项:
1)有多种类型的数据混合运算时,系统首先自动将所有数据转换成容量最大的那种数据类型,然后再进行计算
2)当我们把精度(容量)大的数据类型赋值给精度(容量)小的数据类型时,就会报错,反之就会进行自动类型转换
3)(byte,short)和char之间不会相互自动转换
4)byte,short,char他们三者之间可以计算,在计算时首先转换为int类型
5)boolean不参与转换
6)自动提升原则:表达式的结果的类型自动提升为操作数中最大的类型
//自动类型转换细节
public class AutoConvertDetail {
//编写一个main 方法
public static void main(String[] args) {
//细节1: 有多种类型的数据混合运算时,
//系统首先自动将所有数据转换成容量最大的那种数据类型,然后再进行计算
int n1 = 10; //ok
//float d1 = n1 + 1.1;//错误n1 + 1.1 => 结果类型是double
//double d1 = n1 + 1.1;//对n1 + 1.1 => 结果类型是double
float d1 = n1 + 1.1F;//对n1 + 1.1 => 结果类型是float
//细节2: 当我们把精度(容量)大的数据类型赋值给精度(容量)小的数据类型时,
//就会报错,反之就会进行自动类型转换。
//
//int n2 = 1.1;//错误double -> int
//细节3: (byte, short) 和char 之间不会相互自动转换
//当把具体数赋给byte 时,(1)先判断该数是否在byte 范围内,如果是就可以
byte b1 = 10; //对, -128-127
// int n2 = 1; //n2 是int
// byte b2 = n2; //错误,原因: 如果是变量赋值,判断类型
//
// char c1 = b1; //错误, 原因byte 不能自动转成char
//
//
//细节4: byte,short,char 他们三者可以计算,在计算时首先转换为int 类型
byte b2 = 1;
byte b3 = 2;
short s1 = 1;
//short s2 = b2 + s1;//错, b2 + s1 => int
int s2 = b2 + s1;//对, b2 + s1 => int
//byte b4 = b2 + b3; //错误: b2 + b3 => int
//
//boolean 不参与转换
boolean pass = true;
//int num100 = pass;// boolean 不参与类型的自动转换
//自动提升原则: 表达式结果的类型自动提升为操作数中最大的类型
//看一道题
byte b4 = 1;
short s3 = 100;
int num200 = 1;
float num300 = 1.1F;
double num500 = b4 + s3 + num200 + num300; //float -> double
}
}
强制类型转换
基本介绍:
自动类型转换的逆过程,将容量大的数据类型转换为容量小的数据类型,使用时要加上强制转换符(),但可能造成精度降低或溢出,需要注意
注意细节:
1)当进行数据的大小从大—>小,就需要使用强制转换
2)强转符号只针对于最近的操作数有效,往往会使用小括号提升优先级
3)char类型可以保存int的常量值,但不能保存int的变量值,需要强转
4)byte和short类型在进行运算时,当做int类型处理
public class ForceConvertDetail {
//编写一个main 方法
public static void main(String[] args) {
//演示强制类型转换
//强转符号只针对于最近的操作数有效,往往会使用小括号提升优先级
//int x = (int)10*3.5+6*1.5;//编译错误: double -> int
int x = (int)(10*3.5+6*1.5);// (int)44.0 -> 44
System.out.println(x);//44
char c1 = 100; //ok
int m = 100; //ok
//char c2 = m; //错误
char c3 = (char)m; //ok
System.out.println(c3);//100 对应的字符, d 字符
}
}
基本数据类型和String类型的转换
-
基本类型转String类型
- 语法:将基本类型的值+""即可
-
String转基本类型
- 语法:通过基本类型的包装类调用parseXX方法即可
注意事项:
在将String类型转换成基本数据类型时,要确保String类型能够转成有效的数据,比如:我们可以把"123"转成一个整数,但不能把"hello"转成一个整数,如果格式不正确,就会抛出异常,程序就会终止
public class StringToBasic {
//编写一个main 方法
public static void main(String[] args) {
//基本数据类型->String
int n1 = 100;
float f1 = 1.1F;
double d1 = 4.5;
boolean b1 = true;
String s1 = n1 + "";
String s2 = f1 + "";
String s3 = d1 + "";
String s4 = b1 + "";
System.out.println(s1 + " " + s2 + " " + s3 + " " + s4);
//String->对应的基本数据类型
String s5 = "123";
//会在OOP 讲对象和方法的时候回详细
//解读使用基本数据类型对应的包装类,的相应方法,得到基本数据类型
int num1 = Integer.parseInt(s5);
double num2 = Double.parseDouble(s5);
float num3 = Float.parseFloat(s5);
long num4 = Long.parseLong(s5);
byte num5 = Byte.parseByte(s5);
boolean b = Boolean.parseBoolean("true");
short num6 = Short.parseShort(s5);
System.out.println("===================");
System.out.println(num1);//123
System.out.println(num2);//123.0
System.out.println(num3);//123.0
System.out.println(num4);//123
System.out.println(num5);//123
System.out.println(num6);//123
System.out.println(b);//true
//怎么把字符串转成字符char -> 含义是指把字符串的第一个字符得到
//解读s5.charAt(0) 得到s5 字符串的第一个字符'1'
System.out.println(s5.charAt(0));
}
}
四、运算符
运算符介绍
运算符是一种特殊的符号,用以表示数据的运算、赋值和比较等
- 算术运算符
- 赋值运算符
- 关系运算符
- 逻辑运算符
- 位运算符
- 三元运算符
算术运算符
注意事项:
- 对于除号"/",它的整数除和小数除是有区别的:整数之间做除法时,只保留整数部分而舍弃小数部分
- 当对一个数取模时,可以等价为a%b = a-a/b*b,这样就可以看到取模的一个本质运算
/**
* 演示算术运算符的使用
*/
public class ArithmeticOperator {
//编写一个main 方法
public static void main(String[] args) {
// /使用
System.out.println(10 / 4); //从数学来看是2.5, java 中2
System.out.println(10.0 / 4); //java 是2.5
// 注释快捷键ctrl + /, 再次输入ctrl + / 取消注释
double d = 10 / 4;//java 中10 / 4 = 2, 2=>2.0
System.out.println(d);// 是2.0
// % 取模,取余
// 在% 的本质看一个公式!!!! a % b = a - a / b * b
// -10 % 3 => -10 - (-10) / 3 * 3 = -10 + 9 = -1
// 10 % -3 = 10 - 10 / (-3) * (-3) = 10 - 9 = 1
// -10 % -3 = (-10) - (-10) / (-3) * (-3) = -10 + 9 = -1
System.out.println(10 % 3); //1
System.out.println(-10 % 3); // -1
System.out.println(10 % -3); //1
System.out.println(-10 % -3);//-1
//++的使用
//
int i = 10;
i++;//自增等价于i = i + 1; => i = 11
++i;//自增等价于i = i + 1; => i = 12
System.out.println("i=" + i);//12
/*
作为表达式使用
前++:++i 先自增后赋值
后++:i++先赋值后自增
*/
int j = 8;
//int k = ++j; //等价j=j+1;k=j;
int k = j++; // 等价k =j;j=j+1;
System.out.println("k=" + k + "j=" + j);//8 9
}
}
关系运算符
关系运算符的结果都是boolean型,也就是要么是true,要么是false
关系表达式经常用在if结构的条件或循环结构的条件中
注意事项:
- 关系运算符的结果都是boolean型,也就是要么是true,要么是false
- 关系运算符组成的表达式,我们称为关系表达式
- 比较运算符"==“不能误写成”="
逻辑运算符
用于连接多个条件(多个关系表达式),最终的结果也是一个boolean值
1)短路与 && ,短路或||,取反!
2)逻辑与&,逻辑或|,逻辑异或^
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
&&和&
短路与&& :条件1&&条件2:两个条件都为true,结果为true,否则false
逻辑与& :条件1&条件2:两个条件都为true,结果为true,否则false
1)&&短路与:如果第一个条件为false,则第二个条件不会判断,最终结果为false,效率高
2)& 逻辑与:不管第一个条件是否为false,第二个条件都要判断,效率低
一般使用&&
||和|
短路或||:条件1||条件2:两个条件中只要有一个成立,结果为true,否则为false
|逻辑或:条件1|条件2:只要有一个条件成立,结果为true,否则为false
1)||短路或:如果第一个条件为true,则第二个条件不会判断,最终结果为true,效率高
2)| 逻辑或:不管第一个条件是否为true,第二个条件都要判断,效率低
一般使用||
!取反
! 非(取反):!条件:如果条件本身成立,结果为false,否则为true
^逻辑异或
a^b: 叫逻辑异或,当a 和b 不同时,则结果为true, 否则为false
赋值运算符
赋值运算符就是将某个运算后的值,赋给指定的变量
分类:
- 基本赋值运算符:=
- 复合赋值运算符:+=,-=,*=,/=,%=
特点:
1)运算顺序从右往左
2)赋值运算符的左边只能是变量,右边可以是变量、表达式、常量值
3)复合赋值运算符会进行类型转换
byte b = 3;
b += 2; // 等价b = (byte)(b + 2);
b++; // b = (byte)(b+1);
三元运算符
基本语法:
条件表达式?表达式1:表达式2;
运算规则:
1)如果条件表达式为true,运算后的结果是表达式1;
2)如果条件表达式为false,运算后的结果是表达式2;
运算符优先级
运算符有不同的优先级,所谓优先级就是表达式运算中的运算顺序,只有单目运算符、赋值运算符是从右向左的
位运算符
原码、反码、补码
位运算符:
符号 | 说明 |
---|---|
按位与& | 两位全为1,结果为1,否则为0 |
按位或| | 两位有一个为1,结果为1,否则为0 |
按位异或^ | 两位一个为0,一个为1,结果为1,否则为0 |
按位取反~ | 0->1,1->0 |
算术右移>> | 低位溢出,符号位不变,并用符号位补溢出的高位 |
算术左移<< | 符号位不变,低位补0 |
逻辑右移>>> | 低位溢出,高位补0 |
无<<<符号
五、程序控制结构
在程序中,程序运行的流程控制决定程序是如何执行的,主要有三大流程控制语句:
- 顺序控制
- 分支控制
- 循环控制
顺序控制
分支控制
if-else结构
让程序有选择的执行,分支控制有三种:
- 单分支:if
- 双分支if-else
- 多分支 if-else if-…-else
单分支
基本语法:
if(条件表达式){
执行代码块;
}
当条件表达式为true时,就会执行{}的代码,如果为false,就不执行
双分支
基本语法:
if(条件表示式){
执行代码块;
}else{
执行代码块;
}
当条件表达式成立,即执行代码块1,否则执行代码块2,如果执行代码块只有一条语句,则{}可以省略,否则,不能省略
多分支
基本语法:
if(条件表示式1){
执行代码块1;
}else if(条件表达式2){
执行代码块2;
}
......
else{
执行代码块n;
}
多分支可以没有else,如果所有的条件表达式都不成立,则一个执行入口都没有
如果有else,如果所有的条件表达式都不成立,则默认执行else代码块
嵌套分支
基本介绍:在一个分支结构中又完整的嵌套了另一个完整的分支结构,里面的分支的结构称为内层分支外面的分支结构称为外层分支
基本语法:
if(){
if(){
//if-else...
}else{
//if-else...
}
}
switch分支结构
基本语法:
注意事项:
1)表达式数据类型,应和case后的常量类型一致,或者是可以自动转成可以相互比较的类型,比如输入的是字符,而常量是int
2)switch(表达式)中表达式的返回值必须是:(byte,short,int,char,enum[枚举],String)
3)case子句中的值必须是常量而不是变量
4)default子句是可选的,当没有匹配的case时,执行default
5)break语句用来在执行完一个case分支后使程序跳出switch语句块,如果没有写break,程序会顺序执行到switch结尾,除非遇到break
switch和if的比较
1)如果判断的具体数值不多,而且符合byte、short 、int、char, enum[枚举], String 这6 种类型。虽然两个语句都可以使用,建议使用swtich 语句。
2)其他情况:对区间判断,对结果为boolean 类型判断,使用if,if 的使用范围更广
循环控制
for循环控制
基本语法:
for(循环变量初始化;循环条件;循环变量迭代){
循环操作;
}
说明:
- for关键字,表示循环控制
- for有四要素:循环变量初始化,循环条件,循环操作,循环变量迭代
- 循环操作,这里可以有多条语句,也就是我们要循环执行的代码
- 如果循环操作(语句)只要一条语句,可以省略{},建议不要省略
注意事项:
1)循环条件是返回一个布尔值的表达式
2)for(;循环判断条件;)中的初始化和变量迭代可以写到其他地方,但是两边的分号不能省略
3)循环初始值可以有多条初始化语句,但要求类型一样,并且中间用逗号隔开,循环变量迭代也可以有多条变量迭代语句,中间用逗号隔开
while循环
基本语法:
循环变量初始化;
while(循环条件){
循环体;
循环变量迭代;
}
流程结构:
注意事项:
1)循环条件是返回一个布尔值的表达式
2)while循环是先判断再执行语句
do while循环
基本语法:
循环变量初始化;
do{
循环体(语句);
循环变量迭代;
}while(循环条件);
说明:
1)do while是关键字
2)也有循环四要素,只是位置不一样
3)先执行,再判断,也就是说,一定会至少执行一次
4)最后有一个分号;
流程结构:
注意事项:
1)循环条件是返回一个布尔值的表达式
2)do…while循环是先执行,再判断,因此它至少执行一次
多重循环控制
1)将一个循环放在另一个循环体内,就形成了嵌套循环。其中,for ,while ,do…while 均可以作为外层循环和内层循环。
2)实质上,嵌套循环就是把内层循环当成外层循环的循环体。当只有内层循环的循环条件为false 时,才会完全跳出内层循环,才可结束外层的当次循环,开始下一次的循环
3)设外层循环次数为m 次,内层为n 次,则内层循环体实际上需要执行m*n 次
for(int i = 1;i<=7;i++){
for(int j = 1;j<=2;j++){
System.out.println("ok");
}
}
执行步骤分析:
for(int i = 0; i < 2; i++) { //先思考
for( int j = 0; j < 3; j++) {
System.out.println("i=" + i + j=" + j);
}
}
break,continue,return
break
基本介绍:
break语句用于终止某个语句块的执行,一般使用在switch或循环中
基本语法:
{
....
break;
....
}
流程结构:
注意事项:
continue
基本介绍:
1)continue 语句用于结束本次循环,继续执行下一次循环。
2)continue 语句出现在多层嵌套的循环语句体中时,可以通过标签指明要跳过的是哪一层循环, 这个和前面的标签的使用的规则一样
流程结构:
return
基本介绍:
return使用在方法,表示跳出所在的方法,注意:如果return写在main方法,则退出程序
六、数组
一维数组
数组可以存放多个同一类型的数据。数组也是一种数据类型,是引用类型。
即:数(数据)组(一组)就是一组数据
数组的使用
方式一:
方式二:
方式三:
import java.util.Scanner;
public class Array02 {
//编写一个main 方法
public static void main(String[] args) {
//演示数据类型数组名[]=new 数据类型[大小]
//循环输入5 个成绩,保存到double 数组,并输出
//步骤
//1. 创建一个double 数组,大小5
//(1) 第一种动态分配方式
//double scores[] = new double[5];
//(2) 第2 种动态分配方式, 先声明数组,再new 分配空间
double scores[] ; //声明数组, 这时scores 是null
scores = new double[5]; // 分配内存空间,可以存放数据
//2. 循环输入
// scores.length 表示数组的大小/长度
//
Scanner myScanner = new Scanner(System.in);
for( int i = 0; i < scores.length; i++) {
System.out.println("请输入第"+ (i+1) +"个元素的值");
scores[i] = myScanner.nextDouble();
}
//输出,遍历数组
System.out.println("==数组的元素/值的情况如下:===");
for( int i = 0; i < scores.length; i++) {
System.out.println("第"+ (i+1) +"个元素的值=" + scores[i]);
}
}
}
注意事项:
-
数组是多个相同类型数据的组合,实现对这些数据的统一管理
-
数组中的元素可以是任何数据类型,包括基本类型和引用类型,但是不能混用
-
数组创建后,如果没有赋值,有默认值
- int 0,short 0, byte 0, long 0, float 0.0,double 0.0,char \u0000,boolean false,String null
-
使用数组的步骤
- 声明数组并开辟空间
- 给数组各个元素赋值
- 使用数组
-
数组的下标是从0开始的
-
数组下标必须在指定范围内使用,否则报:下标越界异常
-
数组属于引用类型,数组型数据是对象
数组赋值
1)基本数据类型赋值,这个值就是具体的数据,而且相互不影响。
int n1 = 2; int n2 = n1;
2)数组在默认情况下是引用传递,赋的值是地址。
具体分析:
//基本数据类型赋值,赋值方式为值拷贝
//n2的变化不会影响n1的值
int n1 = 10;
int n2 = n1;
n2 = 80;
System.out.println("n1=" + n1);//10
System.out.println("n2=" + n2);//80
//数组在默认情况下是引用传递,赋的值是地址,赋值方式为引用
//是一个地址,arr2变化会影响到arr1
int[] arr1 = {1,2,3};
int[] arr2 = arr1; //把arr1赋给arr2
arr2[0] = 10;
二维数组
public class TwoDimensionalArray01 {
//编写一个main 方法
public static void main(String[] args) {
/*
请用二维数组输出如下图形
0 0 0 0 0 0
0 0 1 0 0 0
0 2 0 3 0 0
0 0 0 0 0 0
*/
//什么是二维数组:
//1. 从定义形式上看int[][]
//2. 可以这样理解,原来的一维数组的每个元素是一维数组, 就构成二维数组
int[][] arr = { {0, 0, 0, 0, 0, 0},
{0, 0, 1, 0, 0, 0},
{0,2, 0, 3, 0, 0},
{0, 0, 0, 0, 0, 0} };
//关于二维数组的关键概念
//(1)
System.out.println("二维数组的元素个数=" + arr.length);
//(2) 二维数组的每个元素是一维数组, 所以如果需要得到每个一维数组的值
// 还需要再次遍历
//(3) 如果我们要访问第(i+1)个一维数组的第j+1 个值arr[i][j];
// 举例访问3, =》他是第3 个一维数组的第4 个值arr[2][3]
System.out.println("第3 个一维数组的第4 个值=" + arr[2][3]); //3
//输出二维图形
for(int i = 0; i < arr.length; i++) {//遍历二维数组的每个元素
//遍历二维数组的每个元素(数组)
//老韩解读
//1. arr[i] 表示二维数组的第i+1 个元素比如arr[0]:二维数组的第一个元素
//2. arr[i].length 得到对应的每个一维数组的长度
for(int j = 0; j < arr[i].length; j++) {
System.out.print(arr[i][j] + " "); //输出了一维数组
}
System.out.println();//换行
}
}
}
二维数组的使用
方式一:动态初始化
语法: 类型[][] 数组名 = new 类型[大小][大小]
比如:int a[][] = new int[2][3];
方式二:动态初始化
1)先声明:类型数组名[][];
2)再定义(开辟空间) 数组名= new 类型[大小] [大小]
3)赋值(有默认值,比如int 类型的就是0)
方式三:列数不确定
public class TwoDimensionalArray03 {
//编写一个main 方法
public static void main(String[] args) {
/*
看一个需求:动态创建下面二维数组,并输出
i = 0: 1
i = 1: 2 2
i = 2: 3 3 3
一个有三个一维数组, 每个一维数组的元素是不一样的
*/
//创建二维数组,一个有3 个一维数组,但是每个一维数组还没有开数据空间
int[][] arr = new int[3][];
for(int i = 0; i < arr.length; i++) {//遍历arr 每个一维数组
//给每个一维数组开空间new
//如果没有给一维数组new ,那么arr[i]就是null
arr[i] = new int[i + 1];
//遍历一维数组,并给一维数组的每个元素赋值
for(int j = 0; j < arr[i].length; j++) {
arr[i][j] = i + 1;//赋值
}
}
System.out.println("=====arr 元素=====");
//遍历arr 输出
for(int i = 0; i < arr.length; i++) {
//输出arr 的每个一维数组
for(int j = 0; j < arr[i].length; j++) {
System.out.print(arr[i][j] + " ");
}
System.out.println();//换行
}
}
}
方式四:静态初始化
定义类型数组名[][] = {{值1,值2…},{值1,值2…},{值1,值2…}}
使用即可[ 固定方式访问]
注意事项:
1)一维数组的声明方式有:int[] x 或者int x[]
2)二维数组的声明方式有:int[] [] y 或者 int[] y[] 或者int y[] []
3)二维数组实际上是由多个一维数组组成的,它的各个一维数组的长度可以相同,也可以不相同
int map [][] = {{1,2},{3,4,5}}
由map[0] 是一个含有两个元素的一维数组,map[1] 是一个含有三个元素的一维数组构成,我们也称为列数不等的二维数组