语法构建
标识符
标识符是程序中用于标识变量、方法、类、接口等元素的名称。标识符的命名规则包括:
1. 字符组成:可以包含字母、数字、下划线(_)和美元符号($),但不能以数字开头。
2. 大小写敏感:myVariable 和 myvariable 被视为不同的标识符。
3. 不能使用关键字:标识符不能与 Java 的关键字相同。
关键字
关键字是 Java 语言中具有特定意义的保留字,不能用作标识符。Java 有 50 个关键字,例如:
• 数据类型:int, float, double, char, boolean
• 控制语句:if, else, switch, case, for, while, do
• 访问修饰符:public, private, protected
• 其他:class, interface, extends, implements, void, return, try, catch, finally
变量
o 定义:内存中的一块有名字的存储空间
o 变量三要素:类型、名字、值
常量
o 定义:值不可变的变量
o 特点:只能赋一次值,不能二次赋值
o 常量通常使用 final 关键字声明,且通常采用全大写字母格式
基本数据类型
Java 有 8 种基本数据类型:
1. 整型:
• byte:8 位,范围是 -128 到 127
• short:16 位,范围是 -32,768 到 32,767
• int:32 位,范围是 -2,147,483,648 到 2,147,483,647
• long:64 位,范围是 -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807
2. 浮点型:
• float:32 位,单精度浮点数
• double:64 位,双精度浮点数
3. 字符型:
• char:16 位,表示单个字符,范围是 '\u0000' (0) 到 '\uffff' (65,535)
4. 布尔型:
• boolean:只能取 true 或 false 两个值
类型转换
• 自动转换:
• 小赋大、整赋浮
• 注意:byte、short、char参与运算的时候,先转换为int类型
byte b = 1;
short c = 2;
int n = b + c;
• 强制类型转换:大赋小、浮赋整
float p2 = (float)3.10;
引用数据类型
引用数据类型用于引用对象,包括但不限于:
• 类:例如 String, Scanner, 自定义类等。
• 接口:定义类的行为。
• 数组:例如 int[], String[] 等。 int[] numbers = new int[5];
运算符
算术运算符
+ :加法 - :减法 * :乘法 / :除法 % :取余
2. 关系运算符
== :等于 != :不等于 > :大于 < :小于 >= :大于等于 <= :小于等于
3. 逻辑运算符(会短路)
&& :逻辑与(AND) || :逻辑或(OR) ! :逻辑非(NOT) 4. 位运算符
4.用于按位操作整数类型(不会短路)
& :按位与 | :按位或 ^ :按位异或 ~ :按位取反
<< :左移 >> :右移 >>> :无符号右移
5. 赋值运算符
= :赋值 += :加赋值 -= :减赋值
*= :乘赋值 /= :除赋值 %= :取余赋值
6. 三元运算符
用于简化条件语句。
条件 ? 表达式1 : 表达式2
条件:这是一个布尔表达式。如果条件为 true,则返回 表达式1;如果为 false,则返回 表达式2。
7. 实例运算符
用于在对象中检查类型和获取信息。
instanceof:检查对象是否为某个类的实例。
语句构建
循环语句
if 语句
用于根据条件执行不同的代码块。
switch 语句
用于根据变量的值选择执行不同的代码块。
for 循环
用于重复执行一段代码,直到满足特定条件。
while 循环
在条件为 true 的情况下重复执行代码。
do-while 循环
与 while 循环类似,但至少会执行一次循环体。
增强 for 循环(foreach),用于简化集合或数组的遍历。
for (元素类型 元素 : 集合或数组) {
// 使用元素
}
跳转语句
break
用于立即终止循环或 switch 语句。
continue
用于跳过当前循环的迭代,直接进入下一个迭代。
return
用于从方法中返回,并可返回一个值(如果方法有返回值)。
输入输出
// Scanner
Scanner sc = new Scanner(System.in);
int a = sc.nextInt();
double b = sc.nextDouble();
String c = sc.next();
String d = sc.nextLine();
// System.out
System.out.print(); // 输出
System.out.println(); // 输出并换行
保留小数
double number = 123.456789;
String formattedNumber = String.format("%.2f", number);
System.out.println(formattedNumber); // 输出: 123.46
System.out.printf("%.2f%n", number); // 输出: 123.46
方法
• 定义:java 中一个命名的代码块,在其他计算机语言中常被称为函数;
• 好处:代码复用、使程序结构清晰
• 语法:
[修饰符] returnType methodName([形参列表]){
methodBody
}
return 语句:使程序的执行回到主调方法
注意:
1、有返回值类型的方法,必须要有return语句;
2、返回值在主调方法中可以不被接收使用;
3、方法重载:方法名相同,方法参数不同(参数个数、参数类型、参数顺序)的方法
4、方法递归:方法自己调用自己
JAVA进阶
String类
String类常用方法
在 Java 中,创建字符串有两种常见方法:
1. 字面量方式:String s = "hello";
• 这种方式会在字符串池中创建一个字符串对象。如果字符串池中已有相同内容的字符串,则会引用已有的对象,而不会创建新的。
2. 使用构造函数:String s = new String("hello");
• 这种方式会直接在堆内存中创建一个新的字符串对象,不论字符串池中是否存在相同内容的字符串。这种方式通常不推荐使用,除非需要确保创建一个新的对象。
这种区别会影响内存管理和性能。
1. concat() 和 +
• concat(String str):用于连接两个字符串,返回一个新字符串。
• +:运算符重载,用于字符串连接,也可以将多个字符串拼接在一起。
2. equals() 和 ==
• ==:用于比较两个引用是否指向同一个对象。对于字符串,它会比较内存地址。
• equals(Object obj):用于比较两个字符串的内容是否相同。
3. length()
• length():返回字符串的长度(字符数)。
4. substring()
• substring(int beginIndex):返回从指定索引到字符串末尾的子字符串。
• substring(int beginIndex, int endIndex):返回从指定的 beginIndex 到 endIndex(不包括该索引)的子字符串。
5. indexOf()
• indexOf(String str):返回指定子字符串第一次出现的索引。如果未找到,则返回 -1。
• indexOf(char ch):返回指定字符第一次出现的索引。
6. split()
• split(String regex):根据给定的正则表达式分割字符串,返回一个字符串数组。
String、StringBuffer、StringBuilder、StringJoiner
1. String
不可变性:String 是不可变的,一旦创建,内容无法更改。任何对字符串的修改都会生成一个新的 String 对象。
性能:由于每次修改都会创建新对象,频繁的字符串操作(如拼接)可能导致性能问题。
2. StringBuffer
可变性:StringBuffer 是可变的,允许在原有对象上进行修改。
线程安全:它是同步的,适合在多线程环境中使用。
性能:在频繁的字符串修改时,StringBuffer 的性能优于 String,但由于其线程安全的特性,可能会稍微影响性能。
3. StringBuilder
可变性:StringBuilder 也是可变的,与 StringBuffer 类似。
非线程安全:不保证线程安全,适合单线程环境,性能优于 StringBuffer。
性能:在频繁的字符串拼接和修改操作中,StringBuilder 提供了更好的性能。
总结
如果你需要创建一个不变的字符串,使用 String。
如果你在多线程环境中需要安全的字符串操作,选择 StringBuffer。
如果在单线程环境中进行大量字符串操作,推荐使用 StringBuilder。
4.StringJoiner 是 Java 8 引入的一个类,主要用于将字符串拼接在一起,特别是在需要添加分隔符的情况下。它可以用来创建一个由特定分隔符连接的字符串,简化了字符串拼接的操作。
主要特性
分隔符:可以指定字符串之间的分隔符,例如逗号、空格等。
前缀和后缀:可以为拼接的结果添加前缀和后缀,便于生成特定格式的字符串。
可变性:StringJoiner 是可变的,可以逐步添加元素。
线程安全:不是线程安全的,适合在单线程环境中使用。
API
时间API
Java 的时间 API 主要通过 java.time 包提供,使用起来比旧的 java.util.Date 和 java.util.Calendar 更加方便和直观。
常用类
• LocalDate:表示不带时区的日期。
• LocalTime:表示不带时区的时间。
• LocalDateTime:表示不带时区的日期和时间。
• ZonedDateTime:表示带时区的日期和时间。
数学API
Java 提供了 java.lang.Math 类,包含了许多常用的数学方法,比如三角函数、指数、对数等。
常用方法
• Math.abs(double a):返回绝对值。
• Math.sqrt(double a):返回平方根。
• Math.pow(double a, double b):返回 a 的 b 次幂。
• Math.sin(double a)、Math.cos(double a)、Math.tan(double a):三角函数。
• Math.random():返回 0 到 1 之间的随机数。
外部API
外部 API 是指与外部系统或服务进行交互的接口。通过调用外部 API,应用程序可以获取数据、执行操作或利用第三方服务的功能。外部 API 通常使用 HTTP 协议,返回的数据格式一般为 JSON 或 XML。
使用外部 API 的基本步骤
了解 API 文档:在使用外部 API 前,查看相关的文档,了解请求格式、支持的方法、参数、返回值等信息。
选择 HTTP 方法:
GET:获取数据。
POST:发送数据。
PUT:更新数据。
DELETE:删除数据。
构建请求:
设置请求 URL。
添加必要的请求头(如认证信息)。
根据需要传递请求参数。
发送请求:使用 HTTP 客户端库(如 HttpURLConnection、OkHttp、Retrofit 等)发送请求。
处理响应:解析响应数据,通常是 JSON 格式,可以使用 JSON 解析库(如 Jackson、Gson 等)。
类、对象、包
面向过程 & 面向对象
• 面向过程(POP:procedure oriented programming):
o “面向过程” 关心的是事件,以及事件的执行流程
o 加 -> 减 -> 乘 -> 除
• 面向对象(OOP:Object Oriented Programming):
o “面向对象” 关心的是对象,以对象为中心,由对象发出动作 。
类 (Class)
-
定义:类是对象的蓝图或模板,用于定义对象的属性(成员变量)和行为(方法)。
-
成员变量:类中定义的变量,表示对象的状态。
-
方法:类中定义的函数,表示对象的行为。
-
构造方法:特殊的方法,用于创建对象并初始化属性。
-
语法:与类名同名且没有返回值类型的方法;
-
作用:对象初始化构造器中的第一条可执行语句是对其它构造器(
父类构造器、当前类构造器
)的调用,当没有显示调用其它构造器时,系统默认调用的是父类无参构造器(父类中必须有无参构造器
)。 -
this
-
对象 (Object)
-
定义:对象是类的实例,具有类中定义的属性和方法。每个对象都有独立的状态。
-
创建对象:使用
new
关键字来创建对象。
类和对象的关系
- 类是模板:类定义了对象的结构和行为,但本身不占用内存。
- 对象是实例:对象是类的具体实现,每个对象都有自己的属性值。
包(Package)
包是用于组织类和接口的一种机制,类似于文件夹结构。包可以帮助管理代码,避免命名冲突,并控制访问权限。
• 定义:包是一个命名空间,用于存放相关类和接口的集合。
• 声明:使用 package 关键字来声明包。字母全小写:例如package com.example.myapp;
导入包
• 导入类:使用 import 关键字引入其他包中的类。
访问控制
• 公共访问:使用 public 修饰符,类和接口可以被其他包访问。
• 默认访问:如果没有指定访问修饰符,类和接口只能在同一包中访问。
常用包
• Java 标准库包:如 java.util(集合框架)、java.io(输入输出流)、java.lang(基础类)。
• 自定义包:可以根据项目需求创建自己的包。
封装、继承、多态
封装、继承和多态是面向对象编程(OOP)的三大基本特征。
封装 (Encapsulation)
定义:封装是将数据(属性)和对数据的操作(方法)组合在一起,并隐藏内部实现细节的过程。
实现:通过访问修饰符(如 private、protected、public)来控制对类成员的访问。用户只能通过公共方法(get/set)访问和修改属性。
继承 (Inheritance)
代码复用
定义:继承是允许一个类(子类)继承另一个类(父类)的属性和方法的机制。
实现:使用 extends 关键字,子类可以重用父类的代码并添加新的功能。
可继承成员:父类中除私有成员和构造器外,其余成员都能被子类继承,私有的成员只能通过从父类中继承来的公有方法间接的调用。
成员覆盖、属性覆盖、方法新增
方法重写(override) (就近原则调用自己的)
子类拥有与父类完全相同的方法,覆盖了父类中的方法。重写的方法返回值类型/异常类型可以缩小,访问权限可以被放大。
继承中的初始化:先人(父)后己(子)
构造器中的第一条可执行语句是对其它构造器(父类构造器|当前类构造器)的调用,当没有显示调用其它构造器时,系统默认调用的是父类无参构造器(父类中必须有无参构造器)
类是单继承的,即一个类只能继承一个类
最终类不能被继承
最终量(常量)不能被二次赋值
最终方法不能被覆盖(重写)
最终类不能被继承,比如String
多态 (Polymorphism)
定义:多态是指同一操作可以作用于不同类型的对象,表现出不同的行为。
实现:通过方法重载(同一方法名不同参数)和方法重写(子类重写父类方法)来实现。
向上转型(父类的属性,子类的方法)
静态绑定/前期绑定/编译期绑定/属性绑定
动态绑定/后期绑定/运行时绑定/行为绑定
向下转型:a -> b -> a , 强制类型转换。
instanceof: 类型判断
总结
• 封装:保护数据,提供安全性。
• 继承:促进代码重用和扩展性。
• 多态:提高灵活性和可扩展性,使代码更具可读性。
权限控制、static
权限控制
private : 类中可见;
默认:同包可见;
protected: 同包可见 + 子类可见;
public: 哪儿都可见。
static 关键字
用于定义类的静态成员,意味着该成员属于类而不是类的实例。静态成员可以是变量、方法或块。
1. 静态变量
定义:静态变量在内存中只有一份,与所有实例共享。
2. 静态方法
定义:可以通过类名直接调用,不需要实例化对象。静态方法不能访问非静态成员。
3. 静态块
定义:用于初始化静态变量,类加载时执行一次。
4. 静态成员属于类,需用static修饰,这样的成员,被称为类成员,通过类名直接调用。(依赖对象调用的成员被称为实例成员)
5. java类首次加载进JVM时,会对静态变量(含静态块)进行一次初始化(执行)。
所谓类首次加载是指:比如第一次new对象,第一次调用类的静态方法,都要用到这个类,第一次用到该类的时候,静态代码(静态成员变量、静态块)就会被率先执行。
6. 静态方法(静态块)不能操作实例成员。
7. 在java中,java的静态类、方法、变量是存放在全局数据区中的,在应用程序运行期间一直占用内存而不被销毁。
抽象类、接口
抽象类和接口都是用于实现抽象化和多态的关键概念,但它们有不同的用途和特点。
抽象类(abstract)
定义: abstract修饰的类
抽象方法:abstract修饰的没有方法体的方法
定义:不能实例化的类,可以包含抽象方法(没有实现)和具体方法(有实现)。
特点:
可以有构造函数。
可以有状态(成员变量)。
注意:
抽象类不能实例化
子类继承抽象父类,如果父类中的抽象方法不在子类中实现,那么子类依然是抽象类
接口(interface)
定义:只有静态常量或抽象方法(默认情况下方法是 public 和 abstract 的)的抽象类
JDK8及以后,允许在接口中定义static方法和default方法。
1. 静态方法,只能通过接口名调用,不可以通过实现类的类名或者实现类的对象调用。
2. default方法,只能通过接口实现类的对象来调用。如果默认方法不能满足需要,实现类可以覆盖默认方法。
特点:
Java 8 后支持默认方法(有实现)。
类可以实现多个接口(支持多重继承)。
不能有构造函数或状态。
类是单继承的(一个只能继承一个类)
接口是多实现的(一个类可以实现多个接口)
接口多继承(一个接口可以继承多个接口)
总结
使用抽象类:当有共同行为或状态时。
使用接口:当需要实现多重继承或定义协议时。
类的继承性限制
类(接口)通常可被被任意继承(实现),
为了限制类的继承性,java提供了两种限制方式:最终类 和 密封类 。
final 最终类
被 final 修饰的类为最终类,最终类不能为继承。
public final class String{}
sealed 密封类
JDK 17 中,Sealed Classes 被正式提出,密封类的使用有以下几个关键字:
• sealed:修饰类(接口),用来描述这个类(接口)为密封类(接口)
• non-sealed:修饰类(接口),用来描述这个类(接口)为非密封类(接口)
• permits:指定可以继承或实现的类(接口)
sealed Person。。。。。。