Java知识总结(全!)--持续更新中

不定期更新

第一篇

1.1 前言

作为一名计算机专业的大学生,经常在网上找学习资料和笔记,学习Java,在此总结一点Java基础的学习经验,作为一个萌新博主,有不足的地方还请大家指出。

1.2 Java背景

Java是一种面向对象的编程语言,最初由Sun Microsystems于1995年发布。它是一种跨平台的语言,可以在不同的操作系统上运行,如Windows、Linux和Mac OS。Java被广泛用于Web应用程序、移动应用程序、桌面应用程序、游戏开发、企业应用程序等领域。它的特点包括可移植性、安全性、可靠性和易学性。

1.3 Java方向

Java SE:Standard Edition

Java SE 以前称为 J2SE。它允许开发和部署在桌面、服务器、嵌入式环境和实时环境中使用的 Java 应用程序。Java SE 包含了支持 Java Web 服务开发的类,并为Java EE和Java ME提供基础。

Java EE:Enterprise Edition

Java EE 以前称为 J2EE。企业版本帮助开发和部署可移植、健壮、可伸缩且安全的服务器端Java 应用程序。Java EE 是在 Java SE 的基础上构建的,它提供 Web 服务、组件模型、管理和通信 API,可以用来实现企业级的面向服务体系结构(service-oriented architecture,SOA)和Web2.0应用程序。

Java ME:Micro Edition

Java ME 以前称为 J2ME。Java ME 为在移动设备和嵌入式设备(比如手机、PDA、电视机顶盒和打印机)上运行的应用程序提供一个健壮且灵活的环境。Java ME 包括灵活的用户界面、健壮的安全模型、许多内置的网络协议以及对可以动态下载的连网和离线应用程序的丰富支持。基于 Java ME 规范的应用程序只需编写一次,就可以用于许多设备,而且可以利用每个设备的本机功能。

1.4 Java开发工具

Sublume Text文本编辑器(初学者建议使用,帮助你对代码理解)

eclipse

IDEA(本人使用,方便快捷)

IDEA安装请按照下面博主的博客IntelliJ IDEA安装教程(超详细)_intellijidea安装教程_蓝多多的小仓库的博客-CSDN博客

版权声明:本文为CSDN博主「蓝多多的小仓库」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_43554335/article/details/121928344

1.5 Java运行机制

Java核心机制-Java虚拟机(JVM):JVM(Java Virtual Machine)是Java虚拟机的缩写,是Java程序的运行环境。它是一个虚拟的计算机,具有自己的指令集和堆栈,可以在不同的操作系统上运行Java程序。JVM负责将Java源代码编译成字节码,然后在运行时解释执行字节码。JVM还提供了垃圾回收、内存管理等功能,使得Java程序具有良好的跨平台性和安全性。

Java 程序运行机制包括以下几个步骤:

  1. 首先,Java 编译器将源代码编译成字节码,也就是.class文件。
  2. 然后,Java虚拟机(JVM)将字节码加载到内存中。
  3. JVM会对字节码进行校验,以确保它的完整性和正确性。
  4. 当字节码加载完成后,JVM会为程序中的每个类和接口创建一个运行时类对象,并将它们保存在方法区中。
  5. JVM会为程序中的每个方法创建一个运行时方法对象,并将它们保存在方法区中。
  6. 当JVM启动程序时,它会为main方法创建一个运行时方法对象,并将其加载到虚拟机栈中。
  7. JVM会执行main方法中的代码,并处理程序中出现的任何异常。
  8. 当main方法执行完毕后,JVM会将其从虚拟机栈中弹出,并终止程序的执行。

Java 运行机制的主要特点是跨平台性。在任何支持Java的操作系统上,都可以运行由Java编写的程序,只要在该系统上安装了Java虚拟机。

如果对JVM有兴趣的同学可以看一看下面这位博主的博客

一篇文章掌握整个JVM,JVM超详细解析!!!_小杰要吃蛋的博客-CSDN博客
版权声明:本文为CSDN博主「小杰要吃蛋」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_43122090/article/details/105093777

1.6 JDK、JRE

JDK(Java Development Kit)是Java开发工具包,包含了Java编译器、Java虚拟机、Java API等开发工具和库。

JRE(Java Runtime Environment)是Java运行时环境,包含了Java虚拟机和Java API等运行时工具和库。JDK包含了JRE,但JRE不包含JDK。如果你只是想运行Java程序,只需要安装JRE即可;如果你想开发Java程序,需要安装JDK。

在这里插入图片描述

JDK安装请参照下面博主的博客JDK安装教程(有图详解)_叼着奶瓶瓶敲代码的博客-CSDN博客

版权声明:本文为CSDN博主「叼着奶瓶瓶敲代码」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/R_Y_Fren/article/details/120438636

1.7 Java入门

项目需求:写一个Java程序,输出Hello,World!

public static void main(String[] args){
  System.out.println("Hello World");
}

1.8 Java源程序执行流程

一个java程序的执行按照以下的步骤进行

大纲编辑源代码(.java)

将源代码.java编译成字节码文件.class

java虚拟机对字节码文件进行解析执行输出结果。

在这里插入图片描述

1.9 Java转义字符

Java常用的转义字符

\t:一个制表位,实现对齐的功能

\n:换行符

\\:一个\

\":一个’’

\‘:一个’

\r:一个回车

1.10 Java注释

1)单行注释 //
格式://注释文字
2)多行注释
/*
代码块
/
3)文档注释
/
*
文档注释标签:注释文字
*/
常见的Java标签

标签作用示例
@author标识一个类的作者@author description
@return说明返回值类型@return exp
@param说明一个方法的参数@param parameter-name exp
@exception标志一个类抛出的异常@exception exception-name exp
@serial说明一个序列化属性@serial description

官方帮助文档
javadoc

2.1 从控制台读取输入

Java中的Scanner类是用于读取用户输入或文件内容的工具类。可以通过Scanner类的构造函数创建一个Scanner对象,并使用该对象的方法来读取输入或文件内容。Scanner类在包java.util中

以下是Scanner类的一些常用方法:

next():读取下一个以空格分隔的字符串。
nextLine():读取下一行字符串。
nextInt():读取下一个整数。
nextFloat():读取下一个浮点数。
nextDouble():读取下一个双精度浮点数。
hasNext():判断是否还有下一个输入项。
hasNextLine():判断是否还有下一行输入。

import java.util.Scanner;

public class ScannerDemo {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入一个字符串: ");
        String str = scanner.next();
        System.out.println("输入的字符串为: " + str);
        scanner.close();
    }
}
/*以上代码创建了一个Scanner对象,从控制台读取用户输入的字符串,
并输出到控制台。需要注意的是,在读取完输入后,
应该调用Scanner对象的close()方法关闭输入流*/

2.2 标识符

Java中的标识符是用来标识变量、方法、类、接口等程序元素的名称。标识符的命名必须遵循一定的规则:

  • 标识符只能由字母、数字、下划线和美元符号($)组成,且不能以数字开头。

  • Java中的标识符是区分大小写的,因此myVar和myvar是两个不同的标识符。

  • 命名标识符时要使用有意义的名称,可以使用驼峰命名法来命名变量和方法,即第一个单词的首字母小写,后面每个单词的首字母大写,例如myVariableName。

  • 对于类名,建议使用首字母大写的方式来命名,例如MyClassName。

  • 标识符不能是保留字

遵守良好的标识符命名规则可以提高代码的可读性和可维护性。同时,也可以避免由于命名不规范而导致的代码错误和混淆

2.3 Java关键字

Java中的关键字是指具有特殊含义的单词,它们不能被用作标识符名称。这些关键字在Java语言中有着特殊的作用,例如用于控制流程、定义类、变量和方法等。

以下是一些Java关键字的介绍:

  1. abstract:用于定义抽象类和抽象方法。
  2. assert:用于测试代码的正确性。
  3. boolean:用于定义布尔类型的变量和值。
  4. break:用于跳出循环或switch语句。
  5. byte:用于定义字节类型的变量和值。
  6. case:用于定义switch语句的分支。
  7. catch:用于捕获异常。
  8. char:用于定义字符类型的变量和值。
  9. class:用于定义类。
  10. const(已经废弃):用于定义常量,但已经被final关键字所取代。
  11. continue:用于跳过循环中的某个迭代。
  12. default:用于定义switch语句的默认分支。
  13. do:用于定义do-while循环。
  14. double:用于定义双精度浮点数类型的变量和值。
  15. else:用于定义if语句的否定分支。
  16. enum:用于定义枚举类型。
  17. extends:用于定义类的继承关系。
  18. final:用于定义常量、方法和类,表示它们不能被修改或继承。
  19. finally:用于定义异常处理的最终代码块。
  20. float:用于定义单精度浮点数类型的变量和值。
  21. for:用于定义for循环。
  22. goto(已经废弃):用于无条件跳转语句,但已经被Java禁用。
  23. if:用于定义条件语句。
  24. implements:用于实现接口。
  25. import:用于导入其他包中的类。
  26. instanceof:用于测试一个对象是否是一个类的实例。
  27. int:用于定义整数类型的变量和值。
  28. interface:用于定义接口。
  29. long:用于定义长整数类型的变量和值。
  30. native:用于声明本地方法。
  31. new:用于创建一个新的对象。
  32. package:用于定义包。
  33. private:用于定义私有成员。
  34. protected:用于定义受保护的成员。
  35. public:用于定义公共成员。
  36. return:用于返回值。
  37. short:用于定义短整数类型的变量和值。
  38. static:用于定义静态成员。
  39. strictfp:用于定义精确浮点计算。
  40. super:用于调用父类的构造方法

