JDK8
复习用
Java前置知识
- JavaSE
Java Standard Edition 标准版
支持面向桌面级应用(如Windows下的应用程序)的 Java平台,提供了完整的Java核心API
此版本以前称为 J2SE
- JavaEE
Java Enterprise Edition 企业版
一套用于企业环境下的应用程序的应用方案(包含:Servlet、Jsp),主要针对 Web应用程序的开发
此版本以前称为 J2EE
- JavaME
Java Micro Edition 小型版
支持 Java程序 运行在移动端的版本,对 JavaAPI 有所精简,并且加入了针对移动端的支持
此版本以前称为 J2ME
- JDK
Java Development Kit Java开发工具包
JDK = JRE + Java开发工具(java、javac、javap、javadoc等)
- JRE
Java Runtime Environment Java运行环境
JRE = JVM + Java核心类库
- JVM
Java Virtual Machine Java虚拟机
JVM 是一个虚拟的计算机,具有指令集并使用不同的存储区域,负责执行指令,管理数据、内存、寄存器
对于不同的平台有不同的虚拟机,屏蔽了底层运行平台的差别,实现了“一次编译,到处运行”
- Java运行简单的大致流程
Java文件 通过 javac 编译为 Class文件,再通过 java指令 交给 JVM虚拟机 执行
- Java中特殊的转义字符
\r : 光标定位到行首- public class Main {
- public static void main(String[] args) {
- System.out.println("aaaaaaa\rbb");
- }
- }
复制代码
- 在 IDEA 中 会清空这一行并把光标放到这一行的首位
上方代码在IDEA中输出:bb
- 在 windows终端 中,只会帮光标定位到该行的行首
上方代码在Windows终端中输出:bbaaaaa
- Java程序 中 + 号的使用
- 当 + 号 的 左边和右边 都是数值型时,视为加法运算
- 当 + 号 的 左边和右边 有一方是字符串时,视为拼接运算
- 运算顺序:从左往右
- System.out.println(100 + 98); // 输出: 198
- System.out.println("100" + 98); // 输出:10098
- System.out.println(100 + 3 + "hello"); // 输出:103hello
- System.out.printIn("hello" + 100 + 3); // 输出:hello1003
复制代码
- 当 + 号 的 左边和右边 有一方是char字符时,视为字符编码值的运算
由于 Java 中 char 底层存储的是 对应字符的Unicode码值,打印时会对照Unicode表打印出对应的字符
因此,对char字符的运算相当于对char字符对应的Unicode码值进行运算
但当有一方是字符串时,仍然视为拼接运算- System.out.println(1 + 'a'); // 98
- System.out.println('a' + 1); // 98
- System.out.println('a' + 'b'); // 195 (97+98=195)
- System.out.println('a' + "bc"); // abc
复制代码
- JavaAPI
- API : Application Programming Interface 应用程序编程接口
- JavaAPI : Java提供的基本编程接口
- JavaAPI文档 : Java语言提供了大量的基础类,Oracle公司也为这些基础类提供了相应的AP文档用于告诉开发者如何使用这些类,以及这些类里包含的方法
- switch语句 中表达式的值,必须是:byte、short、int、char、这4个基本数据类型的包装类对象、String对象、枚举对象
Java变量
不论使用哪种高级程序语言编写程序,变量都是程序的基本组成单位
- 变量三要素:
类型、名称、值
- 变量相当于内存中一个存储空间的表示,即 声明变量时就是先开辟了一定空间的空房间,变量相当于门牌号,通过 门牌号 可以找到目标房间,从而放入、取出房间中的填充物(也就是变量值),一个房间是有最大容量限制的,超过这个容量就会导致溢出
- 变量类型的不同,其占用内存空间的大小也不同
- 此区域有自己的变量名、数据类型,且可以在同一类型内不断变化
- 变量必须先声明后使用
- 变量在同一个作用域内,不能重名
- 数据类型
- 基本数据类型
- 数值型
- 整数类型
- byte : 1个字节
- short : 2个字节
- int : 4个字节
- long : 8个字节
- 浮点数类型
- float : 4个字节
- double : 8个字节
浮点数计算陷阱:
2.7 和 8.1/3 的值在计算机中会不相等
因为在二进制方面 8.1/3 是无限小数,double的精度太低,导致在内存中存储的 2.7 和 8.1/3 的值在二进制层面不相等
- 字符型
- char : 2个字节(Java中可以使用2个char来表示1个字符,用于弥补单个char存储空间小的限制)
- 布尔型
- 引用数据类型
flowchart RL byte([byte 1字节]) short([short 2字节]) int([int 4字节]) long([long 8字节]) float([float 4字节]) double([double 8字节]) char([char 2字节]) boolean([boolean 1字节]) CLASS([类 class]) interface([接口 interface]) array([数组 arrary]) NUMBER([数值型]) CHARACTER([字符型]) BOOLEAN([布尔型]) BASIC([基本数据类型]) REFERENCE([引用数据类型]) Java([Java数据类型]) byte --> short --> int --> long --> NUMBER float --> double --> NUMBER char --> CHARACTER boolean --> BOOLEAN NUMBER --> BASIC CHARACTER --> BASIC BOOLEAN --> BASIC BASIC --> Java CLASS --> REFERENCE interface --> REFERENCE array --> REFERENCE REFERENCE --> Java
- 字符类型
- 字符类型(char)可以表示单个字符,占用两个字节(可以存放汉字),多个字符使用字符串(String类)
- String类底层仍然是多个char
- Java中的char本质存储的是Unicode表中,对应字符的整数码值,因此一些特殊符号(\n、\t)也可以赋值给char,使对应的char在打印时具备对应特殊符号的功能
- 布尔类型
- 布尔类型也叫boolean类型,booolean类型数据只允许取值true和false,不允许赋予null值
- boolean类型占1个字节
- boolean类型适于逻辑运算(if、while、do-while、for等)
- 基本数据类型的相互转换
- 自动类型转换
当java程序在进行赋值或者运算时,精度小的类型自动转换为精度大的数据类型,这个就是自动类型转换
flowchart LR byte --> short --> int char --> int int --> long --> float --> double
- 注意事项
- 有多种类型的数据混合运算时,系统首先自动将所有数据转换成容量最大的那种数据类型,然后再进行计算
- 当我们把精度(容量)大的数据类型赋值给精度(容量)小的数据类型时,就会报错,反之就会进行自动类型转换
- (byte,short)和char之间不会相互自动转换
flowchart LR byte & short x--无法自动转换---x char
- byte、short、char他们三者可以计算,在计算时首先转换为int类型
- boolean不参与转换
- 自动提升原则:表达式结果的类型自动提升为操作数中最大的类型
- 强制类型转换
自动类型转换的逆过程,将容量大的数据类型转换为容量小的数据类型
使用时要加上强制转换符(),但可能造成精度降低或溢出,格外要注意
- 数据类型从大—>小(或多态的向下转型)时,就需要使用到强制转换
- 强转符号只针对于最近的操作数有效,实际中经常会使用小括号提升优先级
- char类型可以保存int的常量值,但不能保存int的变量值,需要强转
- char c1 = 100; //ok
- int m = 100; //ok
- char c2 = m; //错误
- char c3 = (char)mi; //ok
- System.out.printIn(c3):/100对应的字符
复制代码 - byte、short、char类型在进行运算时,会被当做int类型处理
- 易错题
- short s = 12; //ok
- s = s - 9; // 错误 int -> short
- byte b = 10;//ok
- b = b + 11; // 错误 int -> byte
- b = (byte)(b+11); //正确,使用了强转
- char c = 'a'; // ok
- int i = 16; // ok
- float d = .314F; // ok
- double result = c i d; // ok float -> double
- byte b = 16;// ok
- short s = 14;// ok
- short t = s + b; // 错误 int -> short
复制代码
- 基本数据类型 和 String类 的转换
- 转 String类
- int aInt = 1;
- String aStr = 1 + "";
复制代码 - 转 基本数据类型
- String aStr = "1";
- int aInt = Integer.parseInt(aStr);
复制代码 - String类 转 char
String类底层维护的就是char数组,因此只需要取出数组中的某个索引位置的值即可
- String str = "Hello world!";
- char e = str.charAt(1); // 数组索引下标从0开始
复制代码 - 注意事项
- 在将String类型转成基本数据类型时,要确保String类型能够转成有效的数据
比如我们可以把"123",转成一个整数,但是不能把"hello"转成一个整数
- 若String类无法转换为数值基本类型,会抛出异常:java.lang.NumberFormatException
- String类 转 boolean 时,除了字符串为true时,得到true的boolean值,其他情况均会得到false的boolean值
- String str1 = "Hello world!";
- boolean b1 = Boolean.parseBoolean(str1);
- System.out.println(b1); // 输出 : false
- String str2 = null;
- boolean b2 = Boolean.parseBoolean(str2);
- System.out.println(b2); // 输出 : false
复制代码
Java运算符
- 运算符是一种特殊的符号,用以表示数据的运算、赋值和比较等
Java中存在的运算符:算术运算符、关系运算符 [比较运算符]、逻辑运算符、位运算符、赋值运算符、三元运算符
- 测试算术运算符
运算符运算范例结果+正号+ 77-负号- 7-7+加号9 + 918-减号9 - 90*乘号9 * 981/除号(保留整数部分)10 / 33%取模(保留小数部分)10 % 31++自增(前):先运算后取值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;+字符串相加(拼接)"hello" + "world""helloworld"
- 注意:
- 取模 的 本质: a % b = a - a / b * b
- 自增、自减 在前在后 的简化理解:看作一个整体
例如下面的例子
- 将 x++ 看作一个整体,因为自增在后,所以此时 x++ 整体的值为 5 ,x 的值为6
- 将 ++y 看作一个整体,因为自增在前,所以此时 ++y 整体的值为6,y 的值为6
- int x = 5;
- int y = 5;
- if (x++==6 & ++y==6){ // F & T -> F
- x=11;
- }
- System.out.print("x -> " + x + "\t"); // 6
- System.out.println("y -> " + y); // 6
复制代码
- 关系运算符(比较运算符)
关系运算符的 结果 都是 boolean类型,即 都是 true 或 false
常用于 条件判断 中
运算符运算范例结果==相等于8 == 7fasle!=不等于8 != 7true</tdtd 小于/tdtd 8 < 7/tdtd false/td/trtrtd >大于8 > 7true= 7trueinstanceof检查左边(对象)是否右边(类)相等 或 子类关系"hello world" instanceof Stringtrue
- 逻辑运算符、位运算符
用于连接多个条件(多个关系表达式,关系表达式也就是前面关系运算符所连接的一串表达式)
最终的结果也是一个 boolean 值
- & : 逻辑与
左边、右边同为 true 时,结果为 true,否则为 false
- && : 短路与
在满足 逻辑与 的基础上,添加了短路机制:当左边为 false 时,不会计算右边,直接返回 false
- | : 逻辑或
左边、右边同为 false 时,结果为 false,否则为 true
- || : 短路或
在满足 短路或 的基础上,添加了短路机制:当左边为 true 时,不会计算右边,直接返回 true
- ^ : 逻辑异或
左边、右边 不同 时,返回 true
左边、右边 相同 时,返回 false
- ! : 取反
对 ! 右侧的 boolean值进行取反
true –> false
false –> true
aba & ba && ba | ba || ba ^ b!atruetruetruetruetrueturefalsefalsetruefalsefalsefalsetruetruetruefalsefalsetruefalsefalsetruetruetruetruefalsefalsefalsefalsefalsefalsefalsetrue
- 复习题
- //题1
- public static void test01(){
- int x = 5;
- int y = 5;
- if (x++==6 & ++y==6){ // F & T -> F
- x=11;
- }
- System.out.print("x -> " + x + "\t"); // 6
- System.out.println("y -> " + y); // 6
- }
- //题2
- public static void test02(){
- int x = 5;
- int y = 5;
- if (x++==5 | ++y==5){ // T | F -> T
- x=11;
- }
- System.out.print("x -> " + x + "\t"); // 11
- System.out.println("y -> " + y); // 6
- }
- //题3
- public static void test03(){
- int x = 5;
- int y = 5;
- if (x++==6 && ++y==6){ // F && (短路不运算)
- x=11;
- }
- System.out.print("x -> " + x + "\t"); // 6
- System.out.println("y -> " + y); // 5
- }
- //题4
- public static void test04(){
- int x = 5;
- int y = 5;
- if (x++==5 || ++y==5){ // T || (短路不运算)
- x=11;
- }
- System.out.print("x -> " + x + "\t"); // 11
- System.out.println("y -> " + y); // 5
- }
复制代码
- 赋值运算
赋值运算符就是将某个运算后的值,赋给指定的变量
- 基本赋值运算符
- int a = 1; // 此处的 = 号,便是基本赋值运算符,可以理解为: 有一个存储int的4字节空间,空间名称为a,现在将 1 这个值存放到这个空间中
复制代码 - 复合赋值运算符
- int a = 10;
- int b = 20;
- a += b; // 等价于: a = a + b;
- a -= b; // 等价于: a = a - b;
- a *= b; // 等价于: a = a * b;
- a /= b; // 等价于: a = a / b;
- a %= b; // 等价于: a = a % b;
复制代码 - 赋值运算符的特点
- 运算顺序从右往左
- 赋值运算符
- 左边 只能是变量
- 右边 可以是变量、表达式、常量值
- 复合赋值运算符会进行类型转换
- byte b = 3;
- b += 2; // 等价 b = (byte)(b + 2);
- b++; // b = (byte)(b+1);
复制代码
- 三元运算符
- 基本语法 : 条件表达式 ? 表达式1 : 表达式2
当条件表达式为 true 时,返回 表达式1 的 结果
当条件表达式为 false 时,返回 表达式2 的 结果
- 举例 :
- int a = 10;
- int b = 20;
- int res = a > b ? a++ : --b; // res -> 21 ; a -> 10 ; b -> 21 ;
复制代码 - 细节
- 三元运算符返回基本数据类型时,会自动转换为表达式中精度最高的类型
- int a = 10;
- double b = 10.1;
- System.out.println(true ? a : b); // 输出 : 10.0
复制代码
- 运算符优先级
所谓优先级就是表达式运算中的运算顺序
下表中的运算符中,上一行运算符总优先于下一行
只有单目运算符、赋值运算符是从右向左运算的
运算方向运算符. () {} ; ,右 -> 左++ -- ~ !(data type)左 -> 右* / %左 -> 右+ -左 -> 右> >>> 位移左 -> 右< > = instanceof左 -> 右== !=左 -> 右&左 -> 右^左 -> 右|左 -> 右&&左 -> 右||左 -> 右xx ? xx : xx(三元运算符)右 -> 左= *= /= %=右 -> 左+= -= =右 -> 左>>>= &= ^= |=
- 标识符的命名规范
Java对各种变量、方法和类等命名时使用的字符序列称为标识符
凡是自己可以起名字的地方都叫标识符
- 标识符的命名规则(必须遵守)
- 26个英文字母大小写(Java中区分大小写)、0-9、_ 、$ 组成
最好不要用 $
- 数字 不能 开头
- 不可以 使用 保留字、关键字,但能够包含 保留字、关键字
- 长度 不受限制
- 不能包含 空格
- 标识符的命名规范(约定俗成)
- 包名
多单词组成时所有字母都小写
com.zhumei.study
- 类名、接口名
多单词时使用大驼峰
XxxYyyZzz
- 变量名、方法名
多单词时使用小驼峰
xxxYxxZzz
- 常量名
字母全大写
多单词时使用下划线分隔
XXX_YYY_ZZZ
Java流程控制
<ol>顺序控制
没什么好说的,就是从上往下按代码顺序执行
分支控制
- 单分支 if
- if (条件表达式) {
- // 条件表达式的值为 ture 则执行此代码块中的代码(false则不执行)
- 代码;
- }
复制代码 flowchart TD A[Start] --> B{条件表达式} B -->|true| C[代码块] C --> D[end] B -->|false| D
- 双分支 if - else
- if (条件表达式) {
- // 条件表达式的值为 ture 则执行此代码块中的代码1(false则不执行)
- 代码1;
- } else{
- // 条件表达式的值为 false 则执行此代码块中的代码2(true则不执行)
- 代码2;
- }
复制代码 flowchart TD A[Start] --> B{条件表达式} B -->|true| C[代码块1] C --> E[end] B -->|false| D[代码块2] D --> E
- 多分枝 if - else if - … - else
- if (条件表达式1) {
- 代码1; // 条件表达式1为true则执行代码1,并不再继续执行与条件表达式1处于同一分支的表达式与其对应的代码
- } else if (条件表达式2){
- 代码2; // 条件表达式2为true则执行代码2,并不再继续执行与条件表达式2处于同一分支的表达式与其对应的代码
- } else if (条件表达式N){
- 代码n; // 条件表达式n为true则执行代码n,并不再继续执行与条件表达式n处于同一分支的表达式与其对应的代码
- } else{
- 代码n+1; // 若所有的表达式都为false,则执行此代码块
- }
复制代码 flowchart TD A[Start] --> B{条件表达式1} B -->|true| C[代码块1] C --> D[end] B -->|false| E{条件表达式2} E -->|true| F[代码块2] F --> D E -->|false| G{条件表达式n} G -->|true| H[代码块n] G -->|false| I[代码n+1] H --> D I --> D
- 嵌套分支
在 一个分支结构 中又 完整的 嵌套了 另一个完整的分支结构
建议不超过3层,嵌套层数与可读性呈负相关,层数越多可读性越差
- if (条件表达式a){
- 代码1;
- if (条件表达式b){
- 代码2;
- }else if (条件表达式c){
- 代码3;
- }else {
- 代码4
- }
- }
复制代码 - switch分支
- 在Java中:
- switch表达式的值可以是变量(byte、short、int、char、这4个基本数据类型的包装类对象、String对象、枚举对象)
- case后的值不能为变量,必须是常量
- default语句是可选的,若没有default语句又没有匹配上对应的case中的常量,就表示不会执行switch中的任何代码(switch中的表达式是一定会执行的)
- 在case中的代码不写break,会导致case穿透
- switch(表达式){
- case 常量1:
- 代码1;
- break;
- case 常量2:
- 代码2;
- break;
- case 常量n:
- 代码n;
- break;
- default:
- 代码default;
- break;
- }
复制代码
循环控制
<ul>for循环
- for循环的四要素:
- 循环变量初始化
- 循环条件
- 循环操作(需要循环的代码)
- 循环变量迭代
- 循环变量初始化、循环条件、循环变量迭代,都可以不放在for循环的括号中
- 循环条件是一个返回布尔值的表达式,若在for循环中没有写循环条件,则默认为true
- 退出for循环的方式:
- 循环条件结果为false
- 执行break语句
- 执行return语句
- for(循环变量初始化;循环条件;循环变量迭代){
- 需要循环的代码;
- }
复制代码 while循环
while循环和for循环一样,也有相同的循环四要素,只不过放的位置和for循环不一样
简单来说,可以把while循环看作另一种写法的for循环
不必纠结写法上的细枝末节,重点在于知道执行的代码在哪种情况下被循环了几次
- 循环变量初始化;
- while(循环条件){
- 需要循环的代码;
- 循环变量迭代;
- }
复制代码 do…while循环
和while循环相比,do…while循环会先执行一次寻妖循环的代码,再进行
- 循环变量初始化;
- do{
- 需要循环的代码;
- 循环变量迭代;
- }while(循环条件);
复制代码 多重循环控制
将一个循环放在另一个循环中,外层循环和内层循环均可使用for循环、while循环、do…while循环
一般建议多重循环不超过3层,层数越多,代码可读性越差- for (int i = 0; i < 10; i++) { // 外层循环
- for (int j = 0; j < 20; j++) { // 内层循环
- System.out.print("*"); // 需要xun
- }
- System.out.println(); // 表示换行
- }
复制代码 <ul>经典题<ol>
打印 九九乘法表
[code]for (int i = 1; i |