祗疼妳一个 发表于 2023-6-30 21:29:51

Java-语法基础

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 KitJava开发工具包
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存储空间小的限制)

[*]布尔型

[*]boolean : 1个字节


[*]引用数据类型

[*]类
[*]接口
[*]数组

flowchart RL    byte()    short()    int()    long()    float()    double()    char()    boolean()    CLASS([类 class])    interface([接口 interface])    array([数组 arrary])    NUMBER([数值型])    CHARACTER([字符型])    BOOLEAN([布尔型])    BASIC([基本数据类型])    REFERENCE([引用数据类型])    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 --> B{条件表达式}    B -->|true| C[代码块]    C --> D    B -->|false| D
[*]双分支 if - else
if (条件表达式) {
    // 条件表达式的值为 ture 则执行此代码块中的代码1(false则不执行)
    代码1;
} else{
    // 条件表达式的值为 false 则执行此代码块中的代码2(true则不执行)
    代码2;
}flowchart TD    A --> B{条件表达式}    B -->|true| C[代码块1]    C --> E    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 --> B{条件表达式1}    B -->|true| C[代码块1]    C --> D    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;
}https://img2023.cnblogs.com/blog/2304439/202306/2304439-20230630202458320-226969969.jpg
循环控制
<ul>for循环

[*]for循环的四要素:

[*]循环变量初始化
[*]循环条件
[*]循环操作(需要循环的代码)
[*]循环变量迭代

[*]循环变量初始化、循环条件、循环变量迭代,都可以不放在for循环的括号中
[*]循环条件是一个返回布尔值的表达式,若在for循环中没有写循环条件,则默认为true
[*]退出for循环的方式:

[*]循环条件结果为false
[*]执行break语句
[*]执行return语句

for(循环变量初始化;循环条件;循环变量迭代){
    需要循环的代码;
}https://img2023.cnblogs.com/blog/2304439/202306/2304439-20230630202550970-1366555949.jpgwhile循环
while循环和for循环一样,也有相同的循环四要素,只不过放的位置和for循环不一样
简单来说,可以把while循环看作另一种写法的for循环
不必纠结写法上的细枝末节,重点在于知道执行的代码在哪种情况下被循环了几次
循环变量初始化;
while(循环条件){
    需要循环的代码;
    循环变量迭代;
}https://img2023.cnblogs.com/blog/2304439/202306/2304439-20230630202640713-556657298.jpgdo…while循环
和while循环相比,do…while循环会先执行一次寻妖循环的代码,再进行
循环变量初始化;
do{
    需要循环的代码;
    循环变量迭代;
}while(循环条件);https://img2023.cnblogs.com/blog/2304439/202306/2304439-20230630202938614-1800299548.jpg多重循环控制
将一个循环放在另一个循环中,外层循环和内层循环均可使用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>
打印 九九乘法表
for (int i = 1; i
页: [1]
查看完整版本: Java-语法基础