2.4 变量

变量用于表示在程序中可能被改变的值

Java中的变量还可以被分为实例变量和局部变量。实例变量是定义在类中、方法外部的变量,它们属于类的实例,每个实例都有自己的实例变量。局部变量是定义在方法内部的变量,它们只在方法内部可用,离开方法后就被销毁了。

Java中还有一种特殊的变量,叫做静态变量,它们被定义为static关键字,属于类而不是实例,它们在整个程序的执行过程中只有一份拷贝,可以被所有实例访问。静态变量通常用于存储跨实例共享的数据。(这个后面章节会讲到)

2.4.1 变量的声明

int age = 10;//整型变量的声明
double value = 20.0//double型数据的声明
char sex = '男';//字符型数据的声明
String name = "Kobe";//字符串型数据的声明

2.4.2 变量的使用细节

Java变量的使用细节:

  1. 变量名必须遵守Java的命名规范,即以字母、下划线或美元符号开头,后面可以跟字母、数字、下划线或美元符号。
  2. 变量在使用前必须先声明并初始化,否则会出现编译错误。
  3. 变量的作用域是指在哪些地方可以访问到该变量。在Java中,变量可以有多种作用域,包括类作用域、方法作用域、块作用域等。

初学者可去查看下面这篇文章,初学者了解。

教妹学Java(八):初识Java变量_沉默王二的博客-CSDN博客

版权声明:本文为CSDN博主「沉默王二」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

2.5 Java中 + 号的使用

在Java中,+号主要有两种作用:

  1. 数学运算符:+号可以用于两个数字之间的加法运算,例如:

    int num1 = 5;
    int num2 = 10;
    int sum = num1 + num2; // sum的值为15

  2. 字符串连接符:+号可以将两个字符串连接起来,例如:

    String str1 = “Hello”;
    String str2 = “World”;
    String result = str1 + str2; // result的值为"HelloWorld"

需要注意的是,在使用+号进行字符串连接时,如果其中一个操作数是字符串,那么Java会将另一个操作数也转换为字符串,然后将它们连接起来。如果两个操作数都是数字,那么Java会将它们相加,并返回一个数字类型的结果。

System.out.println(10 + 10);//输出结果为:20
System.out.println(10 + "10");//输出结果为:1010
System.out.println(10 + "hi" + 20);//输出结果为:10hi20
System.out.println("hi" + 10 + 20);//输出结果为:hi1020

2.6 Java数据类型

Java中的数据类型可以分为两类:基本数据类型和引用数据类型。

  1. 基本数据类型:Java中的基本数据类型包括:

    • 整型:byte、short、int、long

    • 浮点型:float、double

    • 字符型:char

    • 布尔型:boolean

    • 这些数据类型都有固定的大小和取值范围,可以直接存储在内存中,并且可以直接进行算术运算。

  2. 引用数据类型:Java中的引用数据类型包括:

    • 接口

    • 数组

    这些数据类型在内存中只是存储了一个引用,需要通过new关键字来创建对象,并且可以调用对象的方法和访问对象的属性。引用数据类型的大小和取值范围是不固定的,取决于实际存储的数据。

数据类型默认值大小
booleanfalse1比特
char‘\u0000’2字节
byte01字节
short02字节
int04字节
long0L8字节
float0.0f4字节

01、布尔
布尔(boolean)仅用于存储两个值:true 和 false,也就是真和假,通常用于条件的判断。代码示例:

boolean flag = true;

02、byte
byte 的取值范围在 -128 和 127 之间,包含 127。最小值为 -128,最大值为 127,默认值为 0。在网络传输的过程中,为了节省空间,常用字节来作为数据的传输方式。代码示例:

byte a = 10;
byte b = -10;

03、short
short 的取值范围在 -32,768 和 32,767 之间,包含 32,767。最小值为 -32,768,最大值为 32,767,默认值为 0。代码示例:

short s = 10000;
short r = -5000;

04、int
int 的取值范围在 -2,147,483,648(-2 ^ 31)和 2,147,483,647(2 ^ 31 -1)(含)之间,默认值为 0。如果没有特殊需求,整形数据就用 int。代码示例:

int a = 100000;
int b = -200000;

05、long
long 的取值范围在 -9,223,372,036,854,775,808(-2^63) 和 9,223,372,036,854,775,807(2^63 -1)(含)之间,默认值为 0。如果 int 存储不下,就用 long,整形数据就用 int。代码示例:

long a = 100000L; 
long b = -200000L;/*为了和 int 作区分,long 型变量在声明的时候,末尾要带上大写的“L”。
					不用小写的“l”,是因为小写的“l”容易和数字“1”混淆。*/

06、float
float 是单精度的浮点数,遵循 IEEE 754(二进制浮点数算术标准),取值范围是无限的,默认值为 0.0f。float 不适合用于精确的数值,比如说货币。代码示例:

float f1 = 234.5f;/*为了和 double 作区分,float 型变量在声明的时候,
					末尾要带上小写的“f”。不需要使用大写的“F”,是因为小写的“f”很容易辨别。*/

07、double
double 是双精度的浮点数,遵循 IEEE 754(二进制浮点数算术标准),取值范围也是无限的,默认值为 0.0。double 同样不适合用于精确的数值,比如说货币。代码示例:

double d1 = 12.3

08、char

char 可以表示一个 16 位的 Unicode 字符,其值范围在 ‘\u0000’(0)和 ‘\uffff’(65,535)(包含)之间。代码示例:

char letterA = 'A'; // 用英文的单引号包裹住。

引用数据类型后面章节会讲到

2.7基本数据类型转换

2.7.1自动类型转换

Java中的自动类型转换是指在不需要进行任何显式转换的情况下,将一种数据类型转换为另一种数据类型。自动类型转换的规则如下:

  1. 将低容量类型向高容量类型自动转换。例如,将byte类型转换为int类型。
  2. 将整型常量(如1、2等)自动转换为浮点型。例如,将int类型的1自动转换为float类型的1.0。
  3. 将char类型自动转换为int类型。例如,将char类型的’a’自动转换为int类型的97。

需要注意的是,对于不同的数据类型之间进行运算时,Java编译器会自动进行类型转换,将其中一个数据类型转换为另一个数据类型,然后再进行运算。但是,如果不符合自动类型转换的规则,就需要进行显式类型转换。例如,将double类型转换为int类型时,需要使用强制类型转换符号“()”进行显式转换。

数据类型按容量大小排序
在这里插入图片描述

2.7.2自动类型转换使用细节

自动类型转还有一些细节需要注意:

  1. 当将浮点型转换为整型时,会将小数部分直接截断,而不是四舍五入。
  2. 对于byte、short、char三种类型,它们在进行运算时会自动转换为int类型,因为int类型是它们类型范围内最大的类型。
  3. 当进行运算时,如果两个操作数的类型不一致,Java编译器会自动将其中一个操作数转换为另一个操作数的类型,然后再进行运算。如果转换后的类型仍然不一致,则会将其中一个操作数转换为另一个操作数的类型的最大公共类型,然后再进行运算。
  4. 在表达式中,可以使用强制类型转换符号“()”进行显式类型转换,例如将double类型转换为int类型时可以使用“(int)”进行转换。

需要注意的是,虽然Java中的自动类型转换可以方便地进行数据类型转换,但是在进行类型转换时需要注意数据类型的范围和精度,以避免数据丢失和溢出等问题。

2.7.3强制类型转换

Java中的强制类型转换可以使用强制类型转换符号“()”进行显式类型转换,其语法格式为:

(目标类型) 值或表达式

例如,将double类型的变量d转换为int类型可以使用以下代码:

double d;
int i = (int) d;

需要注意的是,在进行强制类型转换时需要确保转换后的数据类型可以完整地容纳转换前的数据,否则可能会发生数据丢失和溢出等问题。因此,在进行强制类型转换时应该进行数据类型范围和精度的检查。

时需要注意数据类型的范围和精度,以避免数据丢失和溢出等问题。

2.8运算符

2.8.1算术运算符

运算符运算示例结果
+正号+11
-负号a=-1-1
+1+12
-2-11
*2*24
/4/22
%取余3%21
++自增a=2; b=++a
a=2; b=a++
a=3;b=3
a=3;b=2
自减a=2; b= - -a
a=2; b= a- -
a= 1;b=1
a=1;b=2

