Java思维导图
2023-06-09 23:27:07 0 举报
AI智能生成
Java复习
作者其他创作
大纲/内容
1、初识Java
什么是Java语言
Java是一种高级的面向对象编程语言。它是由Sun Microsystems公司于20世纪90年代初开发的,后被Oracle公司收购。Java被广泛应用于企业级软件开发、移动开发、Web应用程序开发、游戏开发等领域。
Java语言特性
1、简单易用:Java语法简洁清晰,易于学习和使用。
2、跨平台性:Java可以在不同的操作系统和硬件平台上运行,不需要重新编译代码。
3、面向对象:Java是一种面向对象的编程语言,支持封装、继承和多态等特性。
4、安全性高:Java具有天生的安全性,提供了内置的安全机制,如安全控制、异常处理等。
5、内存管理自动:Java提供了自动内存管理机制,程序员不需要手动分配和释放内存空间,有效避免了内存泄漏和悬空指针问题。
6、开发工具丰富:Java提供了大量的开发工具和框架,如Eclipse、IntelliJ IDEA、Spring、Struts等,可以提高开发效率和代码质量。
2、跨平台性:Java可以在不同的操作系统和硬件平台上运行,不需要重新编译代码。
3、面向对象:Java是一种面向对象的编程语言,支持封装、继承和多态等特性。
4、安全性高:Java具有天生的安全性,提供了内置的安全机制,如安全控制、异常处理等。
5、内存管理自动:Java提供了自动内存管理机制,程序员不需要手动分配和释放内存空间,有效避免了内存泄漏和悬空指针问题。
6、开发工具丰富:Java提供了大量的开发工具和框架,如Eclipse、IntelliJ IDEA、Spring、Struts等,可以提高开发效率和代码质量。
2、Java开法工具
Eclipse开发工具简介
Eclipse是一种Java开发工具,也是一种集成开发环境(IDE),它可以用于开发各种类型的Java应用程序,包括桌面程序、Web应用程序、企业应用程序等。Eclipse具有以下特点:
丰富的插件:Eclipse拥有大量的插件,可以扩展其功能,如Web开发插件、数据库开发插件、版本控制插件等。
自由开源:Eclipse是一款开源软件,可以自由下载和使用,并且可以修改源代码以满足用户特定的需求。
跨平台性:Eclipse基于Java开发,并且支持多种操作系统平台,包括Windows、Linux、macOS等。
容易使用:Eclipse的界面简单明了,功能齐全,支持快捷键等多种操作方式,使得开发人员可以高效地进行编码和调试。
大型社区支持: Eclipse拥有庞大的用户社区,可以获取大量的文档和教程,开发人员可以减少学习时间,提高开发效率。
总之,Eclipse是一种非常流行的开发工具,是开发Java应用程序的首选之一。
Eclipse是一种Java开发工具,也是一种集成开发环境(IDE),它可以用于开发各种类型的Java应用程序,包括桌面程序、Web应用程序、企业应用程序等。Eclipse具有以下特点:
丰富的插件:Eclipse拥有大量的插件,可以扩展其功能,如Web开发插件、数据库开发插件、版本控制插件等。
自由开源:Eclipse是一款开源软件,可以自由下载和使用,并且可以修改源代码以满足用户特定的需求。
跨平台性:Eclipse基于Java开发,并且支持多种操作系统平台,包括Windows、Linux、macOS等。
容易使用:Eclipse的界面简单明了,功能齐全,支持快捷键等多种操作方式,使得开发人员可以高效地进行编码和调试。
大型社区支持: Eclipse拥有庞大的用户社区,可以获取大量的文档和教程,开发人员可以减少学习时间,提高开发效率。
总之,Eclipse是一种非常流行的开发工具,是开发Java应用程序的首选之一。
下载与安装
Eclipse是一个常用的Java集成开发环境,可以在Windows、Linux和Mac OS X等系统上运行。
以下是Eclipse下载和安装的步骤:
1. 打开Eclipse官网https://www.eclipse.org/downloads/,选择与你电脑操作系统版本相匹配的Eclipse下载地址。
2. 下载后解压Eclipse安装包,在解压的文件夹中找到“eclipse.exe”文件,并双击该文件运行Eclipse。
3. 第一次启动Eclipse,会提示选择工作空间。工作空间是我们保存项目的地方,可以手动选择工作空间文件夹,也可以使用默认的工作空间,然后点击“Launch”按钮,启动Eclipse。
4. 启动后,会出现一个欢迎页面。点击页面左上角的“Workbench”图标,即可进入Eclipse的主界面。
5. 如果发现Eclipse在启动时出现了错误,则可以检查Java环境变量或重新安装JDK。
6. 在Eclipse界面中,依据你的需求安装一些Java开发插件或者开发工具。
安装完成后,你可以通过Eclipse进行Java程序的编写、调试和运行。同时,Eclipse也可以支持其他编程语言的开发,如C++、Python等。
以下是Eclipse下载和安装的步骤:
1. 打开Eclipse官网https://www.eclipse.org/downloads/,选择与你电脑操作系统版本相匹配的Eclipse下载地址。
2. 下载后解压Eclipse安装包,在解压的文件夹中找到“eclipse.exe”文件,并双击该文件运行Eclipse。
3. 第一次启动Eclipse,会提示选择工作空间。工作空间是我们保存项目的地方,可以手动选择工作空间文件夹,也可以使用默认的工作空间,然后点击“Launch”按钮,启动Eclipse。
4. 启动后,会出现一个欢迎页面。点击页面左上角的“Workbench”图标,即可进入Eclipse的主界面。
5. 如果发现Eclipse在启动时出现了错误,则可以检查Java环境变量或重新安装JDK。
6. 在Eclipse界面中,依据你的需求安装一些Java开发插件或者开发工具。
安装完成后,你可以通过Eclipse进行Java程序的编写、调试和运行。同时,Eclipse也可以支持其他编程语言的开发,如C++、Python等。
3、Java语言基础
Java主类结构
在Java中,主类结构指的是一个包含main方法的类的结构。这个类是Java应用程序的入口点,在程序启动时首先被执行。Java程序中,每个包含main方法的类都可以作为主类结构。
一个Java主类的结构如下:
public class MainClassName {
public static void main(String[] args) {
// 程序执行的入口点
}
}
其中,MainClassName代表类名,需要和文件名相同,并且需要在文件头部声明包名(如果有的话)。main方法是Java程序的入口点,程序从这里开始执行。
main方法的定义格式是固定的,它接收一个字符串数组作为参数,其中args表示命令行参数。在程序启动时,可以在命令行中传递参数给main方法,这些参数会被包装成一个字符串数组传递给main方法,程序可以根据需要使用这些参数。
一个Java主类的结构如下:
public class MainClassName {
public static void main(String[] args) {
// 程序执行的入口点
}
}
其中,MainClassName代表类名,需要和文件名相同,并且需要在文件头部声明包名(如果有的话)。main方法是Java程序的入口点,程序从这里开始执行。
main方法的定义格式是固定的,它接收一个字符串数组作为参数,其中args表示命令行参数。在程序启动时,可以在命令行中传递参数给main方法,这些参数会被包装成一个字符串数组传递给main方法,程序可以根据需要使用这些参数。
基本数据类型
Java有8种基本数据类型,它们可以分为4类:
1. 数值类型:
- byte:表示1个字节(8位)的带符号数字,取值范围为 -128到+127。
- short:表示2个字节(16位)的带符号数字,取值范围为 -32,768到+32,767。
- int:表示4个字节(32位)的带符号数字,取值范围为 -2^31到2^31-1。
- long:表示8个字节(64位)的带符号数字,取值范围为 -2^63到2^63-1。
2. 浮点类型:
- float:表示4个字节(32位)的浮点数字,取值范围为 ±3.40282347E+38F(十进制)。
- double:表示8个字节(64位)的浮点数字,取值范围为 ±1.79769313486231570E+308(十进制)。
3. 字符类型:
- char:表示2个字节(16位)的Unicode字符,取值范围为0到65,535。
4. 布尔类型:
- boolean:表示一个布尔值,只有两个取值:true和false。
这些基本数据类型是Java中最基础和常用的数据类型,用于存储不同类型的数据。除了基本数据类型,Java还有引用类型,如对象和数组,它们存储的是对象或数组在虚拟机中的引用。可以通过关键字new来创建对象和数组,它们也有自己的类型和方法。
1. 数值类型:
- byte:表示1个字节(8位)的带符号数字,取值范围为 -128到+127。
- short:表示2个字节(16位)的带符号数字,取值范围为 -32,768到+32,767。
- int:表示4个字节(32位)的带符号数字,取值范围为 -2^31到2^31-1。
- long:表示8个字节(64位)的带符号数字,取值范围为 -2^63到2^63-1。
2. 浮点类型:
- float:表示4个字节(32位)的浮点数字,取值范围为 ±3.40282347E+38F(十进制)。
- double:表示8个字节(64位)的浮点数字,取值范围为 ±1.79769313486231570E+308(十进制)。
3. 字符类型:
- char:表示2个字节(16位)的Unicode字符,取值范围为0到65,535。
4. 布尔类型:
- boolean:表示一个布尔值,只有两个取值:true和false。
这些基本数据类型是Java中最基础和常用的数据类型,用于存储不同类型的数据。除了基本数据类型,Java还有引用类型,如对象和数组,它们存储的是对象或数组在虚拟机中的引用。可以通过关键字new来创建对象和数组,它们也有自己的类型和方法。
变量与常量
Java中的变量是一些可以改变值的内存位置,用于存储各种数据类型的值。变量由一个标识符表示,标识符可以是我们命名的任何名称。Java中的变量分为局部变量和成员变量(也称为类变量或实例变量)。
1. 局部变量:定义在方法、代码块或构造函数中的变量,只能在定义它的方法、代码块或构造函数中访问。局部变量只有在定义之后才可以使用,且必须先进行初始化才能使用。
2. 成员变量:定义在类中,而不是在方法、代码块或构造函数中的变量,有时也称为类变量或实例变量。成员变量可以被整个类和其中的所有方法访问。如果成员变量没有分配初始值,则会被自动赋为0、false或null。
Java中的常量是一种固定值,声明后它的值不能被修改。使用final关键字定义的变量即为常量。与变量不同,常量在定义时必须显式地分配一个初始值,不能在后续的代码中更改它们的值。
常量定义的语法格式如下:
final data_type CONSTANT_NAME = CONSTANT_VALUE;
例如:
final double PI = 3.14159;
final int MAX_VALUE = 100;
使用常量的好处是提高代码的可读性、可维护性和可重用性,因为在程序中多次使用的固定值可以定义成常量,避免硬编码。
1. 局部变量:定义在方法、代码块或构造函数中的变量,只能在定义它的方法、代码块或构造函数中访问。局部变量只有在定义之后才可以使用,且必须先进行初始化才能使用。
2. 成员变量:定义在类中,而不是在方法、代码块或构造函数中的变量,有时也称为类变量或实例变量。成员变量可以被整个类和其中的所有方法访问。如果成员变量没有分配初始值,则会被自动赋为0、false或null。
Java中的常量是一种固定值,声明后它的值不能被修改。使用final关键字定义的变量即为常量。与变量不同,常量在定义时必须显式地分配一个初始值,不能在后续的代码中更改它们的值。
常量定义的语法格式如下:
final data_type CONSTANT_NAME = CONSTANT_VALUE;
例如:
final double PI = 3.14159;
final int MAX_VALUE = 100;
使用常量的好处是提高代码的可读性、可维护性和可重用性,因为在程序中多次使用的固定值可以定义成常量,避免硬编码。
变量作用范围
Java中的变量作用域是指其可见性的范围,一般可分为以下几种情况:
1. 局部变量(Local Variables):在方法、构造函数、块中定义的变量,仅在其被声明的代码块内有效,出了这个范围,这个变量就会被销毁。
2. 成员变量(Instance Variables):在类中定义的变量,其作用域是整个类,可以在类中的任意方法、构造函数、块中使用。
3. 静态变量(Static Variables):也称为类变量,其作用域也是整个类,但是其在内存中的生命周期会比实例变量长,可以通过类名直接访问。
4. 方法参数(Method Parameters):在方法中定义的参数变量,其作用域在该方法中,只能在该方法内部使用。
需要注意的是,变量的作用域会影响到其可访问的范围,如果不理解作用域的范围,容易导致变量的重名或意外的行为。因此,在编写代码时,应该尽量避免变量的作用域重叠,以防止混淆。
1. 局部变量(Local Variables):在方法、构造函数、块中定义的变量,仅在其被声明的代码块内有效,出了这个范围,这个变量就会被销毁。
2. 成员变量(Instance Variables):在类中定义的变量,其作用域是整个类,可以在类中的任意方法、构造函数、块中使用。
3. 静态变量(Static Variables):也称为类变量,其作用域也是整个类,但是其在内存中的生命周期会比实例变量长,可以通过类名直接访问。
4. 方法参数(Method Parameters):在方法中定义的参数变量,其作用域在该方法中,只能在该方法内部使用。
需要注意的是,变量的作用域会影响到其可访问的范围,如果不理解作用域的范围,容易导致变量的重名或意外的行为。因此,在编写代码时,应该尽量避免变量的作用域重叠,以防止混淆。
Java关键字
Java关键字表
运算符
Java中的运算符是一些用于操作操作数的符号或关键字,可以对变量、常量、表达式等进行各种类型的操作。常见的Java运算符包括:
1. 算术运算符:用于数值数据类型的加、减、乘、除、取余等运算,包括+、-、*、/、%等。
2. 关系运算符:用于比较两个数值的大小关系或判断两个对象是否相等,包括==、!=、>、<、>=、<=等。
3. 逻辑运算符:用于对逻辑表达式进行操作,包括与(&&)、或(||)、非(!)等。
4. 位运算符:用于对二进制数的位进行操作,包括按位与(&)、按位或(|)、按位异或(^)、取反(~)等。
5. 赋值运算符:用于给变量赋值,包括=、+=、-=、*=、/=、%=、&=、|=、^=、<<=、>>=、>>>=等。
6. 三元运算符:用于根据条件选择执行语句,包括条件表达式?值1:值2。
7. instanceof运算符:用于判断对象是否属于某个类或接口类型,包括对象 instanceof 类。
这些运算符涵盖了Java中常用的运算,可以帮助开发者进行各种类型的操作以实现程序功能。在写代码时需要注意运算符的使用顺序以及类型转化问题,以确保程序的正确性和效率。
1. 算术运算符:用于数值数据类型的加、减、乘、除、取余等运算,包括+、-、*、/、%等。
2. 关系运算符:用于比较两个数值的大小关系或判断两个对象是否相等,包括==、!=、>、<、>=、<=等。
3. 逻辑运算符:用于对逻辑表达式进行操作,包括与(&&)、或(||)、非(!)等。
4. 位运算符:用于对二进制数的位进行操作,包括按位与(&)、按位或(|)、按位异或(^)、取反(~)等。
5. 赋值运算符:用于给变量赋值,包括=、+=、-=、*=、/=、%=、&=、|=、^=、<<=、>>=、>>>=等。
6. 三元运算符:用于根据条件选择执行语句,包括条件表达式?值1:值2。
7. instanceof运算符:用于判断对象是否属于某个类或接口类型,包括对象 instanceof 类。
这些运算符涵盖了Java中常用的运算,可以帮助开发者进行各种类型的操作以实现程序功能。在写代码时需要注意运算符的使用顺序以及类型转化问题,以确保程序的正确性和效率。
数据类型转换
1、隐式类型转换
隐式转换:指自动转换类型,例如将一个byte类型的变量赋值给int类型的变量,这种转换是自动发生的,Java编译器会自动将byte类型转换成int类型,但不能从int类型直接转换成byte类型。占用字节数小的转换位为占用字节数大的。
2、显式类型转换
显式转换:指强制转换类型,使用强制转换符将一个数据类型转换为另一个数据类型,例如将int类型的变量转换为byte类型,需要使用(int)强制转换符进行显式转换。大转小
注意
需要注意的是,在进行数据类型转换时可能会发生数据精度丢失,例如将一个double类型的变量强制转换成int类型,会发生数据的截断。为了避免这种情况的发生,可以通过一些转换技巧或者使用Java提供的一些库函数进行处理。
常见的数据类型转换包括:
将浮点型转换为整型:使用Math库提供的round方法,将float或double类型的数值四舍五入后转为整型。
将字符串转换为整型或浮点型:使用Integer.parseInt()或Double.parseDouble()方法,将字符串类型转换为int或double类型。
数据类型转换是Java编程中常用的技巧,需要注意转换的方式和范围,以确保程序的正确性和效率。
4、流程控制语句
条件语句
if语句:根据表达式的值来决定哪个分支被执行;
if-else语句:如果if语句的表达式值为true,则执行if块的代码;如果为false,则执行else块的代码;块与块之间使用一对大括号区分,一对大括号就是一个代码块:{}
switch语句:根据表达式的值进行匹配,匹配成功后执行对应的代码块。需要注意的是在JDK7之后,可以在switch中使用String类型作为开关变量。
循环语句
while语句:只要循环条件的值为true,就一直执行循环体的代码;
do-while语句:先执行循环体的代码,然后再判断循环条件的值是否为true,如果为true则继续执行,否则跳出循环;
for语句:基于计数器的循环控制结构,循环开始前需要初始化计数器,然后循环体中可修改计数器并在达到某个条件时跳出循环。
跳转语句
break语句:用于跳出循环语句或switch语句;需要注意的是,该语句只能编写在循环语句或switch语句当中
continue语句:用于跳过本次循环的剩余代码并进入下一次循环;需要注意的是,continue语句只能编写在循环语句内部。
5、数组
概述
在Java中,数组是一种特殊的数据结构,用于存储一组相同类型的数据值。数组是以连续的内存空间存储数据的,每个值的位置都有一个唯一的下标(索引),用于访问和操作该数据值。
数组的特点
1.数组不能扩容:Java数组在初始化时必须指定数组容量,一旦分配了空间大小,就不能再改变容量,这也意味着数组中的元素数量是固定的。
2.数组元素类型必须一致:Java数组中的每个元素类型必须一致,可以是Java的任意基本数据类型,例如 int、double、boolean、char 等,也可以是任意的引用类型。
3.数组每个元素的索引从0开始:Java数组中每个元素的下标从0开始,最后一个元素的下标为数组长度-1,访问数组时必须小心,避免越界。
4.数组可以作为参数传递:Java方法可以接受数组作为参数传递,可以在方法中对数组进行操作和修改。
5.Java提供了一些数组工具类:Java提供了一些数组工具类,例如Arrays类,可以方便地进行数组的排序、比较、查找等操作。
一维数组
概述:
Java中的一维数组是最基本、最简单的数组,它由一组数据元素组成,每个元素有自己的唯一索引。在Java中,一维数组可以存储任意基本数据类型和引用类型。
Java中一维数组的特点:
1.一维数组的大小由数组元素的个数决定,一旦创建,其大小不能被改变。
2.一维数组的元素可以是任意数据类型。
3.数组的元素访问下标从0开始,最后一个元素的下标为数组长度-1。
4.数组可以作为方法的参数和返回值。
二维数组
概述:
Java中的二维数组是指由多行多列的元素所组成的数组,每个元素具有一个唯一的行索引和列索引。在Java中,二维数组本质上是由一组一维数组所构成的,可以存储任意基本数据类型和引用类型。
二维数组特点:
1.二维数组是一组带有行索引和列索引的数据值组成的数据集合。
2.二维数组的大小由行和列数决定,一旦创建,其大小不能被改变。
3.二维数组的元素也可以是任意基本数据类型和引用类型。
4.二维数组的元素也可以是任意基本数据类型和引用类型。
5.二维数组也可以作为方法的参数和返回值,可以方便地存储和处理二维数据。
基本排序算法
冒泡排序
算法思想:
冒泡排序是一种基本的排序算法,其原理是从数组的第一个元素开始比较,依次将相邻的元素进行比较,如果前面的元素大于后面的元素,则交换它们的位置,直到数组末尾。一遍过去之后,最大的数就会被交换到了数组的最后一位,下一遍就从数组的第一个元素开始比较,直到数组被排序完毕。
代码实现:
public static void bubbleSort(int[] arr) {
// 外循环控制排序趟数
for (int i = 0; i < arr.length - 1; i++) {
// 内循环控制每趟排序多少次
for (int j = 0; j < arr.length - 1 - i; j++) {
// 判断相邻两个元素的大小关系
if (arr[j] > arr[j+1]) {
// 交换相邻的两个元素
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}
// 外循环控制排序趟数
for (int i = 0; i < arr.length - 1; i++) {
// 内循环控制每趟排序多少次
for (int j = 0; j < arr.length - 1 - i; j++) {
// 判断相邻两个元素的大小关系
if (arr[j] > arr[j+1]) {
// 交换相邻的两个元素
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}
总结:
在代码实现中,外层循环控制排序的趟数,内层循环控制每一趟排序的次数,通过判断相邻元素的大小来交换它们的位置。冒泡排序算法的时间复杂度为 O(n²),因此对于大规模的数据排序来说,效率较低。然而,由于其实现的简单和易于理解,对于小规模的数据排序来说,冒泡排序是一种不错的选择。
直接选择排序
算法思想:
直接选择排序是一种简单直观的排序算法,其基本思想是每次选择最小的元素,依次放置在数组的最前面。具体地,从数组的第一个元素开始,找到它后面比它还要小的元素,将它们的位置进行交换,这样一趟过去后,数组的第一个元素就是最小的元素,然后从第二个元素开始,重复这个过程,直到整个数组排序完成。
代码实现:
public static void selectionSort(int[] arr) {
// 外循环控制排序趟数
for (int i = 0; i < arr.length - 1; i++) {
int minIndex = i;
// 内循环控制每趟排序多少次
for (int j = i + 1; j < arr.length; j++) {
// 判断当前元素是否比最小元素小
if (arr[j] < arr[minIndex]) {
// 更新最小元素的位置
minIndex = j;
}
}
// 将最小元素与当前元素交换位置
int temp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = temp;
}
}
// 外循环控制排序趟数
for (int i = 0; i < arr.length - 1; i++) {
int minIndex = i;
// 内循环控制每趟排序多少次
for (int j = i + 1; j < arr.length; j++) {
// 判断当前元素是否比最小元素小
if (arr[j] < arr[minIndex]) {
// 更新最小元素的位置
minIndex = j;
}
}
// 将最小元素与当前元素交换位置
int temp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = temp;
}
}
总结:
在代码实现中,外层循环控制排序趟数,内层循环是在剩余的元素中选择最小的元素,然后与当前元素进行交换。
直接选择排序算法的时间复杂度为 O(n²),与冒泡排序算法相同,但是相比冒泡排序,直接选择排序的交换次数要明显减少,因此对于中等规模的数据排序来说,直接选择排序是一种不错的选择。
直接选择排序算法的时间复杂度为 O(n²),与冒泡排序算法相同,但是相比冒泡排序,直接选择排序的交换次数要明显减少,因此对于中等规模的数据排序来说,直接选择排序是一种不错的选择。
6、类和对象
概述:
Java是一种面向对象的编程语言,因此在Java中,对象是代码的基本构造块。面向对象编程的核心是对象的概念,通过封装、继承和多态性等特性,可以实现代码的重用、灵活性、易于维护等优秀的编程特征。
对象
在 Java 中,对象是一种特殊的数据类型,是由类定义的具体实例,其包含数据和在这些数据上操作的方法。对象具有状态(属性)和行为(方法),并且能够与其他对象进行交互来完成特定的任务。
对象的创建
1.定义类
定义类。在Java中,我们使用类来定义对象。类可以看作是对象的蓝图,它包含了对象的属性和方法。
2.实例化对象
实例化对象。可通过关键字new来实例化一个对象。
例如,可以使用以下代码来创建一个名为student的对象:
Student student = new Student();
例如,可以使用以下代码来创建一个名为student的对象:
Student student = new Student();
访问对象的属性与行为
访问属性
访问对象的属性可以通过.操作符来访问对象的属性。
例如,可以使用以下代码来访问对象student的name属性:
student.name = "张三";
例如,可以使用以下代码来访问对象student的name属性:
student.name = "张三";
访问行为
同样,可通过.操作符来调用对象的行为。
例如,可以使用以下代码来调用对象student的study()方法:
student.study();
例如,可以使用以下代码来调用对象student的study()方法:
student.study();
对象的引用
概述:
在Java中,对象的引用是指向对象的指针或地址,它存储在栈中。对象的实际数据存储在堆中。因此,对对象的操作始终是通过引用来实现的。
对象引用的特点
1.对象引用是变量。Java中,对象引用也是一种变量,它存储在栈中,而实际的对象数据存储在堆中。
2.对象引用可以是null。如果对象引用没有指向实际的对象,则它的值为null。
3.对象引用可以是null。如果对象引用没有指向实际的对象,则它的值为null。
4.对象引用可以被传递给方法。在Java中,对象引用可以作为参数传递给方法。这将使方法可以访问相同的对象。
5.对象引用可以比较。在Java中,可以使用比较运算符来比较对象引用。若两个对象引用指向同一个对象,则比较结果为true;否则比较结果为false。
结论:
总之,在Java中,对象的引用是非常重要的,因为它们使得我们可以操作对象,并在程序中传递数据。了解对象引用的概念和细节是Java编程中的重要部分。
对象的销毁
在Java中,对象的销毁与其他编程语言存在一些不同。
Java的垃圾回收机制可以自动监视和释放不再被任何引用使用的对象,使得Java程序员无需手动释放内存。
Java中的垃圾回收器会定期扫描内存,寻找不再被任何引用使用的对象。
当一个对象变得不可访问时,垃圾回收器会立即将其从内存中移除。
Java的垃圾回收机制可以自动监视和释放不再被任何引用使用的对象,使得Java程序员无需手动释放内存。
Java中的垃圾回收器会定期扫描内存,寻找不再被任何引用使用的对象。
当一个对象变得不可访问时,垃圾回收器会立即将其从内存中移除。
Java中的对象在以下情况下会被视为垃圾并被销毁:
1.对象的所有引用都已经被释放。当一个对象的所有引用都被释放时,该对象变得不可访问,垃圾回收器会将其销毁并释放内存。
2.对象的引用过期。如果一个对象的引用在特定时间内未被使用,它将被垃圾回收器销毁并释放内存。
3.对象的引用过期。如果一个对象的引用在特定时间内未被使用,它将被垃圾回收器销毁并释放内存。
4.调用System.gc()方法。这并不能保证对象会被立即销毁,而是通知垃圾回收器收集内存。通常情况下,我们不需要手动调用此方法。
结论:
总之,在Java中,对象的销毁是自动进行的,无需我们手动处理。我们只需要确保及时释放不再被使用的对象的所有引用即可。
类
概述:
Java 中,类是一种用于描述对象的抽象数据类型(ADT)。在类中可以定义对象的属性(属性也称为字段或成员变量)和对象的行为(行为也称为方法或成员函数),从而封装了对象的状态和行为信息。类是 Java 中实现封装、继承和多态性的基础,是面向对象编程的核心。
类的组成
成员变量与成员方法:
类的成员变量指的是类的属性,这些属性通常是用 private 访问修饰符来进行修饰,是类的私有属性,只能通过类的内部方法来进行访问。类的成员方法定义了类的行为,也称为函数或方法,通常使用 public 访问修饰符来进行修饰,可以被外部程序访问,也可以被内部程序访问。
构造方法
构造函数是类的一个特殊的函数,用于创建类的对象,构造函数的名字与类名相同,通常没有返回值类型,可以有参数。类的每个对象都会调用它自己的构造函数来初始化对象的属性。如果没有在类中定义构造函数,则 Java 会自动创建一个构造函数。如果在类中已经定义了一个有参构造,但是没有定义无参构造,那么Java虚拟机不会自动构造一个无参构造,需要自行定义。
权限修饰符
概述:
在 Java 中,类中可以使用的权限修饰符有四种,分别是 public、protected、default(即默认访问修饰符)和 private,它们的访问级别依次递减。
1.public
使用 public 权限修饰符的成员或方法是公开的,可以被该类的所有其他类、不同包中的类和所有类都访问。用 public 修饰的类,类名必须与源代码文件名相同,并且该类可以被任何包和类所调用。
2.protected
使用 protected 权限修饰符的成员或方法只能被该类的子类、该类的包中的其他类访问。protected 可以允许子类继承访问它,同时也不会对同一个包中的其他类造成影响。
3.default
使用 default 或不加修饰符的成员或方法是默认的访问修饰符,只能被同一个包中的其他类访问。如果我们定义一个变量或方法时没有使用任何访问控制符,系统将默认将其访问等级设为默认的访问级别。
4.private
使用 default 或不加修饰符的成员或方法是默认的访问修饰符,只能被同一个包中的其他类访问。如果我们定义一个变量或方法时没有使用任何访问控制符,系统将默认将其访问等级设为默认的访问级别。
需要注意的是,外部类不能访问类的私有成员,但可以通过公共方法间接地访问私有成员;
类的内部方法可以访问所有类的所有成员,包括私有成员。
类的内部方法可以访问所有类的所有成员,包括私有成员。
this关键字
在Java中,this关键字表示当前对象的引用,它可以访问当前对象的属性和方法。在类中,当一个方法或一个构造函数与类的一个属性或参数具有相同的名称时,可以使用 this 关键字来区分相同名称的变量,以便访问类的成员,而不是方法内的局部变量。this关键字代表的就是当前对象的地址。
静态变量与静态方法
概述:
Java 类中的静态变量和静态方法是与类自身相关联的,它们不依赖于任何类的实例。静态变量与静态方法随着类的加载而加载
1.静态变量
静态变量也称为类变量,它是由 static 关键字修饰的成员变量,它属于类,而不是类的实例。静态变量只存储一份,被所有对象共享,也就是说当静态变量的值改变的时候,所有引用它的对象的值都会改变。静态变量在程序启动时就已经分配了空间,随着类的加载而加载,无需等待类的实例化。
2.静态方法
静态方法也是由 static 关键字修饰的方法,同样属于类自身。静态方法可以在不实例化对象的情况下直接使用,静态方法只能调用静态成员(变量和方法),而不能调用非静态方法和成员变量(因为非静态成员是由对象创建的)。静态方法通常用于类的工具方法和常量的设置。
总结
总之,静态变量和静态方法是与类自身相关的,不依赖于特定对象的实例化。在使用静态变量和静态方法时,需要注意它们的访问修饰符和调用方法,而且,静态变量和静态方法的使用可以提高程序的性能和灵活性,因此在 Java 中被广泛地应用,是 Java 程序设计中的重要组成部分。
总结
总之,Java 类是面向对象编程中的基本构造块,它将对象的属性和行为封装到一个单独的单元中,并具备可重用性以及对数据和操作的抽象特性,是 Java 程序设计的基础。
面向对象三大特性:
概述:
Java 面向对象编程的三大特性是封装、继承和多态性。这三种特性分别是面向对象编程中的封装、继承和多态性的具体体现,通过它们的结合使用,可以编写出易于维护、模块化和可重用的 Java 代码。
1.封装
封装是面向对象编程的重要特性,它指的是将类的属性和方法结合到一起,对外部进行隐藏,只向外部提供一组接口,使外部代码不能随意操作对象的内部状态,确保数据的安全性和代码的可维护性。这些接口提供类对其独有状态和行为的访问权限,而不需要了解其内部实现细节。
在 Java 中,封装的实现方式通常是使用关键字 private 将对象的属性限制为该类中访问,并使用 getter、setter 等方法来允许外部代码访问和修改这些属性。封装可以有效地隔离对象的内部状态和行为,封装好的类中的属性对外不可见,可以有效地保护数据的安全性,这也是 Java 中的面向对象编程的重要特性之一。
在 Java 中,封装的实现方式通常是使用关键字 private 将对象的属性限制为该类中访问,并使用 getter、setter 等方法来允许外部代码访问和修改这些属性。封装可以有效地隔离对象的内部状态和行为,封装好的类中的属性对外不可见,可以有效地保护数据的安全性,这也是 Java 中的面向对象编程的重要特性之一。
2.继承
继承是面向对象编程中的另一个重要特性,指的是一个类可以继承另一个类的特征,从而不需要重新编写已有的代码,使代码可以重用,并且可以扩展已经有的方法和变量。
Java 中继承的实现方式是使用 extends 关键字,一个类可以继承另一个类的所有成员变量和方法。父类中的方法和属性可以在子类中使用,可以重写父类中的方法,也可以添加子类特有的方法。
Java 中继承的实现方式是使用 extends 关键字,一个类可以继承另一个类的所有成员变量和方法。父类中的方法和属性可以在子类中使用,可以重写父类中的方法,也可以添加子类特有的方法。
3.多态
多态性是面向对象编程中的另一个重要特性,指的是某一个类的实例可以表现出多种形式的属性和行为,即同一操作作用于不同的对象可以有不同的解释,称为“多态”。
Java 中的多态性实现方式是使用重写和重载等技术,一个类的实例在运行时可以表现出不同的形态,包括方法重载、方法重写和类继承等。
Java 中的多态性实现方式是使用重写和重载等技术,一个类的实例在运行时可以表现出不同的形态,包括方法重载、方法重写和类继承等。
总结:
在 Java 中,这三大特性的结合使用,可以有效地提高程序的可维护性、可重用性和代码的高内聚性。经过这些封装、继承和多态性等手段的处理后,可以使 Java 程序变得易于编写、易于理解、易于维护。
7、继承、多态与接口
类的继承
概述:
类的继承是指一个类可以继承另一个类的属性和方法。
实现:
在Java中,使用关键字"extends"来实现继承。一个类可以继承自另一个类,继承的类叫做子类,被继承的类叫做父类。
一个类只能继承一个父类,但一个父类可以有多个子类。
一个类只能继承一个父类,但一个父类可以有多个子类。
作用:
子类可以继承父类的非私有的属性和方法。子类可以使用父类的方法,也可以重写父类的方法,这个过程叫做覆盖(override)。
需要注意的是,在子类重写了父类的方法后,子类调用就是就是本类重写后的方法。
需要注意的是,在子类重写了父类的方法后,子类调用就是就是本类重写后的方法。
代码示例:
class Animal { // 定义了一个动物类
public void sound() {
System.out.println("Animal makes a sound");
}
}
// dog类继承了动物类
class Dog extends Animal {
public void sound() {
System.out.println("Dog barks");
}
}
public class Main {
public static void main(String[] args) {
Animal myAnimal = new Animal();
Dog myDog = new Dog();
myAnimal.sound();
myDog.sound();
}
}
public void sound() {
System.out.println("Animal makes a sound");
}
}
// dog类继承了动物类
class Dog extends Animal {
public void sound() {
System.out.println("Dog barks");
}
}
public class Main {
public static void main(String[] args) {
Animal myAnimal = new Animal();
Dog myDog = new Dog();
myAnimal.sound();
myDog.sound();
}
}
注解:
在上面的例子中,我们定义了一个名为Animal的父类,它有一个名为sound的方法。
然后我们定义了一个Dog子类,它继承自Animal类,并覆盖了sound方法。
在Main类中,我们分别创建了一个Animal对象和一个Dog对象,并调用它们的sound方法。
然后我们定义了一个Dog子类,它继承自Animal类,并覆盖了sound方法。
在Main类中,我们分别创建了一个Animal对象和一个Dog对象,并调用它们的sound方法。
运行结果:
Object类
概述:
在Java中,所有类都直接或间接地继承自一个名叫Object的父类。Object类是Java中的根类,它定义了所有对象都具有的通用行为。
常用方法
Object类中有一些常用的方法,这些方法是所有子类都会继承并可以重写的
1.equals(Object obj):判断当前对象是否与指定对象相同。
由于引入了对象的概念,所以在比较两个对象之间是否相同时无法使用比较运算符==,
因为对象的引用变量中存储的是对象的地址值,但是需要比较的对象的数据值,所以如果需要比较两个对象的话,需要重写equals方法
因为对象的引用变量中存储的是对象的地址值,但是需要比较的对象的数据值,所以如果需要比较两个对象的话,需要重写equals方法
2.toString():返回当前对象的字符串表示。
将当前对象存储的数据值转换成字符串进行返回
此外,Object类还有一个空的构造函数,因为所有的类都隐式地调用了Object类的构造函数,所以它是必需的。
对象类型的转换
概述:
在Java中,对象之间的转换主要有两种形式:向上转型和向下转型。
且需要进行向上转型与向下转型的对象之间,一定需要有继承关系。
且需要进行向上转型与向下转型的对象之间,一定需要有继承关系。
向上转型
向上转型指的是将一个子类对象赋值给一个父类引用,这种转换是自动的,不需要任何特殊操作,因为每个子类对象也是一个父类对象,具有父类对象所有的属性和方法。
例码:
class Animal {
public void sound() {
System.out.println("Animal makes a sound");
}
}
class Dog extends Animal {
public void bark() {
System.out.println("Dog barks");
}
}
public class Main {
public static void main(String[] args) {
Animal myAnimal = new Dog();
myAnimal.sound();
}
}
public void sound() {
System.out.println("Animal makes a sound");
}
}
class Dog extends Animal {
public void bark() {
System.out.println("Dog barks");
}
}
public class Main {
public static void main(String[] args) {
Animal myAnimal = new Dog();
myAnimal.sound();
}
}
注解:
在上面的例子中,我们使用子类Dog对象向上转型为父类Animal类型,并将它赋值给一个Animal类型的引用myAnimal,然后调用myAnimal的sound()方法,输出结果为"Dog barks"。
向下转型
向下转型指的是将一个父类对象转换为其子类对象,这种转换需要使用强制类型转换符。但是,向下转型需要满足一定的条件,即原先被转型的对象必须是向上转型过程中所使用的子类对象。
例码:
class Animal {
public void sound() {
System.out.println("Animal makes a sound");
}
}
class Dog extends Animal {
public void bark() {
System.out.println("Dog barks");
}
}
public class Main {
public static void main(String[] args) {
Animal myAnimal = new Dog();
if(myAnimal instanceof Dog) {
Dog myDog = (Dog) myAnimal;
myDog.bark();
}
}
}
public void sound() {
System.out.println("Animal makes a sound");
}
}
class Dog extends Animal {
public void bark() {
System.out.println("Dog barks");
}
}
public class Main {
public static void main(String[] args) {
Animal myAnimal = new Dog();
if(myAnimal instanceof Dog) {
Dog myDog = (Dog) myAnimal;
myDog.bark();
}
}
}
注解:
在上面的例子中,我们使用子类Dog对象向上转型为父类Animal类型,并将它赋值给一个Animal类型的引用myAnimal,然后判断myAnimal是否可以转换为Dog类型。如果可以,就将myAnimal向下转型为Dog类型,并调用myDog的bark()方法,输出结果为"Dog barks"。
注意:
需要注意,如果向下转型的对象和转换后的类型不是兼容的,会抛出ClassCastException异常。
所以,在进行向下转型之前,要确保对象的类型是正确的。
所以,在进行向下转型之前,要确保对象的类型是正确的。
instanceof关键字
在Java中,instanceof是一个关键字,用来检查一个对象是否是某个类的实例。
语法格式:
if(obj instanceof ClassName) {
// obj是ClassName类型的实例
}
// obj是ClassName类型的实例
}
注解:
instanceof会返回一个布尔值,如果obj是ClassName类的一个实例,就返回true,否则返回false。
注意:
如果obj是null,那么instanceof会返回false。
同时,子类对象也是父类对象的一个实例,所以如果一个对象是某个类的实例,那么它一定是这个类的父类的实例。
同时,子类对象也是父类对象的一个实例,所以如果一个对象是某个类的实例,那么它一定是这个类的父类的实例。
方法重载
在Java中,方法的重载是指在一个类中定义多个方法,它们具有相同的名字但是不同的形参参数列表。
当调用一个重载方法时,Java编译器会根据方法调用所传入的参数类型和数量,自动判断应该调用哪一个方法。
当调用一个重载方法时,Java编译器会根据方法调用所传入的参数类型和数量,自动判断应该调用哪一个方法。
需要注意的是,方法重载和方法修饰符、返回值类型没有关系,重载方法必须具有不同的形参类型或数量。否则,编译器会报错。
final关键字
在Java中,final关键字可以用于三个地方:变量、方法和类。
1.final变量:
使用final关键字修饰的变量称为常量,一旦被赋值之后就不能被修改。final变量必须在定义时进行初始化,并且不能被重新赋值。final变量的用途包括定义常量和防止数据篡改。
2.final方法:
使用final关键字修饰的方法不能被子类重写,保证了方法的一致性。final方法在父类中声明,子类中不能覆盖这个方法。
3.final类:
使用final关键字修饰的类不能被继承,保证了类的一致性和安全性。final类在一般类的基础上添加了不能派生出新的类的限制。
结论:
final关键字的作用主要是为了提高程序的安全性和效率。它能够避免一些不应该改变的变量、方法或类被无意修改,保证了程序的稳定性和一致性。同时,final关键字还能够提高程序的性能,因为在编译期间就能够确定final变量的值,从而减少程序的运行时计算。但是,需要注意使用final关键字时一定要慎重,以免造成过度限制或不必要的程序复杂度。
多态
概念:
在 Java 中,多态性是面向对象编程的一种重要概念,它是指同一个方法调用,在不同对象上产生不同的行为。
多态机制能够让我们写出更加灵活、模块化和可扩展的代码,大大提高了程序的可读性和可维护性。
多态机制能够让我们写出更加灵活、模块化和可扩展的代码,大大提高了程序的可读性和可维护性。
作用:
1.代码重用:多态允许不同类之间共享相同的方法。例如,我们可以针对一个父类编写一个通用的方法,然后在子类中重写这个方法以实现特定的功能,这样代码的重用性会大大提高。
2.程序可扩展性:多态性使得程序可以通过扩展不同的类来实现新的功能,而不需要改变现有的代码。这意味着程序可以很方便地进行扩展,而且扩展的成本较低。
3.统一的接口:多态性允许不同对象使用相同的接口来进行方法调用。这种机制使得接口更加统一和一致,提高了代码的可读性和可理解性。
4.便于维护:由于多态性建立在继承和抽象类的基础之上,因此它使得代码更加易于维护。通过多态性,我们可以将代码分离成不同的模块,每个模块可以独立地进行开发和维护,从而使得整个程序更加健壮和稳定。
结论:
综上所述,多态在 Java 中具有非常重要的作用,它能够使得程序更加灵活、可扩展和易于维护。在编写程序时,我们应该充分利用多态的机制来设计相关的类与方法,从而提高程序的可读性和可维护性。
抽象
概念:
在 Java 中,抽象(Abstraction)指的是将具体的实现细节抽象成一组抽象接口,并隐藏实现细节,只向外界暴露必要的接口。抽象机制能够提高代码的可扩展性和可维护性,使得代码更加灵活和易于修改。Java中抽象的概念主要体现在两个方面:抽象类和接口。
抽象类(abstract)
抽象类是指不能被实例化的类,它包含抽象方法和非抽象方法。
抽象方法是指只声明而不定义方法实现的方法,需要在子类中实现。
抽象类的作用是约束子类实现相应的方法,以确保它们具有相同的行为和属性。
抽象方法是指只声明而不定义方法实现的方法,需要在子类中实现。
抽象类的作用是约束子类实现相应的方法,以确保它们具有相同的行为和属性。
注意:
抽象方法只能存在于抽象类中,而抽象类中不止有抽象方法,还可以有普通方法,普通方法不强制子类重写。
子类在继承抽象类后必须重写父类中的所有抽象方法。
子类在继承抽象类后必须重写父类中的所有抽象方法。
接口(interface)
接口是指由特定的关键字interface定义的一组抽象方法和常量,没有方法体。
接口与类类似,可以有方法和常量,但只能有抽象方法和常量。
接口的作用是定义一个实现某些功能的规范或标准,它把描述行为的方法和实现行为的代码分离开,使得程序更加灵活和可扩展。
接口与类类似,可以有方法和常量,但只能有抽象方法和常量。
接口的作用是定义一个实现某些功能的规范或标准,它把描述行为的方法和实现行为的代码分离开,使得程序更加灵活和可扩展。
接口继承
接口与接口之间是存在继承关系的,称为接口继承。接口可以扩展一个或多个接口,通过接口继承机制,一个接口可以获得多个父接口的方法。在继承关系中,子接口可以继承父接口的方法和常量,并且可以添加新的方法和常量。
接口继承的特点
1.接口之间的继承关系是多重继承,一个接口可以继承多个接口。
2.父接口中的方法和常量会被子接口继承下来,并且要求子接口实现父接口中的所有未实现方法。
3.子接口可以新增自己的方法、常量等。
总结:
综上所述,接口和接口之间是存在继承关系的,通过接口继承机制,一个接口可以获得多个父接口中的方法和常量,并且可以添加新的方法和常量。通过接口继承,我们可以实现更为灵活的接口设计,提高代码的复用性和可扩展性。
8、包和内部类
Java类包
概述
Java类包是Java平台中用于组织、分类和管理Java类、接口、枚举和注解等程序代码的一种机制。Java类包提供了一种灵活的、面向对象的包含机制,使得Java程序员可以将相关的类组织在一起,方便代码的管理和使用。
命名规则
Java类包采用了非常简单的命名规则,以点号(.)为分隔符,用于分隔不同的包名,可以在类或接口的代码文件的开头用package关键字来指定该类或接口所在的包。
作用:
一个Java类包可以包含多个Java类文件,这些文件可以自由地存储在同一个或多个目录中。在编写代码时,可以使用import关键字来引用其他Java类包中的类、接口或静态方法。
拓展
Java平台提供了大量的类包,如java.lang、java.util、java.io等,其中java.lang包是Java平台中最基本、最核心的类包,提供了Java语言基本类型、异常类和字符串操作等常用功能,其他类包则提供了各种不同的功能模块,比如java.util提供了各种数据结构和算法类、java.io提供了文件输入输出和网络通信类等。
包名冲突
概念:
在Java程序中,如果两个或多个不同的类包含了相同的包名和类名,就会导致包名冲突。在使用这些类时,Java编译器无法判断具体使用哪个类,因此会抛出编译错误。
解决方法:
为了避免包名冲突,Java规定每个类都有一个全限定名(Fully Qualified Name),即包含包名和类名的完整名称。因此,即使两个类的名称和包名相同,它们的全限定名也是不同的。在编写代码时,可以使用完整的全限定名来引用相应的类。
创建包
语法:
Java中创建包的方法非常简单,只需在源代码文件的开头增加package语句即可,语法格式如下:
package 包名;
package 包名;
导入包
概述:
在Java代码中,为了引用其他类包中的类或接口,需要使用import语句来导入相应的包。
语法:
import 包名.类名;
其中,包名是被导入的类所在的包的名称,而类名则是要导入的类的名称。
其中,包名是被导入的类所在的包的名称,而类名则是要导入的类的名称。
内部类
概述:
Java内部类指的是定义在另一个类内部的类。与普通类不同,内部类可以访问外部类的私有属性和方法,同时也可以被外部类访问。
内部类特点:
1.内部类可以访问外部类的私有属性和方法,因此可以提高程序的封装性和安全性。
2.内部类可以访问外部类的构造方法和初始化块,从而可以进行一些特殊的初始化或操作。
3.内部类可以被声明为private或protected,从而限制外部类的访问。
4.内部类可以实现多重继承,即可以实现多个接口、继承一个类并实现接口等。
5.内部类可以被声明为静态的,从而可以直接通过外部类访问,不需要创建外部类的实例。
内部类类型
1.成员内部类(Member Inner Class):
成员内部类是最普通的内部类,它定义在另一个类的内部,并与该类的成员具有相同的访问权限。
成员内部类的创建方式为:先创建外部类的实例,然后在该实例上使用new关键字创建内部类的实例。
成员内部类的创建方式为:先创建外部类的实例,然后在该实例上使用new关键字创建内部类的实例。
2.局部内部类(Local Inner Class):
局部内部类是定义在方法或作用域内部的类。局部内部类只在该方法或作用域内可见,仅能在该方法或作用域内使用。
局部内部类的使用时机通常是在某个方法中需要一个类来完成一些逻辑,但这个类不适合放在其他地方定义,因此将其定义成局部内部类,只在需要时才创建并使用它。
局部内部类的使用时机通常是在某个方法中需要一个类来完成一些逻辑,但这个类不适合放在其他地方定义,因此将其定义成局部内部类,只在需要时才创建并使用它。
3.匿名内部类(Anonymous Inner Class):
匿名内部类是一种特殊的局部内部类,没有类名,定义在方法或作用域内部,通常用于创建只需要一次性使用的对象。
匿名内部类可以继承一个类或实现一个接口,同时还可以使用外部类的变量和方法。
匿名内部类可以继承一个类或实现一个接口,同时还可以使用外部类的变量和方法。
4.静态内部类(Static Inner Class):
静态内部类是一个静态的类,被声明为static,可以直接通过外部类访问,不需要创建外部类的实例。
静态内部类通常作为外部类的静态属性使用。静态内部类与外部类没有绑定关系,也就是说,它可以访问外部类的静态成员和静态方法,但不能访问外部类的非静态成员和方法。
静态内部类通常作为外部类的静态属性使用。静态内部类与外部类没有绑定关系,也就是说,它可以访问外部类的静态成员和静态方法,但不能访问外部类的非静态成员和方法。
总结:
总之,Java内部类是Java语言的一项重要特性,可以帮助程序员更灵活、更方便地组织Java代码。
掌握Java内部类的相关知识,有助于提高Java程序的封装性、可读性和安全性。
掌握Java内部类的相关知识,有助于提高Java程序的封装性、可读性和安全性。
9、异常处理
异常的概念
Java异常(Exception)是指在程序运行期间出现的错误或意外情况。当Java程序发生异常时,它会抛出一个异常对象,如果异常没有被捕捉,则程序会终止执行。在Java中,所有的异常对象都是Throwable类或其子类的实例。Throwable类是所有错误和异常类的超类,分为两种类型:Error(错误)和Exception(异常)。其中,Error是Java系统级别的错误,不能被程序员处理,系统级错误通常是由于Java虚拟机或操作系统出现问题导致的;Exception则是可以被程序员处理的异常,分为受检查异常和非受检查异常两种类型。
异常的类型
1.受检查异常(Checked Exception):
受检查异常是指编译时需要检查的异常,是Java编译器强制进行检查的异常。这种类型的异常通常是因为程序员在调用外部库时,需要对外部库可能出现的异常进行处理。常见的受检查异常包括IOException、SQLException等。
2.非受检查异常(Unchecked Exception):
非受检查异常是指在编译时不需要进行检查的异常,通常是由于程序员在编写代码时出现的错误或逻辑异常。常见的非受检查异常包括NullPointerException、ArrayIndexOutOfBoundsException等。
3.错误(Error):
错误是指Java系统级别的错误,不能被程序员处理,通常是由于Java虚拟机或操作系统出现问题导致的。常见的错误包括OutOfMemoryError、StackOverflowError等。
异常的抛出与捕捉
概述:
在Java程序中,如果发生异常,可以通过抛出异常的方式来传递异常信息,同时也可以通过捕捉异常的方式来处理异常,保证程序的正确执行。
1.抛出异常
在Java中,可以使用throw关键字抛出一个异常对象
语法
throw new Exception();
在抛出异常时,可以将异常对象传递给调用方法,从而将异常信息传递给上层调用方法。
在抛出异常时,可以将异常对象传递给调用方法,从而将异常信息传递给上层调用方法。
2.捕捉异常
在Java中,可以使用try-catch语句来捕捉异常,从而可以处理异常,保证程序的正常运行。try语句的执行过程:先尝试执行try块中的代码,如果代码块中发生了异常,则捕捉异常并执行catch块中的代码,最后执行finally块中的代码(如果有的话)。
语法:
try {
// 可能会抛出异常的代码块
}
catch (Exception e) {
// 捕获并处理异常
}
finally {
// (可选)在try或catch快结束之前,总会执行的代码块
}
在捕捉异常时,使用catch语句来指定要捕捉的异常类型,如果捕捉到匹配的异常,则执行相应的处理代码;如果没有匹配到捕捉的异常,则异常会被传递给上层方法,继续寻找匹配的异常。
// 可能会抛出异常的代码块
}
catch (Exception e) {
// 捕获并处理异常
}
finally {
// (可选)在try或catch快结束之前,总会执行的代码块
}
在捕捉异常时,使用catch语句来指定要捕捉的异常类型,如果捕捉到匹配的异常,则执行相应的处理代码;如果没有匹配到捕捉的异常,则异常会被传递给上层方法,继续寻找匹配的异常。
常见异常类
Java中提供了非常丰富的异常类来处理各种情况下的异常,通常情况下我们只需要使用一些常见的异常类即可。
1.NullPointerException:当应用程序试图访问空引用时,抛出该异常。
2.ArrayIndexOutOfBoundsException:当应用程序试图访问超出数组范围的元素时,抛出该异常。
3.ClassCastException:在对象强制类型转换时,如果对象的实际类型与强制转换的类型不兼容,则抛出该异常。
4.FileNotFoundException:当试图打开不存在的文件时,抛出该异常。
5.IndexOutOfBoundsException:当试图访问列表或字符串中不存在的元素或超出范围时,抛出该异常。
6.NumberFormatException:当试图将字符串转换为数值类型时,如果字符串格式不正确,则抛出该异常。
7.IllegalArgumentException:当参数传递错误或不合法时,抛出该异常。
8.IOException:当试图进行读写文件操作时,如果发生输入输出错误,则抛出该异常。
自定义异常
概述:
除了使用Java提供的现有异常类之外,Java程序员还可以自定义异常类来处理自己的异常情况。
要求:
自定义异常类通常继承于Exception或RuntimeException类(如果是受检查的异常,则继承Exception类,否则继承RuntimeException类),并提供自己的构造器和处理逻辑。自定义异常类通常需要重写父类的两个构造器,即无参构造器和带有字符串信息的构造器,从而可以根据不同的异常情况来创建不同的异常对象。
自定义异常的定义
在自定义异常类中,我们可以定义多个构造方法,以便在不同的场景下使用不同的构造方法来创建异常对象。在创建自定义异常对象时,我们通常需要为异常设置一个状态码和异常信息,用于记录和标识异常的来源和类型。在自定义异常类中,我们可以使用getter和setter方法来访问和设置状态码和异常信息。
示例
try {
// 可能会抛出 MyException 异常的代码
} catch (MyException e) {
// 捕获 MyException 异常,并打印异常信息
System.out.println("MyException caught! code=" + e.getCode() + ", message=" + e.getMessage());
}
// 可能会抛出 MyException 异常的代码
} catch (MyException e) {
// 捕获 MyException 异常,并打印异常信息
System.out.println("MyException caught! code=" + e.getCode() + ", message=" + e.getMessage());
}
作用
自定义异常的好处是可以让我们更加精细地控制和处理异常,同时也可以增加代码的可读性和可维护性。当我们需要处理特定类型或特定场景下的异常时,可以通过自定义异常类来实现。
方法中抛出异常
概述:
在Java中,方法可以抛出异常,表示当前方法无法正常完成其任务。当方法抛出异常时,当前方法停止执行,并将异常抛给调用方处理。调用方可以选择捕获异常并处理,或者将异常继续向上抛出。
使用:
方法可以抛出受检查异常或非受检查异常。受检查异常是指编译器要求我们在编写代码时要处理的异常,必须在方法声明上使用throws语句声明方法可能抛出的异常,或者在方法内部使用try-catch语句进行处理。非受检查异常是指程序在运行时出现的异常,也称运行时异常,在方法声明上可以不使用throws语句声明方法可能抛出的异常。
示例
public void readFile(String fileName) throws IOException {
// 抛出 IOException 异常,表示读取文件时可能出现的异常
FileReader reader = new FileReader(fileName);
// ...
}
// 抛出 IOException 异常,表示读取文件时可能出现的异常
FileReader reader = new FileReader(fileName);
// ...
}
上面的例子中,readFile方法声明可能会抛出IOException异常,表示读取文件时可能出现的异常情况。调用方必须要么捕获这个异常并处理,要么继续向上抛出这个异常。
作用
总之,在Java中使用方法抛出异常可以有效地处理出现的异常情况,避免出现错误结果。但是必须谨慎使用异常,避免在不必要的情况下使用异常,要注意合理使用异常来增强程序的健壮性。
运行时异常
概述
在Java中,除了受检查异常之外,还有一种异常称为运行时异常(RuntimeException)。运行时异常指的是程序在执行过程中出现的异常,通常是由程序员的错误代码所引起的,如数组越界、除数为0等情况。与受检查异常不同的是,当程序抛出运行时异常时,不需要使用try-catch语句进行捕获,也不需要在方法声明上使用throws语句进行声明。也就是代码的逻辑错误导致的异常错误
运行时异常通常是程序员需要修正的代码问题,因为他们通常是可以避免的,在编写时就可以避免的问题。例如,如果程序员在访问数组时检查数组索引的值是否合法,那么就可以避免出现数组越界异常。同样,如果除数为0的情况下检查除数的值是否为0,那么也可以避免出现ArithmeticException异常。
常见运行时异常
除了RuntimeException外,还有几个常见的运行时异常,包括NullPointerException、ClassCastException和IllegalArgumentException。它们分别表示空指针、类型转换错误和非法参数等异常情况。
总结:
总之,在Java中,运行时异常是由程序员的错误代码引起的异常,通常是可以避免的,但在编写代码时仍然需要进行预处理。我们应该尽可能避免出现运行时异常,以提高代码的可靠性和健壮性。
异常的使用原则
1.不要滥用异常:
异常处理的成本相对较高,所以不应该在不必要的情况下滥用异常。只有在真正的异常情况下才应该抛出异常。
2.区分受检查异常和非受检查异常:
在编写代码时应该考虑可能出现的异常情况,并使用try-catch语句或者在方法声明上使用throws语句进行处理。对于受检查异常,我们必须捕获异常并进行处理或者在方法声明上使用throws语句进行声明。对于非受检查异常,可以在代码中进行预防性检查,但不需要在方法声明上使用throws语句进行声明。
3.使用异常层次结构:
Java中异常是一种层次结构,使用异常层次结构可以更好的描述和区分异常情况。在设计自定义异常类时应该继承合适的异常类,并在异常类中提供清晰的异常信息,便于开发人员查错和调试。
4.不要捕获不必要的异常:
在代码中使用try-catch语句捕获异常时,应该捕获真正的异常情况。不要捕获不必要的异常,否则会损害代码的可读性和性能,导致代码难以维护。
5.慎用finally语句块:
finally语句块用于释放资源和设置状态,应该考虑使用try-with-resources语句块或者在finally语句块中释放资源和设置状态。过度使用finally语句块可能会影响代码的可读性和性能。
总结:
总之,在Java中,正确的使用异常可以提高代码的健壮性和可读性。需要根据实际情况选择合适的异常处理方式,并在设计自定义异常类时考虑异常层次结构,便于开发人员查错和调试代码。
10、字符串
概述:
Java中的字符串是一个非常重要的数据类型,它通常被用于处理文本和字符数据。在Java中,字符串是由字符的序列组成的,每个字符都对应一个Unicode编码。
在Java中,可以使用字符串字面值或者String类的构造函数来创建一个字符串对象。
在Java中,可以使用字符串字面值或者String类的构造函数来创建一个字符串对象。
String类
概述:
Java中的String类是一个非常常用的类,用于表示字符串并提供了方便的操作方法。它属于Java的标准库,不需要额外导入即可使用。
特性:
String类是不可变的,在创建后不可修改,它的每个实例都表示一个不可变的字符序列。因为String是不可变的,所以它可以被安全地共享,而且效率也更高。
常用操作
String类常用的操作方法有:字符串拼接、获取子串、查找、替换、转换大小写、去除空格等。它还提供了一些方法来判断字符串的属性,比如长度、是否为空、是否以特定的字符或子串开始、结束等。
String类创建对象
在Java中,可以使用字符串字面值或者String类的构造函数来创建一个字符串对象。
String str1 = "Hello"; // 字符串字面值创建
String str2 = new String("World"); // String构造函数创建
String str2 = new String("World"); // String构造函数创建
字符串连接
在Java中,可以使用“+”符号将两个字符串拼接起来,也可以使用concat()方法来进行字符串拼接。
String str1 = "Hello";
String str2 = "World";
String str3 = str1 + " " + str2; // 字符串拼接
String str4 = str1.concat(" ").concat(str2); // 使用concat()方法进行字符串拼接
String str2 = "World";
String str3 = str1 + " " + str2; // 字符串拼接
String str4 = str1.concat(" ").concat(str2); // 使用concat()方法进行字符串拼接
获取字符串信息
1.获取字符串长度
在Java中String类的底层实现是使用字符数组实现数据存储的,所以获取字符串长度也就是获取该字符数组的长度。
所以在底层,String类封装了一个方法 .length(),用于返回字符串长度。
所以在底层,String类封装了一个方法 .length(),用于返回字符串长度。
String str="123456";
System.out.println(str.length()); // 输出字符串长度6
System.out.println(str.length()); // 输出字符串长度6
2.字符串查找
在Java中,可以使用indexOf()方法或lastIndexOf()方法来查找一个字符串中是否包含某个子串。
String str = "Hello World";
int index1 = str.indexOf("o"); // 查找第一个字符'o'在字符串中的位置,即4
int index2 = str.lastIndexOf("o"); // 查找最后一个字符'o'在字符串中的位置,即7
int index1 = str.indexOf("o"); // 查找第一个字符'o'在字符串中的位置,即4
int index2 = str.lastIndexOf("o"); // 查找最后一个字符'o'在字符串中的位置,即7
3.获取指定索引位置的字符
前文说过,在String类中使用的字符数组存储数据,所以我们要获取指定索引上的字符也是直接操作该字符数组即可。
使用 .charAt(索引) 方法即可。需要注意的是,索引不能小于0且大于等于字符串长度。
String str="abcd";
System.out.println(str.charAt(1)); // 输出字符b
String str="abcd";
System.out.println(str.charAt(1)); // 输出字符b
字符串操作
1.获取子字符串
在Java中,可以使用substring()方法获取一个字符串的子串。
String str = "Hello World";
String subStr1 = str.substring(0, 5); // 获取第0个字符到第4个字符的子串,即"Hello"
String subStr2 = str.substring(6); // 获取第6个字符到最后一个字符的子串,即"World"
String subStr1 = str.substring(0, 5); // 获取第0个字符到第4个字符的子串,即"Hello"
String subStr2 = str.substring(6); // 获取第6个字符到最后一个字符的子串,即"World"
2.去除空格
在Java中,可以使用trim()方法去除一个字符串两端的空格。
String str = " Hello World ";
String newStr = str.trim(); // 去除字符串前后的空格,得到"Hello World"
String newStr = str.trim(); // 去除字符串前后的空格,得到"Hello World"
3.字符串替换
在Java中,可以使用replace()方法来替换一个字符串中的子串。
String str = "Hello World";
String newStr = str.replace("o", "*"); // 将字符串中所有的字符'o'替换成'*',得到"Hell* W*rld"
String newStr = str.replace("o", "*"); // 将字符串中所有的字符'o'替换成'*',得到"Hell* W*rld"
4.字符串比较
在Java中,有两种比较字符串的方法:equals()方法和==运算符。equals()方法会比较两个字符串的内容是否相同,而==运算符则比较两个字符串的地址是否相同。
String str1 = "Hello";
String str2 = "Hello";
String str3 = new String("Hello");
System.out.println(str1.equals(str2)); // true
System.out.println(str1 == str2); // true
System.out.println(str1.equals(str3)); // true
System.out.println(str1 == str3); // false
String str2 = "Hello";
String str3 = new String("Hello");
System.out.println(str1.equals(str2)); // true
System.out.println(str1 == str2); // true
System.out.println(str1.equals(str3)); // true
System.out.println(str1 == str3); // false
5.字符串大小转换
在Java中,可以使用substring()方法获取一个字符串的子串。
String str = "Hello World";
String subStr1 = str.substring(0, 5); // 获取第0个字符到第4个字符的子串,即"Hello"
String subStr2 = str.substring(6); // 获取第6个字符到最后一个字符的子串,即"World"
String subStr1 = str.substring(0, 5); // 获取第0个字符到第4个字符的子串,即"Hello"
String subStr2 = str.substring(6); // 获取第6个字符到最后一个字符的子串,即"World"
6.字符串分割
概述:
在Java中,可以使用split()方法来进行字符串分割。该方法可以把一个字符串按照指定的分隔符分成多个子字符串,并将它们存放到一个字符串数组中。
基本用法
在Java中,使用split()方法可以将一个字符串按照指定的分隔符进行分割。
String str = "Hello,World,Java";
String[] arr = str.split(","); // 将字符串按照逗号分隔成一个字符串数组
分隔符的正则表达式
在Java的split()方法中,可以使用正则表达式作为分隔符。
正则表达式通常用来描述字符串的模式,因此可以根据不同的模式选择不同的分隔符。
正则表达式通常用来描述字符串的模式,因此可以根据不同的模式选择不同的分隔符。
例如,如果要将一个字符串按照空格或逗号进行分割,可以使用以下代码:
String str = "Hello,World Java";
String[] arr = str.split("[ ,]"); // 将字符串按照空格或逗号分隔成一个字符串数组
String str = "Hello,World Java";
String[] arr = str.split("[ ,]"); // 将字符串按照空格或逗号分隔成一个字符串数组
上面的代码中,使用了正则表达式"[ ,]"作为分隔符,这个正则表达式表示空格或逗号。因此,该方法会将字符串按照空格或逗号分割成了三个子字符串,存放在字符串数组arr中。
分隔符的限制
在Java中,split()方法默认将字符串按照所有的分隔符进行分割,但是有时候我们可能只需要分割一定数量的子串,或者只需要分割前几个子串。
这时,可以使用split()方法的重载版本来进行限制。
这时,可以使用split()方法的重载版本来进行限制。
String str = "Hello,World,Java";
String[] arr = str.split(",", 2); // 将字符串按照逗号分隔成前两个子字符串
上面的代码中,使用了split()方法的重载版本,其中第二个参数2表示只分割前两个子字符串。
特殊字符的转义
在Java中,有一些字符是有特殊含义的,例如双引号、单引号和反斜杠等。如果要在分隔符中使用这些特殊字符,需要进行转义。
String str = "Hello\"World\"";
String[] arr = str.split("\""); // 将字符串按照双引号分隔成两个子字符串
上面的代码中,使用了反斜杠对双引号进行转义,这样split()方法就可以正确地将字符串按照双引号分割成了两个子字符串。
总结
split()方法是Java中常用的字符串分割方法,掌握了该方法的使用,可以更好地完成字符串处理的任务。
格式化字符串
在Java中,可以通过SimpleDateFormat类来进行日期和时间字符串的格式化,该类可以将日期和时间格式化成指定的字符串格式。
1.SimpleDateFormat类
SimpleDateFormat类是Java中用于解析和格式化日期和时间字符串的一个类。该类提供了一组格式化日期和时间的方法,可以将日期和时间格式化成指定的字符串格式。
构造方法
SimpleDateFormat(String pattern):构造一个SimpleDateFormat对象,使用指定的模式pattern。
String format(Date date):将日期和时间格式化成指定的字符串格式。
String format(Date date):将日期和时间格式化成指定的字符串格式。
示例
// 输出当前日期的字符串形式
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
System.out.println(sdf.format(new Date()));
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
System.out.println(sdf.format(new Date()));
上面的代码中,SimpleDateFormat(“yyyy-MM-dd”)表示df采用的日期格式是"年-月-日"。
2.日期/时间格式化符号
在SimpleDateFormat中,要将一个日期或时间格式化成指定的字符串格式,必须使用一些日期/时间格式化符号。下面列出了一些常用的符号:
y: 年(例如:2022)
M: 月(例如:12或12月)
d: 日(例如:25)
H: 24小时制的小时数(例如:13)
h:12小时制的小时数(例如:1或01)
m: 分钟(例如:33)
s: 秒(例如:49)
S: 毫秒(例如:513)
M: 月(例如:12或12月)
d: 日(例如:25)
H: 24小时制的小时数(例如:13)
h:12小时制的小时数(例如:1或01)
m: 分钟(例如:33)
s: 秒(例如:49)
S: 毫秒(例如:513)
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
System.out.println(sdf.format(new Date()));
System.out.println(sdf.format(new Date()));
上面的代码中,SimpleDateFormat(“yyyy-MM-dd HH:mm:ss.SSS”)表示该日期格式是"年-月-日 时:分:秒.毫秒"。
3.日期/时间格式化的格式控制
在SimpleDateFormat中,还可以通过使用一些格式控制符来控制日期/时间的格式化方式
E: 星期几(例如:Mon,Tue等)
D:一年的第几天(例如:365)
F:一月中的第几个星期几(例如:2,代表某个月的第二个星期二)
w:一年中的第几个星期
W:一月中的第几个星期(每个月的第一周从哪一天开始)
D:一年的第几天(例如:365)
F:一月中的第几个星期几(例如:2,代表某个月的第二个星期二)
w:一年中的第几个星期
W:一月中的第几个星期(每个月的第一周从哪一天开始)
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd E HH:mm:ss");
System.out.println(sdf.format(new Date()));
上面的代码中,SimpleDateFormat(“yyyy-MM-dd E HH:mm:ss”)表示该日期格式是"年-月-日 星期几 时:分:秒"。
System.out.println(sdf.format(new Date()));
上面的代码中,SimpleDateFormat(“yyyy-MM-dd E HH:mm:ss”)表示该日期格式是"年-月-日 星期几 时:分:秒"。
综上所述,通过SimpleDateFormat类,可以方便地将日期和时间格式化成指定的字符串格式。需要注意的是,在使用日期和时间格式化符号时,必须使用正确的大写字母或小写字母,否则将会产生错误的结果。
字符串生成器:StringBuilder类
概述
StringBuilder 类用于处理字符串的可变操作,可以将多个字符串拼接成一个字符串,也可以对一个字符串进行增删改等操作。StringBuilder 类是线程非安全的,适用于单线程环境下的字符串拼接操作。
常用方法
append():添加字符串,可以传入各种类型的参数,包括 boolean、char、int、float、double 等。
insert():在指定位置插入字符串,可以传入各种类型的参数。
delete():删除指定位置的字符串,可以对多个字符进行删除操作。
replace():替换指定位置的字符串。
substring():截取指定位置的字符串。
reverse():反转字符串。
toString():将StringBuilder变量中数据转换成String类变量进行返回。
StringBuilder 和 StringBuffer 的区别
StringBuilder 和 StringBuffer 类的用法和功能基本相同,但是 StringBuilder 更快,如果确保在单线程环境下使用,建议使用 StringBuilder 类。而 StringBuffer 类是线程安全的,适用于多线程环境下的字符串操作。
StringBuilder 类的应用
1、用于字符串拼接:StringBuilder 可以高效地进行字符串拼接操作,而不会创建多个中间字符串对象。
2、优化字符串处理性能:预先为 StringBuilder 对象分配一定的容量,可以提高字符串处理的性能。
3、用于替代拼接字符串的“+”操作符:在多个字符串需要拼接时,应尽量使用 StringBuilder、StringBuffer 等字符串可变类,而不是直接使用“+”操作符,以提高效率。
总结:
综上所述,StringBuilder 类提供了一组高效的可变字符串操作接口,能够满足开发中的大多数字符串操作需求。在开发中,应根据实际情况进行正确的使用和选择。
11、常用类库
包装类
概述
Java中提供了8种基本数据类型,每种基本类型都对应一个包装类,包装类实现了将基本数据类型转换为对象的功能。根据Java规范,所有继承Hierarchy of Numeric Classes层次结构的包装类都是不可变(final),因此,包装类的对象创建后,其值不可变,每次修改包装类的值都会创建一个新的对象。
基本数据类型 对应的包装类
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
boolean Boolean
自动装箱和拆箱
Java 5引入了自动装箱和拆箱的机制,自动装箱是将一个基本类型转换为对应的包装类对象,自动拆箱是将一个包装类对象转换为对应的基本类型,代码会根据需要自动进行转换,无需手动显式地调用构造函数或valueOf()方法。
// 例如
int i = 100;
Integer integer = i;//自动装箱
int j = integer;//自动拆箱
int i = 100;
Integer integer = i;//自动装箱
int j = integer;//自动拆箱
包装类的方法
1、xxxValue(): 将包装类转换为基本数据类型,其中xxx代表int、long、float等类型。
2、valueOf(): 将一个基本类型的值转换为对应的包装类对象。
3、toString(): 将包装类对象转换为字符串。
4、compareTo(): 比较两个数的大小,返回一个整数。
5、equals(): 比较两个数是否相等,返回一个布尔值。
6、hashCode(): 返回包装类的哈希码。
7、MAX_VALUE: 返回极大值。
8、MAX_VALUE: 返回极大值。
9、NaN: 获取不是数字的值。
10、POSITIVE_INFINITY: 无穷大的值。
NEGATIVE_INFINITY: 无穷小的值。
NEGATIVE_INFINITY: 无穷小的值。
适用场景
集合框架中的集合元素必须是对象类型,不能是基本数据类型,因此在使用集合时,需要将基本数据类型封装为对应的包装类对象。
在某些框架或API中,只能够使用对象类型而不能使用基本数据类型。
对象类型可以存储null值,因此在需要对数据进行判空的场合,使用包装类更为灵活。
总结
综上所述,Java中的包装类可以用于将基本数据类型转换为对象,同时还提供了一组常用的方法,方便进行各种数值操作。在实际开发中,包装类有多种应用场景,能够极大地方便Java程序员进行各种数据处理。
数字处理
数字格式化
在Java中,数字格式化是指将数字按照不同的格式进行展示或者输出的过程。Java中提供了NumberFormat类,可以用于格式化数字,使其符合不同的格式要求。
NumberFormat是一个抽象类,Java提供了两个具体实现类:DecimalFormat和NumberFormat实现类。
NumberFormat是一个抽象类,Java提供了两个具体实现类:DecimalFormat和NumberFormat实现类。
DecimalFormat类
DecimalFormat类是一个具体实现类,可以用来定义数值格式。
在使用DecimalFormat类时,首先需要创建一个新的对象,然后使用setGroupingSize()方法设置数字分组大小,最后使用format()方法将数字格式化为指定格式。
// 示例
DecimalFormat decimalFormat = new DecimalFormat("#,###.##");
System.out.println(decimalFormat.format(123456789.1234));
DecimalFormat decimalFormat = new DecimalFormat("#,###.##");
System.out.println(decimalFormat.format(123456789.1234));
输出结果:123,456,789.12
在上述示例中,使用“#,###.##”定义了数字的格式,其中“#”表示数字位(有数字则显示,没有则不显示),“,”表示数字分组,最后两个“#”表示小数点后最多显示两位小数。
在上述示例中,使用“#,###.##”定义了数字的格式,其中“#”表示数字位(有数字则显示,没有则不显示),“,”表示数字分组,最后两个“#”表示小数点后最多显示两位小数。
NumberFormat实现类
NumberFormat类提供了一些静态方法,用于根据当前或指定的地区创建NumberFormat实现类的实例。
// 示例
NumberFormat numberFormat = NumberFormat.getInstance();
System.out.println(numberFormat.format(123456789.1234));
NumberFormat numberFormat = NumberFormat.getInstance();
System.out.println(numberFormat.format(123456789.1234));
输出结果:123,456,789.1234
在上述示例中,使用getInstance()方法创建了一个默认的NumberFormat实例。
NumberFormat类还提供了format()方法用于格式化数字,并且支持指定格式、设置分组大小、保留小数位数等。
总结:NumberFormat是Java中格式化数字的一种工具,在实际开发中,可以使用其提供的方法以各种方式展示和处理数字,例如在输出复杂的报表、价格显示等方面都非常方便。
Math类
在Java中,Math类是用来进行数学运算的标准类之一,它提供了一系列的静态字段和方法来执行各种数学运算。Math类中的方法和属性都是静态的,就是说可以直接通过类名调用它们,而不需要创建Math类的对象。
常用属性
PI: 圆周率pi的常数,用于计算圆或球的周长、面积、体积等。
E: 自然常数e的基数,用于计算指数函数和自然对数函数。
MAX_VALUE: 可表示的最大值。
MIN_VALUE: 可表示的最小值。
NaN: 表示不是一个数字的值。
POSITIVE_INFINITY: 表示正无穷大的值。
NEGATIVE_INFINITY: 表示负无穷大的值。
常用方法
Math类提供了一系列常用的数学函数方法,这些方法都是静态的,使用方式为:类名.方法名(参数1,参数2…),其中参数可以为各种数值类型。
abs(x): 返回x的绝对值。
pow(x,y): 返回x的y次幂。
sqrt(x): 返回x的平方根。
cbrt(x): 返回x的立方根。
ceil(x): 返回大于等于x的最小整数值。
floor(x): 返回小于等于x的最大整数值。
round(x): 返回最接近x的长整数值。
random(): 返回一个随机数(浮点型),大于等于0.0且小于1.0。
sin(x): 返回x的正弦值(x的单位为弧度)。
cos(x): 返回x的余弦值(x的单位为弧度)。
tan(x): 返回x的正切值(x的单位为弧度)。
atan2(y,x): 根据x、y坐标值求出该点与原点的连线与x轴正方向之间的夹角(0~2*Pi之间)。
max(x,y): 返回x和y中的最大值。
min(x,y): 返回x和y中的最小值。
常见数学函数
在Math类中,还提供了一些常见的函数,例如三角函数、指数函数、对数函数等。这些函数将直接返回计算结果,方便进行各种数学计算。
下面列举一些常见的常函数:
Math.acos()
Math.asin()
Math.atan()
Math.toDegrees()
Math.toRadians()
Math.exp()
Math.log()
Math.log10()
Math.pow()
Math.sin()
Math.cos()
Math.tan()
综上所述,Math类提供了一系列的静态方法和属性,可以对各种数值进行处理和计算,在实际开发中非常有用。需要注意的是,在进行类似于小数的计算需要特别注意舍入误差问题。
Random类
概述
在Java中,Random类是用于生成随机数的一个实用类,可以生成各种类型的随机数,包括整数、浮点数、布尔值等。它提供了几种创建随机数的方法,以及一些生成随机数的辅助方法。
创建随机数
使用无参构造函数创建Random实例,以当前时间为随机数种子。
Random random = new Random();
Random random = new Random();
使用带long类型参数的构造函数创建Random实例,以指定的long值为随机数种子。
Random random = new Random(123456);
Random类提供了几个生成随机数的方法
Random类提供了几个生成随机数的方法
方法名 返回值类型 说明
nextBoolean boolean 随机生成一个boolean类型的值,true或false。
nextByte byte 随机生成一个byte类型的值,取值范围为-128~127。
nextInt int 随机生成一个int类型的值,取值范围为-2147483648~2147483647。
nextLong long 随机生成一个long类型的值,取值范围为-9223372036854775808~9223372036854775807。
nextFloat float 随机生成一个float类型的值,取值范围为0.0~1.0。
nextDouble double 随机生成一个double类型的值,取值范围为0.0~1.0。
nextGaussian double 随机生成一个服从正态分布的double类型的值。
nextBoolean boolean 随机生成一个boolean类型的值,true或false。
nextByte byte 随机生成一个byte类型的值,取值范围为-128~127。
nextInt int 随机生成一个int类型的值,取值范围为-2147483648~2147483647。
nextLong long 随机生成一个long类型的值,取值范围为-9223372036854775808~9223372036854775807。
nextFloat float 随机生成一个float类型的值,取值范围为0.0~1.0。
nextDouble double 随机生成一个double类型的值,取值范围为0.0~1.0。
nextGaussian double 随机生成一个服从正态分布的double类型的值。
生成指定范围内的随机数
Random类提供了生成指定范围内的随机数的方法
nextInt(int n): 生成一个大于等于0小于n的随机整数。
nextInt(int min, int max):生成一个大于等于min小于max的随机整数。
nextDouble(double min, double max): 生成一个大于等于min小于max的随机双精度浮点数。
BigInteger类
在Java中,BigInteger类是为了处理大整数而设计的一个类。它提供了一系列的方法操作大整数,可用于实现高精度的数值计算。
创建BigInteger对象
通过静态方法valueOf()创建
BigInteger bigInteger = BigInteger.valueOf(1234567890L);
通过字符串创建
BigInteger bigInteger = new BigInteger("1234567890123456789");
通过字节数组创建
byte[] bytes = new byte[]{(byte) 0x12, (byte) 0x34, (byte) 0x56};
BigInteger bigInteger = new BigInteger(bytes);
常用方法
add(): 返回两个大整数相加的结果。
subtract(): 返回两个大整数相减的结果。
multiply(): 返回两个大整数相乘的结果。
divide(): 返回两个大整数相除的结果,如果除数为0,则会抛出异常。
mod(): 返回除法操作的余数。
pow(): 返回大整数的幂。
compareTo(): 比较两个大整数的大小,如果当前对象小于、等于或大于指定对象,则分别返回负整数、零或正整数。
toString(): 返回大整数的字符串表示。
intValue(): 返回大整数的int型数值。
longValue(): 返回大整数的long型数值。
需要注意的是,大整数计算的效率相对较低,因此在实际开发中,应该减少不必要的大整数计算,尽量使用基本数据类型进行计算。
综上所述,BigInteger类是Java中一个非常实用的类,可用于处理大整数,通过提供一系列的方法来进行数值计算。在实际开发中,应该谨慎使用BigInteger类,尽可能减少不必要的计算。
BigDecimal类
在Java中,BigDecimal类是用于实现高精度小数运算的类,与double和float类型相比,它的精度更高,可以有效避免由舍入误差引起的计算错误。BigDecimal类的方法可以按照任意精度进行计算,因此它在商业、金融等领域中非常有用。
创建BigDecimal对象
直接传入字符串
BigDecimal bigDecimal = new BigDecimal("123456.789");
传入double或float类型的值
double d = 123456.789;
BigDecimal bigDecimal = new BigDecimal(d);
传入BigInteger类型的值
BigInteger bigInteger = new BigInteger("1234567890123456789");
BigDecimal bigDecimal = new BigDecimal(bigInteger);
常用方法
add(): 返回两个BigDecimal对象相加的结果。
subtract(): 返回两个BigDecimal对象相减的结果。
subtract(): 返回两个BigDecimal对象相减的结果。
divide(): 返回两个BigDecimal对象相除的结果,可以指定小数保留位数和标志位。
abs(): 返回BigDecimal对象的绝对值。
compareTo(): 比较两个BigDecimal对象的大小,如果当前对象小于、等于或大于指定对象,则分别返回负整数、零或正整数。
综上所述,BigDecimal类是Java中一个非常实用的类,可用于实现高精度小数运算,通过提供一系列的方法来进行数值计算。在实际开发中,应该谨慎使用BigDecimal类,尽可能减少不必要的计算,以提高效率。
System类
Java中的System类提供了一些方法,可以让我们快捷地访问系统层面的资源,例如标准输入、标准输出、标准错误输出和环境变量等。系统类中的方法大部分是静态方法,因此可以直接通过类名调用。
标准输入输出流
System类提供了三个标准输入输出流
System类提供了三个标准输入输出流
System.out:标准输出流,它是PrintStream类型的对象。
System.out:标准输出流,它是PrintStream类型的对象。
System.in:标准输入流,它是InputStream类型的对象。
可以通过这些流实现与用户的交互。
System.out.println("Hello, world!");
System.err.println("Error occurred!");
Scanner scanner = new Scanner(System.in);
String input = scanner.nextLine();
System.out.println("Hello, world!");
System.err.println("Error occurred!");
Scanner scanner = new Scanner(System.in);
String input = scanner.nextLine();
数组拷贝
System类提供了一个用于数组拷贝的静态方法System.arraycopy(),它可以将源数组中的指定元素拷贝到目标数组中的指定位置。
char[] src = {'a', 'b', 'c', 'd', 'e'};
char[] dest = new char[5];
System.arraycopy(src, 1, dest, 0, 3);
System.out.println(Arrays.toString(dest)); // 输出结果为:[b, c, d, , ]
环境变量
System类提供了一个用于获取和设置环境变量的方法
getenv(String name):根据指定的环境变量名获取环境变量的值。
setenv(String name, String value, boolean overwrite):设置环境变量的值。
需要注意的是,setenv()方法并不是在所有的平台上都可用。
系统退出
System类提供了一个用于退出JVM的静态方法System.exit(),可以在程序运行过程中强制退出JVM,并且返回一个状态码。
System.exit(0); // 结束程序,并返回状态码0
需要注意的是,在使用System.exit()方法时应谨慎,因为它会立即结束程序的运行,可能出现未保存数据的情况。
综上所述,System类提供了一些静态方法,可以让我们方便地访问系统层面的资源和操作系统相关的功能。在实际开发中,应该合理使用System类的方法,以便更加高效地完成各种任务。
Scanner类
Scanner类是Java中常用的输入类,主要用于从控制台或文件中读取数据,可以读取多种类型的输入数据,包括数值型、字符串型等。
Scanner类的实例化需要一个输入流,可以是从文件或控制台中读取输入
读取方式
从控制台中读取输入
Scanner scanner = new Scanner(System.in);
String input = scanner.nextLine(); // 读取输入的一行字符串
从文件中读取输入
Scanner scanner = new Scanner(new File("example.txt"));
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
// ...
}
scanner.close();
从字符串中读取输入
String input = "1,3,5,7,9";
Scanner scanner = new Scanner(input).useDelimiter(",");
while (scanner.hasNextInt()) {
int num = scanner.nextInt();
// ...
}
scanner.close();
Scanner类的常用方法有:
hasNextXxx():判断是否有下一个类型为Xxx的输入,返回布尔类型。
nextXxx():读取下一个类型为Xxx的输入,返回对应的值,如果输入类型错误会抛出异常。
hasNextLine():判断是否有下一行输入,返回布尔类型。
hasNextLine():判断是否有下一行输入,返回布尔类型。
close():关闭Scanner对象关联的输入流。
需要注意的是,Scanner类在读取输入时会根据不同类型进行转换,如果输入类型不匹配会抛出异常。为了避免这种情况,我们可以先使用hasNextXxx() 进行类型判断,确保输入类型与所期望的类型一致。
综上所述,Scanner类是Java中常用的一个输入类,可以用来读取从控制台或文件中输入的数据,支持多种类型的输入。在实际开发中,应该根据需要合理使用Scanner类的方法,以实现各种输入操作。
日期时间类
Date类
Java中的Date类是一个表示日期和时间的类,它封装了一个long型的表示自1970年1月1日以来的毫秒数。虽然Date类在Java中已经存在了很多年,但由于它设计得不是很好,在实际开发中使用得比较少。建议使用Java 8之后的新日期时间API(java.time包)中提供的类来代替Date类。
常用方法
Date():创建一个表示当前日期和时间的Date对象。
Date(long milliseconds):根据毫秒数创建一个Date对象。
getTime():返回自1970年1月1日以来的毫秒数。
setTime(long milliseconds):设置Date对象的毫秒数。
before()、after():比较两个Date对象的大小。
toString():返回日期时间的字符串表示。
需要注意的是,Date类存在线程安全的问题,同时它只能精确到毫秒级别,不支持处理时区和夏令时等问题。在Java 8之后,建议使用新日期时间API中的类进行日期和时间的处理。
日期时间格式化
Java中日期时间格式化的相关知识主要与SimpleDateFormat类和DateTimeFormatter类有关。
SimpleDateFormat类
SimpleDateFormat类是Java中提供的一个日期时间格式化类,可以将Date对象格式化为指定格式的字符串,也可以将字符串解析为Date对象。格式化字符串中使用特定的字母代表不同的日期时间元素。
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String dateStr = sdf.format(new Date()); // 格式化为"2022-06-28 14:35:48"格式的字符串
Date date = sdf.parse(dateStr); // 将字符串解析为Date对象
需要注意的是,SimpleDateFormat类是线程不安全的,不应该在多线程环境下共享实例。
DateTimeFormatter类
Java 8之后,引入了新的日期时间API,其中的DateTimeFormatter类提供了更加丰富和安全的日期时间格式化机制。它也可以将日期时间格式化为字符串,也可以将字符串解析为日期时间对象。
LocalDateTime dateTime = LocalDateTime.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String dateStr = dateTime.format(formatter); // 格式化为"2022-06-28 14:35:48"格式的字符串
LocalDateTime dateTime1 = LocalDateTime.parse(dateStr, formatter); // 将字符串解析为LocalDateTime对象
需要注意的是,DateTimeFormatter是线程安全的,可以在多线程环境下共享实例,但是它不支持旧版的日期时间API,如Date、Calendar等。
在实际开发中,我们应该根据具体的需求选择使用不同的日期时间格式化方式。如果是Java 8及以上版本,推荐使用DateTimeFormatter类;如果使用的是旧版的Java,则可以使用SimpleDateFormat类。
Calendar类
Java中的Calendar类是一个抽象类,提供了对日期和时间进行操作的方法,包括添加、减少、比较等。Calendar类允许进行日期时间字段之间的操作,如年、月、日、小时、分钟和秒。Calendar类是一个抽象类,不能直接实例化,需要使用它的子类进行实例化,常用的子类有GregorianCalendar类。
常用方法
getInstance():获取Calendar类的实例,根据默认时区和区域设置获取一个日历。
Calendar cal = Calendar.getInstance(); // 获取Calendar类实例
set():设置Calendar对象某个字段的值。
cal.set(Calendar.YEAR, 2022); // 设置年份为2022
cal.set(Calendar.MONTH, Calendar.JUNE); // 设置月份为6月(注意,月份是从0开始计数的)
cal.set(Calendar.DAY_OF_MONTH, 28); // 设置日期为28日
get():获取Calendar对象某个字段的值。
int year = cal.get(Calendar.YEAR); // 获取当前年份
int month = cal.get(Calendar.MONTH); // 获取当前月份
int day = cal.get(Calendar.DAY_OF_MONTH); // 获取当前日期
add():对Calendar对象某个字段进行加减操作。
cal.add(Calendar.YEAR, 1); // 日期加上1年
cal.add(Calendar.MONTH, 6); // 日期加上6个月
setTime():使用指定的Date对象设置Calendar对象的时间。
Date date = new Date();
cal.setTime(date); // 使用指定的Date对象设置Calendar对象的时间
需要注意的是,Calendar类的字段(例如年、月、日等)是从0开始计数的,月份的范围是0-11,天数的范围是1-31。同时,Calendar类存在线程安全的问题,不宜在多线程环境下使用。
Runtime类
概述:
在Java中,Runtime类表示当前Java应用程序的运行时环境,可以用来执行操作系统中的其他进程并与之交互。Runtime类只有一个实例,并通过静态方法getRuntime()返回它,因此无需创建新的实例。
常用方法
exec()方法: exec(String command)和exec(String[] cmdarray)方法可以在Java程序中启动其他进程,并与之交互。这两个方法都返回一个Process对象,可以通过它来向进程发送输入数据,读取进程的输出结果以及错误信息等。其中,exec(String command)方法将参数字符串解释为命令行的一部分,执行一个进程;exec(String[] cmdarray)方法接收一个字符串数组,表示命令及其参数。
totalMemory() 和 freeMemory()方法: totalMemory()方法返回Java虚拟机的总内存量,freeMemory()方法返回Java虚拟机的空闲内存量。
maxMemory()方法: 返回Java虚拟机可以使用的最大内存量。
执行本地命令方法
Runtime.getRuntime().exec(String command)方法:该方法启动新进程执行指定的命令,并返回表示该进程的Process对象。在本地执行一些命令非常方便,如打开文本编辑器、执行一些简单的命令等等。
Runtime.getRuntime().exec(String[] cmdarray)方法:该方法与exec(String command)类似,只是需要传递一个字符串数组代替一个单一的命令字符串。
说明:上述代码中的new String[]{"cmd", "/c", "dir"}等价于字符串数组{"cmd", "/c", "dir"}。
其中,/c是cmd执行时的一个选项,表示执行完该命令后关闭cmd。
其中,/c是cmd执行时的一个选项,表示执行完该命令后关闭cmd。
这些方法可以用于监控Java虚拟机的内存使用情况,并根据需要进行内存管理。需要注意的是,在计算机硬件内存受限的情况下,如果JVM占用的内存过大,可能会影响性能甚至导致系统崩溃,因此在使用这些方法时应进行谨慎处理。
查看内存方法
除了执行本地命令外,Runtime类还提供了一些方法用于获取当前Java虚拟机的内存信息。
Runtime.getRuntime().totalMemory()方法:该方法返回当前Java虚拟机的堆总量。
// 获取当前JVM堆内存总量
long totalMemory=Runtime.getRuntime().totalMemory();
Runtime.getRuntime().freeMemory()方法:该方法返回当前Java虚拟机的实际空闲内存量。
// 获取当前JVM空闲内存量
long freeMemory=Runtime.getRuntime().freeMemory();
Runtime.getRuntime().maxMemory()方法:该方法返回Java虚拟机可以使用的最大内存量,即Java虚拟机在运行过程中最多可以使用的内存量。
// 获取当前JVM最大内存量
long maxMemory=Runtime.getRuntime().maxMemory();
这些方法可以用于监控Java虚拟机的内存使用情况,并根据需要进行内存管理。需要注意的是,在计算机硬件内存受限的情况下,如果JVM占用的内存过大,可能会影响性能甚至导致系统崩溃,因此在使用这些方法时应进行谨慎处理。
需要注意的是,Runtime类的方法都是与操作系统相关的,因此在不同的操作系统中可能会有所不同。另外,由于使用Runtime类的方法可能会带来一些风险,因此在程序中使用时需要谨慎处理,避免出现不必要的问题。
0 条评论
下一页