说明:自增++,当自增语句单独使用时,都等价于i=i+1,当作为表达式时,前++:先自增再赋值,后++:先赋值后自增。

2.8.2 增强赋值操作符

Java中允许使用增强赋值操作符来结合赋值和运算操作的功能

运算符运算示例等价于
+=加法赋值操作符i+=1i=i+1
-=减法赋值操纵符i-=1i=i-1
*=乘法赋值操作符i*=1i=i*1
/=除法赋值操作符i/=1i=i/1
%=取余赋值操作符i%=1i=i%1

注意:增强赋值操作符在表达式中所有其他操作符计算完成后执行。比如:x /= 4 + 2 * 3; 等价于x = x / (4 + 2 * 3);增强操作符之间是没有空格的,+=不能写成 + = 。

2.8.3 关系运算符

特点:关系运算符的结果都是boolean型;经常用在if结构或者循环结构的的条件判断

运算符运算示例结果
==相等1==2false
!=不等于1!=1true
<小于1<2true
>大于3>2true
<=小于等于1<=2true
>=大于等于4>=2true
instanceof检查是否是类的对象cat instanceof animaltrue

2.8.4 逻辑运算符

aaa&ba&&ba|ba||b!aa^b
truetruetruetruetruetruefalsefalse
truefalsefalsefalsetruetruefalsetrue
falsetruefalsefalsetruetruetruetrue
falsefalsefalsefalsefalsefalsetruefalse

讲解规则:

  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. &&短路与:如果第一个条件为 false,则第二个条件不会判断,最终结果为 false,效率高
  2. & 逻辑与:不管第一个条件是否为 false,第二个条件都要判断,效率低
  3. 开发中, 我们使用的基本是使用短路与&&, 效率高

|| 和 | 基本规则

名称语法特点
短路或条件 1||条件 2两个条件中只要有一个成立,结果为 true,否则为false
逻辑或 |条件 1|条件 2只要有一个条件成立,结果为 true,否则为 false

2.8.5 三元运算符

基本语法:条件表达式 ? 表达式 1: 表达式 2;
运算规则:
1、如果条件表达式为 true,运算后的结果是表达式 1;
2、如果条件表达式为 false,运算后的结果是表达式 2;
示例

int a = 1;
int b = 2;
// 解读
// 1. a > b 为 false
// 2. 返回 b
// 3. 返回的结果是 2
int result = a > b ? a : b;
System.out.println("result=" + result);

3.1 顺序控制

顺序控制流程是一种程序执行的基本控制流程,它按照代码编写的顺序依次执行每一条语句。在顺序控制流程中,程序会从第一条语句开始执行,直到执行完最后一条语句,才会结束程序的执行。

例如,下面是一个简单的顺序控制流程的示例程序:

a = 5
b = 10
c = a + b
print(c)

这个程序中,首先执行第一条语句,将变量a赋值为5;然后执行第二条语句,将变量b赋值为10;接着执行第三条语句,将a和b的值相加并赋值给变量c;最后执行最后一条语句,输出变量c的值。整个程序的执行过程就是按照代码编写的顺序依次执行每一条语句的过程。
顺序控制流程是所有程序中最基本的控制流程,它对于程序的执行顺序有着决定性的影响。在程序的设计中,程序员需要充分考虑顺序控制流程的作用,合理安排每一条语句的顺序,以达到预期的程序执行效果。

3.2 分支控制

分支控制是指在编程中根据不同的条件执行不同的代码分支的能力。在许多编程语言中,分支控制通常使用条件语句来实现。常见的条件语句包括if语句、switch语句等。

3.2.1 分支控制if-else

分支控制是编程中常用的一种流程控制语句,if-else语句是其中一种常见的分支控制语句。
if-else语句用于根据条件执行不同的代码块。其基本形式如下

if (condition) {
    // 当条件为真时执行的代码块
} else {
    // 当条件为假时执行的代码块
}

其中,condition是一个布尔表达式,当其值为true时执行if语句块中的代码,否则执行else语句块中的代码。
在需要多个条件判断的情况下,可以使用if-else if语句,其基本形式如下:

if (condition1) {
    // 当条件1为真时执行的代码块
} else if (condition2) {
    // 当条件2为真时执行的代码块
} else {
    // 所有条件均为假时执行的代码块
}

在此结构中,如果条件1为真,则执行if语句块中的代码,否则继续判断条件2,如果条件2为真,则执行else if语句块中的代码,否则执行else语句块中的代码。
需要注意的是,if-else语句块中的代码只有当条件为真时才会被执行,否则不会执行。因此,在使用if-else语句时,需要仔细考虑所有可能的情况,确保代码逻辑正确无误。

3.2.2 switch分支结构

switch 分支结构是一种流程控制结构,用于根据不同的情况执行不同的代码块。在 switch 结构中,您可以列出一组可能的选项(称为 case),并针对每个选项编写相应的代码块。然后,您可以将变量或表达式与这些选项进行比较,以确定应该执行哪个代码块。

下面是一个 switch 分支结构的示例:

switch (variable) {
  case value1:
    // 执行代码块1
    break;
  case value2:
    // 执行代码块2
    break;
  case value3:
    // 执行代码块3
    break;
  default:
    // 如果 variable 不匹配任何值,则执行默认代码块
}

在上面的示例中,variable 是要与每个 case 选项进行比较的变量或表达式。如果 variable 的值与 value1 匹配,则执行代码块1,如果与 value2 匹配,则执行代码块2,以此类推。如果 variable 的值不匹配任何选项,则执行默认代码块。
需要注意的是,在每个代码块的结尾都有一个 break 语句,这是为了防止执行下一个代码块。如果省略了 break 语句,switch 结构将会执行所有匹配的代码块,而不是只执行第一个匹配的代码块。

3.3 循环控制

3.3.1 for循环控制

在Java中,for循环是一种常用的循环结构,通常用于对数组或集合进行遍历,其基本语法如下:

for (初始化表达式; 布尔表达式; 更新表达式) {
    // 循环体语句
}

其中,初始化表达式用于初始化循环控制变量;布尔表达式用于判断循环条件是否满足,如果满足,则执行循环体语句,否则跳出循环;更新表达式用于更新循环控制变量的值。
在for循环中,可以使用break语句和continue语句来控制循环的执行。break语句可以用于跳出循环,而continue语句可以用于跳过本次循环,直接执行下一次循环。
另外,在Java 5中引入了增强的for循环,也叫foreach循环,用于简化数组或集合的遍历操作。其基本语法如下:

for (元素类型 元素变量 : 数组或集合) {
    // 循环体语句
}

其中,元素类型是数组或集合中元素的类型,元素变量是用于接收每个元素的变量名。在foreach循环中,循环体语句会针对每个元素执行一次。

3.3.2 while循环控制

在Java中,while循环是一种常见的控制结构,用于重复执行某个代码块,直到指定的条件不再满足为止。它的语法如下:

while (condition) {
  // 循环体代码
}

其中,condition是一个布尔表达式,如果它的值为true,则循环体代码将继续执行;否则,循环将结束。

以下是一个简单的示例,演示了如何使用while循环输出1到10之间的所有奇数:

int i = 1;
while (i <= 10) {
  if (i % 2 == 1) {
    System.out.println(i);
  }
  i++;
}

在这个例子中,循环首先初始化变量i为1。然后,每次循环时,它检查i是否小于或等于10,如果是,则执行循环体代码。在循环体中,它检查i是否是奇数,如果是,则输出i的值。最后,它递增i的值,使循环可以继续执行下一次迭代,直到i的值大于10为止。

3.3.3 do…while循环控制

在Java中,do…while循环用于重复执行一组语句,直到给定的布尔表达式变为false为止。该循环会至少执行一次,因为它的判断条件是在循环体的最后面进行判断的。

do…while循环的语法如下:

do {
    // 循环体语句
} while (布尔表达式);

其中,循环体语句是需要重复执行的一组语句,布尔表达式是用于控制循环是否继续执行的条件。
do…while循环的执行过程如下:
1.执行循环体语句。
2.判断布尔表达式的值是否为true,如果为true,则返回步骤1继续执行循环体语句;否则,结束循环。
需要注意的是,do…while循环至少会执行一次循环体语句,即使布尔表达式一开始就是false。因此,如果你需要在循环之前对一些变量进行初始化或执行一些操作,do…while循环可能是一个不错的选择。

3.4 跳转控制语句

3.4.1 continue

在Java中,continue是一种控制流语句,用于在循环结构(如for、while、do-while)中跳过当前迭代并继续下一次迭代。当程序执行到continue语句时,它将立即跳过循环体中continue语句后面的所有语句,并开始下一次循环迭代。

下面是一个简单的示例,演示了如何使用continue语句在循环中跳过某些迭代:

for (int i = 1; i <= 10; i++) {
    if (i == 5) {
        continue; // 跳过 i = 5 的迭代
    }
    System.out.print(i + " ");
}

在上面的代码中,当i等于5时,continue语句将跳过该迭代并继续下一次迭代。因此,该代码将输出以下内容:

1 2 3 4 6 7 8 9 10

3.4.2 break

在Java中,break是一种控制流语句,用于立即退出一个循环语句(for、while、do-while)或一个switch语句。break语句通常与条件语句结合使用,例如,在一个循环语句中,当满足某个条件时,就可以使用break语句来跳出循环。

下面是一个使用break语句的示例:

for (int i = 0; i < 10; i++) {
    if (i == 5) {
        break;
    }
    System.out.println(i);
}

在上面的示例中,当i等于5时,break语句被执行,循环立即退出,因此只输出了0到4这五个数字。

在switch语句中,break语句可以用来终止case分支,防止执行下一个case分支。例如:

int num = 2;
switch (num) {
    case 1:
        System.out.println("num is 1");
        break;
    case 2:
        System.out.println("num is 2");
        break;
    case 3:
        System.out.println("num is 3");
        break;
    default:
        System.out.println("num is not 1, 2 or 3");
        break;
}

在上面的示例中,当num等于2时,只会输出"num is 2",而不会执行下一个case分支。

3.4.3 return

在 Java 中,return 是一个关键字,用于结束当前方法的执行并返回一个值(如果方法定义了返回类型)。return 关键字可以在任何时候使用,它会立即结束当前方法的执行,并将控制权返回给调用该方法的代码。

如果方法定义了返回类型,则 return 语句必须返回与该类型兼容的值。例如,如果方法定义了 int 类型的返回值,则 return 语句必须返回一个 int 值。

以下是一个简单的 Java 方法,演示了 return 的用法:

public int add(int a, int b) {
    int sum = a + b;
    return sum;
}

在上面的示例中,add 方法接受两个参数 a 和 b,将它们相加并将结果存储在 sum 变量中。然后,return 语句返回 sum 变量的值作为方法的结果。

请注意,return 语句可以出现在方法的任何位置。如果 return 语句出现在方法的任何位置之前,它将会导致方法立即返回并不执行后续的代码。例如:

public int divide(int a, int b) {
    if (b == 0) {
        System.out.println("Cannot divide by zero");
        return 0;
    }
    return a / b;
}

在上面的示例中,divide 方法接受两个参数 a 和 b,并在执行除法之前检查 b 是否为零。如果 b 为零,则方法输出一条错误消息并立即返回 0。否则,方法将执行除法并返回结果。

4.1 数组的介绍

Java数组是一种用于存储和操作相同类型数据的数据结构。它们提供了一种有效的方式来管理大量数据,并且可以方便地访问和修改数组中的元素。
在Java中,数组是固定大小的,这意味着在定义数组时必须指定其大小。数组的大小由其容量确定,也就是说,一旦数组被创建,其大小就不能更改。
Java数组可以包含任何基本数据类型或自定义对象类型。要创建一个数组,需要使用关键字“new”来分配内存空间,并指定数组的大小
Java数组是一种强大的数据结构,可用于存储和操作大量数据。通过使用索引和循环,可以方便地访问和修改数组中的元素。

4.2 数组的创建

4.2.1 数组的静态初始化

Java数组的静态初始化是指在定义数组时直接为其赋值。这种方法通常用于创建小型数组或者已知元素的情况。

Java数组的静态初始化有两种方式:

  1. 声明和初始化同时完成

例如,以下代码声明了一个包含三个整数的数组,并将其初始化为1、2、3:

int[] myArray = {1, 2, 3};
  1. 声明和初始化分开完成

例如,以下代码先声明一个包含四个字符串的数组,然后在另一行中将其初始化:

String[] myArray;
myArray = new String[]{"apple", "banana", "orange", "grape"};

需要注意的是,在使用第二种方法时,需要在大括号内指定数组的长度。在第一种方法中,数组的大小由初始值的数量决定。

静态初始化使得数组的定义更加简洁明了,并且可以减少代码量和错误率。但是,它并不适用于动态计算数组元素的情况,因为在静态初始化中,数组的大小必须是确定的。

4.2.2 数组的动态初始化

Java数组的动态初始化是指在定义数组时只指定数组的长度,而不为其分配具体的初始值。然后可以使用循环或其他方法为数组元素赋值。

Java数组的动态初始化有以下方式:

  1. 通过关键字 new 和指定数组长度进行初始化

例如,以下代码声明了一个包含5个整数的数组,并将其初始化为默认值0:

int[] myArray = new int[5];
  1. 声明数组变量和数组长度,但是在稍后的代码中使用 new 关键字完成数组初始化

例如,以下代码声明了一个包含10个字符串的数组,然后在另一行中使用 new 关键字为其赋值:

String[] myArray;
myArray = new String[10];

需要注意的是,在动态初始化中,数组的大小可以在运行时根据需要进行计算,这使得它更加灵活。但是,与静态初始化相比,动态初始化需要更多的代码,并且在循环或其他方法中赋值也可能会导致性能问题。

4.3 数组使用的细节

在使用Java数组时,有一些需要注意的细节,包括:

  1. 数组的索引从0开始,因此最后一个元素的索引是数组长度减1。

  2. 在访问数组元素之前,必须确保已分配了足够的内存空间。

  3. 在创建数组时,必须指定其大小,并且一旦创建,其大小就不能改变。如果需要扩大数组,可以创建一个新的更大的数组,并将原始数组中的元素复制到新的数组中,然后使用新的数组替换原始数组。

  4. Java数组可以存储任何基本类型或对象类型。但是,在声明数组时,必须指定元素的数据类型,而且所有元素都必须具有相同的数据类型。

  5. 初始化数组时,必须为每个元素赋初值。如果不初始化,则会出现编译错误。

  6. 在使用数组时,应该注意避免数组下标越界。否则会导致运行时异常。

  7. 数组可以作为方法的参数和返回值。在这种情况下,应该注意参数和返回值的类型,并确保数组的大小正确。

总之,Java数组是一种强大的数据结构,可用于存储和操作大量数据。在使用数组时,需要注意上述细节,以确保代码正确性和性能。

4.4 数组的常用操作

在Java中,有很多对数组进行操作的方法和函数。下面列出一些常用的操作:

  1. 创建一个数组

可以使用关键字 new 来创建一个数组,例如:

int[] myArray = new int[10];

这将创建一个包含10个整数的数组。

  1. 访问数组元素

可以使用索引操作符 ([]) 来访问数组中的元素,例如:

int value = myArray[0];

这将把数组中的第一个元素赋给变量 value

  1. 修改数组元素

可以使用索引操作符 ([]) 来修改数组中的元素,例如:

myArray[0] = 5;

这将把数组中的第一个元素更改为值5。

  1. 获取数组长度

可以使用数组对象的 length 属性来获取数组的长度,例如:

int len = myArray.length;

这将返回数组 myArray 的长度。

  1. 遍历数组

可以使用循环结构来遍历数组的所有元素并进行相应的操作,例如:

for (int i = 0; i < myArray.length; i++) {
    System.out.println(myArray[i]);
}

这将打印数组中的所有元素。

  1. 排序数组

可以使用Arrays类中的sort()方法来对数组进行排序,例如:

Arrays.sort(myArray);

这将按升序对数组中的元素进行排序。

总之,在Java中,数组是一种非常有用的数据结构,它提供了方便的方式来存储和处理大量的数据。开发者可以通过上述常用操作来灵活地使用数组。

4.5 数组的复制

在Java中,数组的复制可以使用System.arraycopy()方法或Arrays.copyOf()方法完成。下面分别介绍这两种方法的用法。

  1. System.arraycopy()方法

System.arraycopy()方法是Java提供的用于复制数组的快速且高效的方法,可将一个数组的某个区域复制到另一个数组的指定位置。该方法的语法如下:

public static void arraycopy(Object src, int srcPos,
                             Object dest, int destPos, int length)

其中,src表示源数组,srcPos表示源数组中要复制的起始索引,dest表示目标数组,destPos表示目标数组中放置复制数据的起始索引,length表示要复制的元素数量。

例如,以下代码演示了如何使用System.arraycopy()方法将原数组的第2到4个元素复制到新数组的第1到3个位置:

int[] original = {1, 2, 3, 4, 5};
int[] copy = new int[3];

System.arraycopy(original, 1, copy, 0, 3);
  1. Arrays.copyOf()方法

Arrays.copyOf()方法是Java提供的用于复制数组的方法,它可以创建一个新数组,并将原始数组的所有元素复制到新数组中。该方法的语法如下:

public static <T> T[] copyOf(T[] original, int newLength)

其中,original表示要复制的原始数组,newLength表示新数组的长度。

例如,以下代码演示了如何使用Arrays.copyOf()方法将原数组的前三个元素复制到新数组中:

int[] original = {1, 2, 3, 4, 5};
int[] copy = Arrays.copyOf(original, 3);

需要注意的是,在使用Arrays.copyOf()方法时,如果原数组的长度小于新长度,则会使用默认值填充新数组中剩余的元素。

总之,Java提供了多种方法用于复制数组,包括System.arraycopy()方法和Arrays.copyOf()方法。开发者可以根据实际需要选择最适合的方法。

4.6 数组的反转

在Java中,可以使用循环和临时变量等方式来反转一个数组。下面介绍两种常用的方法:

  1. 使用循环和临时变量

该方法通过循环遍历数组,将数组元素按相反的顺序存储到一个新数组中,然后将新数组赋值回原数组。例如:

int[] myArray = {1, 2, 3, 4, 5};
int[] reversedArray = new int[myArray.length];

for (int i = 0; i < myArray.length; i++) {
    reversedArray[i] = myArray[myArray.length - i - 1];
}

myArray = reversedArray;

在这个例子中,我们创建了一个新数组reversedArray,并通过循环遍历myArray数组,将元素按相反的顺序存储到reversedArray中。最后,我们将reversedArray赋值回myArray。

  1. 使用循环和临时变量

该方法通过循环遍历数组,在原数组中交换相邻的元素,以实现数组反转的目的。例如:

int[] myArray = {1, 2, 3, 4, 5};

for (int i = 0; i < myArray.length / 2; i++) {
    int temp = myArray[i];
    myArray[i] = myArray[myArray.length - i - 1];
    myArray[myArray.length - i - 1] = temp;
}

在这个例子中,我们通过循环遍历myArray数组,将第i个元素与倒数第i个元素交换位置,从而达到数组反转的效果。

总之,Java提供了多种方法来反转一个数组,包括使用循环和临时变量以及使用Collections类的reverse()方法等。开发者可以根据具体情况选择最适合的方法。

4.7 数组的添加/扩容

在Java中,数组的长度一旦确定后就无法更改。因此,在需要向数组中添加元素或将数组扩大时,可以采用以下两种方法:

  1. 创建一个新数组

此方法包括以下步骤:

  • 创建一个新的数组,其长度比原始数组大
  • 将原始数组的元素复制到新数组中
  • 将要添加到数组中的新元素追加到新数组中

例如,以下代码演示了如何向一个整数数组中添加一个新元素:

int[] originalArray = {1, 2, 3};
int[] newArray = new int[originalArray.length + 1];
System.arraycopy(originalArray, 0, newArray, 0, originalArray.length);
newArray[newArray.length - 1] = 4;

在这个例子中,我们首先创建了一个新数组 newArray,它比原始数组 originalArray 多一个元素。然后我们使用 System.arraycopy() 方法将 originalArray 中的所有元素复制到 newArray 中,并将要添加到数组中的新元素 4 追加到 newArray 的末尾。

  1. 使用集合类

可以使用Java集合类(如ArrayList)来避免手动管理数组的长度和扩展。例如,下面是使用ArrayList向数组中添加一个新元素的示例:

ArrayList<Integer> myArrayList = new ArrayList<Integer>(Arrays.asList(originalArray));
myArrayList.add(4);
Integer[] newArray = myArrayList.toArray(new Integer[originalArray.length+1]);

在这个例子中,我们首先将原始数组 originalArray 转换为ArrayList,然后向列表中添加一个新元素。最后,我们将修改后的列表转换回数组 newArray

总之,当需要向Java数组添加元素或将数组扩大时,可以使用上述方法之一。手动扩容需要更多的代码和注意事项,而使用集合类则更加简单。

4.8 二维数组的创建

4.8.1 二维数组的静态初始化

在Java中,可以使用静态初始化的方式创建二维数组。静态初始化是指在声明数组时就为其分配空间并赋予初值。以下是一个示例代码,演示如何使用Java进行二维数组的静态初始化:

public class TwoDArray {
    public static void main(String[] args) {
        int[][] myArray = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
        
        // 打印二维数组
        for (int i = 0; i < myArray.length; i++) {
            for (int j = 0; j < myArray[i].length; j++) {
                System.out.print(myArray[i][j] + " ");
            }
            System.out.println();
        }
    }
}

在这个例子中,我们使用了双重大括号语法来创建二维数组,并为其赋予初值。我们将数组元素按照行列顺序排列,每行用一组花括号括起来,在所有行外再套一层花括号。

上述代码将创建一个3×3的二维数组myArray,并依次为其赋值为:

1 2 3 
4 5 6 
7 8 9 

在打印二维数组时,我们使用两个嵌套的循环来遍历二维数组的所有元素,并输出到控制台上。

总之,Java提供了多种方法来初始化和操作二维数组。开发者可以根据具体情况选择最适合的方法。

4.8.2 二维数组的动态初始化

在Java中,可以使用动态初始化的方式创建二维数组。动态初始化是指在声明数组时不为其分配空间,而是在后续的代码中根据需要动态为其分配空间。以下是一个示例代码,演示如何使用Java进行二维数组的动态初始化:

public class TwoDArray {
    public static void main(String[] args) {
        int[][] myArray = new int[3][3];
        
        // 打印二维数组
        for (int i = 0; i < myArray.length; i++) {
            for (int j = 0; j < myArray[i].length; j++) {
                System.out.print(myArray[i][j] + " ");
            }
            System.out.println();
        }
    }
}

在这个例子中,我们使用关键字new来创建一个3×3的二维数组myArray,并在后续的代码中为其分配空间。由于我们没有为二维数组赋初值,因此默认将所有元素初始化为0。

运行上述代码,将得到以下输出结果:

0 0 0 
0 0 0 
0 0 0 

在打印二维数组时,我们仍然使用两个嵌套的循环遍历二维数组的所有元素,并输出到控制台上。

除了动态初始化外,还可以使用静态初始化的方式进行二维数组的初始化。具体方法请参见上一条回答。

总之,Java提供了多种方法来初始化和操作二维数组。开发者可以根据具体情况选择最适合的方法。

4.9 二分查找

二分查找是一种高效的查找算法,它适用于有序数组。在Java中,可以使用以下方式实现二分查找:

public static int binarySearch(int[] arr, int key) {
    int low = 0;
    int high = arr.length - 1;
    
    while (low <= high) {
        int mid = (low + high) / 2;
        
        if (arr[mid] == key) {
            return mid;
        } else if (arr[mid] < key) {
            low = mid + 1;
        } else {
            high = mid - 1;
        }
    }
    
    return -1;
}

这个方法接受一个整数数组 arr 和一个要查找的关键字 key。该方法首先将 low 设置为0,将 high 设置为 arr.length-1,然后使用while循环在数组中进行查找。

在每次迭代中,我们通过计算 mid(即 lowhigh 的平均值)来确定当前区间的中心位置。如果 arr[mid] 等于 key,则返回 mid。否则,如果 arr[mid] 小于 key,则更新 lowmid+1,否则更新 highmid-1。当 low > high 时,说明 key 不在数组中,返回 -1

下面是一个调用示例:

int[] myArray = {1, 3, 5, 7, 9};
int key = 7;

int index = binarySearch(myArray, key);

if (index != -1) {
    System.out.println("Found at index: " + index);
} else {
    System.out.println("Not found");
}

在这个例子中,我们创建了一个包含奇数个元素的整数数组myArray,并将其升序排列。然后我们使用上述方法在数组中查找key等于7的元素,并打印出其索引值。

总之,二分查找是一种高效的查找算法,可以在对数时间内查找有序数组中的元素。在Java中,可以使用上述方法来实现二分查找。

小节配套习题小练

Java之习题小练—循环控制

版权声明:本文为CSDN博主「L可乐要加冰」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_51110071/article/details/129705037

5.1 类与对象

5.2.1 类与对象引言

Java是一门面向对象编程语言,类和对象是Java中最基本的概念。

类是一个模板或蓝图,它用于创建对象。类定义了对象的属性和方法,其中属性表示对象的状态,而方法表示对象能够执行的操作。

在Java中,使用关键字“class”定义一个类。例如:

public class MyClass {
    // 类的属性
    private int myNumber;
    
    // 类的方法
    public void setMyNumber(int num) {
        this.myNumber = num;
    }
    
    public int getMyNumber() {
        return this.myNumber;
    }
}

上述代码定义了一个名为"MyClass"的类。它有一个私有属性"myNumber"和两个公共方法"setMyNumber"和"getMyNumber"。私有属性只能在类的内部访问,而公共方法可以被其他类访问。

对象是类的实例。当创建一个对象时,会使用关键字“new”调用该类的构造函数。例如:

MyClass obj = new MyClass();
obj.setMyNumber(10);
System.out.println(obj.getMyNumber());

上述代码创建了一个"MyClass"类的对象,并将其赋值给名为"obj"的变量。然后,它通过调用"setMyNumber"方法设置对象的属性值,并通过调用"getMyNumber"方法获取该属性的值。最后,它使用"System.out.println"方法在控制台上打印该值。

总之,类和对象是Java编程中非常重要的概念,对于理解Java编程具有关键作用。

5.2.2 类与对象的区别与联系

类和对象是Java编程中的两个重要概念,它们之间有着联系和区别。

联系:
类是一个抽象的概念,是对具有相同属性和方法的一组对象的抽象。而对象则是类的实例,通过创建对象来使用类中定义的属性和方法。

类和对象都具有属性和方法,属性描述对象的状态,而方法则描述对象能够执行的操作。类和对象都可以访问类中的公共属性和方法,也可以通过继承和多态等方式进行扩展。

区别:
类和对象的最大区别在于,类是一个模板或蓝图,用于定义对象的属性和方法;而对象是类的一个实例,具有独立的内存空间和生命周期。

类通常被认为是静态的,因为它们是在编译时创建的,并且在运行时不会改变。而对象则是动态的,因为它们是在运行时创建的,并且可以随时更改其状态。

另一个重要的区别是,一个类可以创建多个对象,每个对象都有自己的状态和行为。这使得Java程序可以轻松地处理大量的数据。

总之,类和对象是Java编程中非常关键的概念,它们之间有着密切的联系和明显的区别。了解它们的区别和联系可以帮助我们更好地理解Java编程,从而更好地应用和运用Java编程。

5.2.3 Java类与对象在内存的形式

Java 类和对象在内存中的表现形式,栈、堆、方法区、常量池

版权声明:本文为CSDN博主「joshua317」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接https://blog.csdn.net/joshua317/article/details/121238327

5.2.4 属性

在Java中,属性是一个对象的状态信息,它描述了对象所包含的数据。Java属性也被称为实例变量或成员变量。在类中定义属性时,需要指定其类型和访问修饰符。

Java中的访问修饰符有四种:public、protected、private和default。其中,public表示该属性可以被任何其他类访问,protected表示该属性只能被同一个包中的其他类或子类访问,private表示该属性只能在该类内部访问,而default则表示该属性只能在同一个包中的其他类中访问。

Java属性通常使用private来限制对属性的直接访问,并通过公共方法(getters和setters)提供对属性的访问方式。例如:

public class Person {
    private String name;
    private int age;
    
    public String getName() {
        return this.name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
    public int getAge() {
        return this.age;
    }
    
    public void setAge(int age) {
        this.age = age;
    }
}

上述代码定义了一个名为"Person"的类,它有两个私有属性"name"和"age",并且每个属性都有相应的getter和setter方法,用于获取和设置属性的值。

在使用Java属性时,我们需要注意一些要点:

  1. 属性的命名应该清晰明了,避免使用不合适的名称。
  2. 属性的类型应该与其所代表的数据相符合,例如,年龄应该使用int类型而不是String类型。
  3. 访问修饰符应根据需要进行设置,遵循封装原则。
  4. 应该避免直接访问其他类的属性,而应该通过公共方法进行访问。

总之,Java属性是描述对象状态的重要组成部分,了解Java属性的定义和使用方式可以帮助我们更好地进行Java编程。

5.2.5 对象的创建

在Java中,可以使用关键字“new”来创建一个对象。通常,要创建一个对象需要经过以下步骤:

  1. 定义类:首先,需要定义一个类来描述对象的属性和方法。例如:
public class Person {
    private String name;
    private int age;
    
    public void setName(String name) {
        this.name = name;
    }
    
    public String getName() {
        return this.name;
    }
    
    public void setAge(int age) {
        this.age = age;
    }
    
    public int getAge() {
        return this.age;
    }
}

上述代码定义了一个名为“Person”的类,它包含了两个私有属性“name”和“age”,以及对这些属性进行操作的公共方法。

  1. 创建对象:一旦定义了类,就可以使用关键字“new”来创建对象。例如:
Person p = new Person();

上述代码创建了一个名为“p”的Person对象,并将其引用赋值给变量“p”。

  1. 初始化对象:创建对象后,可以通过调用其构造函数来初始化对象。如果没有显式定义构造函数,则会默认使用无参构造函数。例如:
Person p = new Person();
p.setName("张三");
p.setAge(20);

上述代码创建了一个名为“p”的Person对象,并通过调用其setName和setAge方法分别设置了对象的name和age属性。

  1. 使用对象:创建并初始化对象后,就可以使用其属性和方法。例如:
System.out.println(p.getName());
System.out.println(p.getAge());

上述代码分别通过调用getName和getAge方法获取了对象的name和age属性,并将其打印到控制台上。

总之,创建Java对象需要先定义类、然后使用关键字“new”来创建对象、初始化对象并使用对象。

5.2 成员方法

5.2.1 成员方法的介绍

在Java中,成员方法是类的一部分,用于定义类对象的行为和功能。成员方法可以访问类的属性,并且可以在方法内部调用其他方法。

Java中的成员方法包括实例方法和静态方法两种。实例方法是指属于某个对象的方法,只能通过该对象调用;而静态方法则是指与任何特定对象无关的方法,可以直接由类名调用。

下面是一个简单的示例程序:

public class Person {
    private String name;
    private int age;

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return this.name;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public int getAge() {
        return this.age;
    }

    public void sayHello() {
        System.out.println("Hello, my name is " + this.name +
         ", and I'm " + this.age + " years old");
    }

    public static void sayHi() {
        System.out.println("Hi, I'm a person");
    }
}

在上述代码中,我们定义了一个名为“Person”的类,它有两个私有属性“name”和“age”,以及六个公共方法。“setName”、“getName”、“setAge”和“getAge”分别用于设置和获取对象的属性值。“sayHello”方法用于打印出一个问候语,其中包含了对象的名字和年龄。而“sayHi”方法则是一个静态方法,用于打印出一个简单的问候语。

当我们需要使用该类时,可以通过调用相应的成员方法来完成。例如:

Person person = new Person();
person.setName("张三");
person.setAge(20);
person.sayHello();
Person.sayHi();

在上述代码中,我们创建了一个新的Person对象,并通过其setter方法设置了其属性值。然后,我们通过调用其“sayHello”方法打印出问候语,并通过调用类名来访问静态方法“sayHi”。

总之,成员方法是Java对象的重要组成部分,通过定义和调用成员方法,我们可以为Java对象提供行为和功能。

5.2.2 成员方法的定义

成员方法由访问修饰符、返回类型、方法名称、参数列表和方法体组成。以下是成员方法的基本结构:

[访问修饰符] [返回类型] [方法名称]([参数列表]) {
    // 方法体
}

其中,“访问修饰符”指定了该方法的可见性,可以是public、private、protected或者不加修饰符(默认可见性);“返回类型”指定了该方法的返回值类型,可以是任何Java数据类型或者void类型;“方法名称”指定了该方法的名称;“参数列表”指定了接受的参数类型和名称,如果没有参数,则可以省略括号;“方法体”包含了该方法的具体实现。

总之,成员方法是Java中非常重要的概念,使用它们可以为Java对象提供行为和功能,并且可以访问类的属性和其他成员方法。

5.2.3 成员方法的好处

Java成员方法是一种封装方式,可以将相关操作的逻辑放置于同一个方法中,有利于代码的组织和维护。以下是Java成员方法的一些好处:

  1. 提高代码的可读性:通过将相关操作放置于同一个方法中,可以提高代码的可读性,使得代码更易于理解和修改。

  2. 增强代码的复用性:成员方法可以被不同的对象调用,从而实现对相同逻辑的复用,减少了重复编写代码的工作量,提高了代码的复用性。

  3. 提供更好的封装性:成员方法可以访问类的私有属性和方法,但外部代码无法直接访问它们,因此可以保证类的数据封装性。

  4. 提高代码的可维护性:将操作逻辑放置于同一个方法中,可以减少代码之间的耦合性,降低了代码修改的风险,提高了代码的可维护性。

  5. 改善代码的可测试性:成员方法可以独立地进行单元测试,可以更加容易地进行测试和调试,从而提高了代码的可测试性。

总之,Java成员方法是面向对象编程中非常重要的概念,它具有很多优点,可以帮助我们更好地组织和维护代码,实现高效的编程。

5.2.4 方法的使用和注意事项

在Java中,方法是一种封装了代码的功能单元,用于完成特定的任务。使用方法可以提高代码的重用性、可读性、可维护性和可测试性。

下面介绍Java方法的使用和注意事项:

  1. 方法的调用方式:在Java中,可以通过类名或对象名来调用方法。对于静态方法,可以直接使用类名来调用;对于实例方法,则需要先创建类的对象,然后使用该对象来调用方法。

  2. 方法的返回值:Java方法可以有返回值,也可以没有返回值(即void类型)。如果方法有返回值,则必须指定返回值类型,并且在方法体中使用return语句返回具体的值。如果方法没有返回值,则返回类型必须为void,且不需要使用return语句。

  3. 方法的参数:Java方法可以接受参数,参数类型可以是任何Java数据类型。在方法定义时,需要指定参数类型和参数名称。在方法调用时,需要传递具体的参数值。可以有多个参数,多个参数之间以逗号隔开。

  4. 方法的访问修饰符:Java中的方法可以使用public、private、protected或默认访问修饰符来指定其可见性。使用访问修饰符可以控制方法的外部可见性,从而保证程序的安全性和可维护性。

注意事项:

  1. Java方法名称应该具有描述性,能够清楚地表达方法所完成的功能。

  2. Java方法的参数命名应该具有描述性,能够清晰地表达参数所代表的含义。

  3. 在Java方法内部,应该保持代码简洁、结构清晰,使得代码易于理解和修改。

  4. 当Java方法需要调用其他方法时,应该遵循递归的原则,避免出现死循环或者栈溢出的问题。

  5. 在Java方法中,应该尽量避免使用全局变量和静态变量,这会影响程序的可重用性和可测试性。

总之,使用Java方法可以提高编程的效率和代码的质量,但在使用时需要注意一些细节问题,以确保程序的正确性和健壮性。

5.2.5 成员方法的传参机制

在Java中,成员方法可以接受一定数量的参数,这些参数可以是基本类型、对象或数组等。Java成员方法传参的机制有以下几个特点:

  1. 参数传递方式是值传递:在Java中,参数传递是以值传递方式进行的,即将实参的值复制一份赋给形参,在方法内部对形参进行修改不会影响到实参的值。

  2. 引用类型变量的传递:当传递引用类型变量作为参数时,实际传递的是该对象的引用(即地址),而不是对象的拷贝。因此,对于引用类型变量,如果在方法内部修改了其属性值,则会影响到原始对象。

  3. 数组类型变量的传递:数组也是引用类型,因此当传递数组类型变量作为参数时,实际传递的是该数组对象的引用(即地址)。在方法内部修改数组元素的值,同样会影响到原始数组。

  4. 可变参数列表:从Java 5开始,支持使用可变参数列表作为方法的参数。可变参数列表使用三个连续的点“…”表示,允许在调用方法时传递任意数量的参数,这些参数将被封装成一个数组。

下面是一些示例代码,演示了Java成员方法传参的机制:

public class Test {
    public void changeValue(int value) {
        value = 10;
    }

    public void changePersonName(Person person) {
        person.setName("张三");
    }

    public void changeArray(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            arr[i] = arr[i] * 2;
        }
    }

    public void printValues(String... values) {
        for (String s : values) {
            System.out.println(s);
        }
    }
}

public class Person {
    private String name;

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return this.name;
    }
}

public class Main {
    public static void main(String[] args) {
        Test test = new Test();
        
        int value = 5;
        test.changeValue(value);
        System.out.println(value); // 输出结果为5,原始值未被改变
        
        Person person = new Person();
        person.setName("李四");
        test.changePersonName(person);
        System.out.println(person.getName()); // 输出结果为"张三",对象的属性值被修改
        
        int[] arr = {1, 2, 3};
        test.changeArray(arr);
        System.out.println(Arrays.toString(arr)); // 输出结果为[2, 4, 6],数组元素被修改
        
        test.printValues("a", "b", "c"); // 输出结果为"a" "b" "c"
    }
}

在上述代码中,我们定义了一个名为“Test”的类,其中包含了四个成员方法:changeValue、changePersonName、changeArray和printValues。在main方法内,我们创建了一个名为“test”的Test对象,并依次调用了这四个方法,演示了Java成员方法传参的机制。

5.3 方法的重载

5.3.1 重载介绍

在Java中,方法重载是指在同一个类中定义多个方法名称相同但参数列表不同的方法。方法重载允许我们在同一个类中以相似的方式处理不同类型或数量的数据,并使用相同的方法名进行调用。

5.3.2 重载的语法

Java方法重载的语法很简单,只需要在同一个类中定义多个方法名称相同但参数列表不同的方法即可。下面是Java方法重载的语法:

[访问修饰符] [返回类型] 方法名称(参数类型1 参数名称1, 参数类型2 参数名称2, ...) {
    // 方法体
}

[访问修饰符] [返回类型] 方法名称(参数类型1 参数名称1, 参数类型2 参数名称2, ..., 可变参数类型... 可变参数名称) {
    // 方法体
}

其中,“访问修饰符”、“返回类型”、“参数类型”和“参数名称”与普通方法的定义方式相同,只有参数列表不同。可以根据需要为方法定义任意数量和类型的参数,包括可变参数列表。

以下是一些示例代码,演示了Java方法重载的用法:

public class Test {
    public void print(int num) {
        System.out.println("打印整数:" + num);
    }

    public void print(double num) {
        System.out.println("打印浮点数:" + num);
    }

    public void print(String str) {
        System.out.println("打印字符串:" + str);
    }

    public void print(int num1, int num2) {
        System.out.println("打印两个整数:" + num1 + "和" + num2);
    }

    public void print(int... nums) {
        System.out.print("打印可变参数:");
        for (int num : nums) {
            System.out.print(num + " ");
        }
        System.out.println();
    }
}

public class Main {
    public static void main(String[] args) {
        Test test = new Test();
        
        test.print(10); // 输出结果为"打印整数:10"
        test.print(3.14); // 输出结果为"打印浮点数:3.14"
        test.print("Hello"); // 输出结果为"打印字符串:Hello"
        test.print(5, 7); // 输出结果为"打印两个整数:5和7"
        test.print(1, 2, 3, 4, 5); // 输出结果为"打印可变参数:1 2 3 4 5"
    }
}

在上述代码中,我们定义了一个名为“Test”的类,其中包含了五个方法:print(int)、print(double)、print(String)、print(int, int)和print(int…)。这些方法具有相同的名称,但参数列表不同。在Main类中我们创建了一个名为“test”的Test对象,并依次调用了这五个方法,演示了Java方法重载的用法。

总之,Java方法重载是一种非常有用的编程技巧,可以使代码更加模块化和可重用,提高了程序的可读性和可维护性。使用Java方法重载可以处理不同类型或数量的数据,同时使用相同的方法名进行调用。

5.3.3 重载的好处

Java重载的好处在于:

  1. 提高代码可读性:使用相同的方法名进行调用,让代码更加简洁易懂,降低了程序员的记忆负担。

  2. 增强代码复用性:通过不同的参数列表来实现不同的功能,减少了代码冗余,提高了代码的复用性。

  3. 提高程序的健壮性:能够根据不同的参数类型和数量,为方法实现不同的行为,从而增强了程序的健壮性。

  4. 支持方法重载的编程语言具有更高的灵活性和扩展性,能够更好地适应不同的开发需求。

总之,Java重载是一种非常有用的编程技巧,允许我们以相似的方式处理不同类型或数量的数据,并使用相同的方法名进行调用。这样可以提高代码的可读性、复用性和健壮性,是编写高质量Java程序的关键之一。

5.3.4 重载的使用细节和注意事项

在使用Java重载时,需要注意以下几个细节和注意事项:

  1. 方法名称必须相同:方法重载的前提是要定义多个方法名称相同但参数列表不同的方法。

  2. 参数列表必须不同:参数列表包括参数的类型、数量或者顺序,只有参数列表不同才能实现方法重载。

  3. 返回值类型可以不同:方法重载的返回值类型可以不同,因为Java编译器可以根据调用方法时的上下文自动推断出返回值类型。

  4. 可变参数列表与数组参数不能同时存在:在Java中,可变参数列表和数组参数不能同时存在,因为它们的语法很相似,会造成歧义。

  5. 自动类型转换:当传递的参数类型与定义方法的参数类型不匹配时,Java编译器会进行自动类型转换。例如,将一个整数传递给一个接受浮点数的方法时,Java编译器会进行隐式的类型转换。

  6. 避免过度使用方法重载:虽然方法重载可以提高代码的复用性和可读性,但是过度使用方法重载会使代码变得复杂和难以理解,不利于程序员的维护工作。

总之,在使用Java方法重载时,我们需要合理地设计方法的参数列表,确保方法名称相同、参数列表不同,使得程序更加简洁、易懂和可维护。同时,我们也需要谨慎使用方法重载,避免过度使用导致代码的复杂性增加。

5.4 构造方法/构造器

5.4.1 构造方法的介绍

Java构造方法是一种特殊的方法,用于创建和初始化对象。每当我们创建一个新的对象时,Java会自动调用该对象对应类中的构造方法来进行初始化操作。构造方法的作用是为对象的属性赋初值,确保对象在被创建时具有合法的初始状态。
Java构造方法的特点包括:

  1. 构造方法的名称与类名相同。
  2. 构造方法没有返回类型(包括void),也不需要使用return语句返回值。
  3. 如果没有显式地定义构造方法,Java会提供一个默认的无参构造方法。如果显式地定义了构造方法,则必须在代码中明确地调用它,否则编译器会报错。
  4. 构造方法可以重载,允许实现多个构造方法,以适应不同的初始化需求。

5.4.2 构造方法的语法

Java构造方法的基本语法如下:

[访问修饰符] 类名([参数列表]) {
    // 构造方法体
}

其中,“访问修饰符”可以是public、private、protected或者不写任何修饰符,用于控制构造方法的访问权限。参数列表包括零个或多个参数,用于向构造方法传递参数。构造方法体是一组Java语句,用于实现对象的初始化操作。

5.4.3 构造方法的使用

Java构造方法的使用主要包括两个方面:

  1. 创建对象时自动调用构造方法:每当我们创建一个新的对象时,Java会自动调用该对象对应类中的构造方法来进行初始化操作。因此,在定义构造方法时,需要确保它能够为对象的属性赋初值,从而确保对象在被创建时具有合法的初始状态。

  2. 构造方法的重载和调用:Java允许定义多个构造方法,以适应不同的初始化需求。在调用构造方法时,需要根据参数列表的类型、数量或顺序选择相应的构造方法进行调用。

以下是一个示例代码,演示了Java构造方法的用法:

public class Person {
    private String name;
    private int age;

    // 无参构造方法
    public Person() {
        System.out.println("调用了无参构造方法");
    }

    // 带参构造方法
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println("调用了带参构造方法");
    }

    // Getter和Setter方法
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

public class Main {
    public static void main(String[] args) {
        // 创建Person对象
        Person person1 = new Person();
        Person person2 = new Person("张三", 20);

        // 使用Setter方法设置属性值
        person1.setName("李四");
        person1.setAge(30);

        // 使用Getter方法获取属性值
        System.out.println(person1.getName() + "," + person1.getAge() + "岁");
        System.out.println(person2.getName() + "," + person2.getAge() + "岁");
    }
}

在上述代码中,我们定义了一个名为“Person”的类,其中包含两个构造方法:无参构造方法和带参构造方法。在Main类中我们创建了两个名为“person1”和“person2”的Person对象,并使用Setter方法设置它们的属性值,然后使用Getter方法获取属性值并输出结果。

总之,Java构造方法是一种特殊的方法,用于创建和初始化对象。在实际开发中,我们需要根据需求定义适当的构造方法,以便为对象赋初值,确保对象在被创建时具有合法的初始状态。同时,我们也可以重载构造方法,以适应不同的初始化需求,并在调用构造方法时根据参数列表的类型、数量或顺序选择相应的构造方法进行调用。

5.4.4 构造方法的使用细节和注意事项

在使用Java构造方法时,需要注意以下几个细节和注意事项:

  1. 构造方法名称必须与类名相同:构造方法的名称必须与对应的类名完全一致,包括大小写。

  2. 构造方法没有返回类型:Java构造方法没有返回类型,包括void,因为构造方法的返回值就是创建的对象本身。

  3. 如果没有定义构造方法,Java会提供默认的无参构造方法:如果没有显式地定义构造方法,则Java编译器会自动添加一个无参构造方法,默认访问修饰符为public。如果我们定义了一个或多个构造方法,则必须在代码中明确地调用它,否则编译器会报错。

  4. 构造方法可以重载:Java允许定义多个构造方法,以适应不同的初始化需求,这些构造方法之间必须有参数列表的差异。

  5. 在构造方法中可以调用其他的构造方法:在Java中,我们可以使用this关键字来调用本类中的其他构造方法,从而避免重复编写代码。需要注意的是,this语句必须放在构造方法体的第一行。

  6. 在构造方法中可以使用super关键字调用父类的构造方法:当子类继承父类时,子类的构造方法可以使用super关键字调用父类的构造方法。需要注意的是,super语句必须放在构造方法体的第一行。

总之,在使用Java构造方法时,我们需要注意构造方法名称与类名相同、没有返回类型、可以重载等特点,以确保对象在被创建时具有合法的初始状态。此外,我们还需要了解如何调用其他的构造方法和父类的构造方法,以便更加灵活地使用构造方法来完成对对象的初始化工作。

5.5 Java this关键字

5.5.1 this关键字介绍

在Java中,this关键字是一个指向当前对象的引用。它可以用来引用当前对象的成员变量、方法以及构造方法。

具体而言,this关键字可以用于以下几个方面:

  1. 引用当前对象的成员变量:在类中定义的成员变量与方法参数同名时,可以使用this关键字来区分二者,从而访问对象的成员变量。
  2. 引用当前对象的方法:在对象内部调用另一个方法时,可以使用this关键字来引用当前对象,从而避免歧义和错误。
  3. 在构造方法中调用其他的构造方法:在构造方法中使用this关键字来调用同一类中的其他构造方法,从而实现代码重用。需要注意的是,this语句必须放在构造方法体的第一行。
  4. 作为返回值返回当前对象:在某些情况下,我们可能需要让方法返回当前对象本身。此时,可以使用return this;语句来实现。

5.5.2 this关键字使用

在Java中,this关键字可以用于以下几个方面:

  1. 引用当前对象的成员变量:当构造方法或方法的参数名称与类的成员变量名称相同时,使用this关键字来引用当前对象的成员变量。例如:
public class Person {
    private String name;

    public void setName(String name) {
        this.name = name;
    }
}

在上述代码中,this.name表示Person类的成员变量name,而name表示方法参数。

  1. 引用当前对象的方法:在对象内部调用另一个方法时,使用this关键字来引用当前对象。例如:
public class Person {
    private String name;

    public void printName() {
        System.out.println("姓名:" + this.getName());
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

在上述代码中,this.getName()表示调用Person类的getName()方法。

  1. 在构造方法中调用其他的构造方法:在构造方法中使用this关键字来调用同一类中的其他构造方法,从而实现代码重用。需要注意的是,this语句必须放在构造方法体的第一行。例如:
public class Person {
    private String name;
    private int age;

    // 构造方法1:不带参数
    public Person() {
        this("张三", 20); // 调用带参构造方法
    }

    // 构造方法2:带参数
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

在上述代码中,构造方法1使用this关键字调用了另一个带参数的构造方法2来完成初始化操作。

  1. 作为返回值返回当前对象:在某些情况下,我们可能需要让方法返回当前对象本身。此时,可以使用return this;语句来实现。例如:
public class Person {
    private String name;
    private int age;

    public Person setName(String name) {
        this.name = name;
        return this;
    }

    public Person setAge(int age) {
        this.age = age;
        return this;
    }
}

在上述代码中,setName()和setAge()方法都返回当前对象Person,以便支持方法链式调用。

需要注意的是,在使用this关键字时,我们需要遵循一些规则:

  1. this关键字必须放在类的内部,不能在静态方法或静态块中使用。

  2. this关键字不能用于访问父类的成员变量或方法。

  3. 使用this关键字时,应该避免歧义或混淆,尽量使代码易于理解和维护。

总之,this关键字是Java中一个非常有用的关键字,它可以用于引用当前对象的成员变量、方法以及构造方法,从而提高代码灵活性和可读性。在实际开发中,我们需要掌握如何正确使用this关键字,以便让代码更加优雅和高效。

5.5.3 this关键字的使用细节和注意事项

在使用Java中的this关键字时,需要注意以下几个细节和注意事项:

  1. this关键字只能用于实例方法和构造方法中,不能用于静态方法中。

  2. 使用this关键字引用成员变量时,需要遵循就近原则。也就是说,如果参数名称与成员变量名称相同,则this关键字将引用成员变量而非参数。

  3. 在一个构造方法中,使用this调用另一个构造方法时,必须将this语句放在构造方法体的第一行,否则会出现编译错误。

  4. 如果类中定义了多个构造方法,可以通过this关键字在不同构造方法之间进行调用,从而实现代码复用。但要注意在构造方法中不要形成死循环。

  5. 使用return this;语句将当前对象作为返回值返回时,可以实现链式调用,但应谨慎使用,以避免代码过于复杂难以维护。

  6. 尽管this关键字可以提高代码的可读性和灵活性,但过多地使用它可能会使代码变得复杂难以阅读和维护,因此应该适量使用。

总之,在使用Java中的this关键字时,我们需要注意以上细节和注意事项,以确保代码正确、简洁、易于理解和维护。

博主有话说

博主在这里给大家推荐几个学习网站

菜鸟教程 - 学的不仅是技术,更是梦想! (runoob.com)

| Java 全栈知识体系 (pdai.tech)

还有提升能力的刷题网站

AcWing(这个网站可以参加周赛,与其他同学竞争,比赛,是个比较好用的网站)

还有大家比较熟悉的力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台,甚至蓝桥杯的网站也可以,蓝桥杯对我们这样的大学生比较重要,大家多去刷刷题对自己也有比较好的提升。
家比较熟悉的力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台,甚至蓝桥杯的网站也可以,蓝桥杯对我们这样的大学生比较重要,大家多去刷刷题对自己也有比较好的提升。

  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值