前言
基础部分看的是B站动力节点杜老师的视频
标识符与关键字
2.1. 标识符
2.1.1. 什么是标识符
程序员有权利命名的单词都是标识符
2.1.2 标识符命名规则
- 标识符首字母只能为英文、下划线、$、中文
- 标识符只能出现英文、下划线、$、中文、数字
- 关键字不能为标识符
- 标识符严格区分大小写
- 标识符理论上没有长度限制
- java中的标识符严格区分大小写的说明:
作用域不同标识符可以重名 - 但是对于类名来说,如果一个java源文件中同时出现了:B类和b 类,那么谁在前就生成谁。大家以后最好不 要让类名“相同”,最好类名是不同的。
2.1.3. 标识符的命名规范
- 变量名、方法名:首字母小写第二个因为字母首字母大写
- 类名、接口名:首字母大写第二个英文单词首字母大写
- 常量名:所有字母大写,第一个与第二个字母之间用下划线连接
- 均遵守驼峰命名法
2.2. 关键字
2.2.1.什么是关键字
- sun公司提前编写好具有特殊含义的词
- 关键字不把你作为标识符
- 关键字全部小写
3. 变量
3.1. 什么是变量
- 内存中存储数据的最基本的单元
- 变量的三要素:变量的数据类型、变量的名字、变量中保存的值
- 变量的数据类型:决定数据的空间大小
- 变量的名字:方便程序员调用
- 变量的值:变量存储的数据
- 在java语言中有一个规定,变量必须先声明,再赋值才能访问。(没有值相当于这个空间没有开辟。)
- int n1=100,n2=200,n3 = 300 ; // 一行上面可以声明多个变量的正确方式
public class VarTest1{
public static void main(String args){
int age ;
}
}
/*
在这里的age系统会默认赋值为0 所以符合Java语法,系统不会报错
若为String 类型的变量这里默认为 null
但若要输出age就会报错,未完成变量的初始化
*/
public class VarTest2{
public static void main(String[] args){
/*
int n1,n2,n3 = 300 ; // 错误的一行上面可以声明多个变量
System.out.println(n3);
System.out.println(n2);
System.out.println(n1);
java允许一行申明多个变量,若 为 int a,b,c = 300 ;输出c 有值300,其余
两未赋值如输出 a, b 会报错 未完成初始化,若只输出System.out.println(c);不会报
错
*/
//正确一行声明多个变量的方法
int n1=100,n2=200,n3 = 300 ; // 一行上面可以声明多个变量的正确方式
System.out.println(n3);
System.out.println(n2);
System.out.println(n1);
}
}
- 变量的作用域
- 成员变量:类体中声明的变量
- 局部变量:方法体内声明的变量
- } 为 一个作用域,关于变量的有效范围:出了大括号就不认识了。
- 总结:
- 变量根据声明的位置可以分为成员变量和局部变量,并且声明位置不同作用域也是不同的。
- 还需要注意在同一个域当中变量名不能重名,不同的域,变量名可以相同,只不过 Java 遵循就近原则,会自动访问离它最近的数据。
4. 数据
- 在java语言中“数据”被称为“字面量”。
- 1个字节=8个比特位
1个比特位就是一个1或0.
注意:比特位是二进制位。
int i = 1; 实际上在内存中是这样表示的:
00000000 00000000 00000000 00000001
int i = 2;
00000000 00000000 00000000 00000010
4.1数据类型
- 数据类型用来声明变量,程序在运行过程中根据不同的数据类型分配不同大小的空间。
- 数据类型分类:
- 基本数据类型:八种基本数据类型
数据类型 |
占用字节数量(byte) |
取值范围 |
byte |
1 |
[-128,127] |
shot |
2 |
[-32768,32767] |
int |
4 |
[-2147483648,2147483647] |
long |
8 |
|
float |
4 |
|
double |
8 |
|
boolean |
1 |
true为(00000001) |
char |
2 |
[0,65535] |
- 说明:
- short和char实际上容量相同,不过char可以表示更大的数字。因为char表示的是文字,文字 没有正负之分,所以char可以表示更大的数字。
- 引用数据类型:字符串型String属于引用数据类型
- java中除了基本数据类型之外,剩下的都是引用数据类型。
4.2. 字符编码
- 字符编码是人为的定义的一套转换表。
- 在字符编码中规定了一系列的文字对应的二进制
- 编码和解码的时候必须采用同一套字符编码方式,不然就会出现乱码。需要记住的字符编码名称:
- ASCII('a' 是97 'A '是65 '0 '是47)
- GBK 编 码方式简体中文
- Big5 繁体中文
- utf unicode编码统一了全球所有的文字,支持所有文字。
4.3. 转义字符
- java语言中“\”负责转义。
- '\t' 表示一个制表位
System.out.println("adc\tdef");
//打印出来的结果为:adc tdef
// \t 表示一个TAB键
- '\u4e2d'
char x ='\u4e2d' ;
System.out.println(X);
//输出的结果为'中'
- '\n'表示换行
System.out.print('\n');
//表示换一行
😄在控制台输出一个 ' 字符怎么办?
System.out.println("'");
System.out.println('\'');
😄 在控制台输出一个 \ 字符怎么办?
System.out.println('\\');
4.4. 基本数据类型
- 字符型字面量
char占用两个字节,可以存储一个汉字 - 整数型字面量
- byte 、 short 、int 、long
对于以上的四个类型来说,最常用的是int。开发的时候不用斤斤计较,直接选择使用int就行了。 - 在任何情况下,整数型的字面量默认被当做int类型处理。(记住就行)
- 如果希望该“整数型字面量”被当做long类型来处理,需要在“字面量”后面添加L
- 任意一个浮点型都比整数型空间大。
- Boolean型字面量
在java语言中boolean类型只有两个值:true和false。没有其它值( 00000001 表示 true 00000000 表示false) - 浮点型字面量
- float是单精度,double是双精度,double更精确float和double存储数据的时候都是存储的近似值。
思考:0.6 - 0.3 =0.30000001
- 在银行方面或者说使用在财务方面,double也是远远不够的,在java中提供了一种精度更高 的类型,这种类型专门使用在财务软件方面:java.math.BigDecimal (不是基本数据类型, 属于引用数据类型。)
- java中规定,任何一个浮点型数据默认被当做double来处理。如果想让这个浮点型字面量被当做float类型来处理,那么请在字面量后面添加F/f。
4.5. 数据类型转换
- 基本数据类型转换
- 小容量可以直接赋值给大容量,称为自动类型转换。
- 大容量不能直接赋值给小容量,需要使用强制类型转换符进行强转。但需要注意的是:加强 制类型转换符之后,虽然编译通过了,但是运行的时候可能会损失精度。
- java中有一个语法规则:当这个整数型字面量没有超出byte、short、char的取值范围,那么 这个整数型字面量可以直接赋值给byte、short、char类型的变量。这种语法机制是为了方便 写代码,而存在的。
- 目前 double 类型转换成 int 类型的强制转换不需要四舍五入直接舍去小数点后面的任何数
- 整数型的混合运算
- byte、short、char的混合运算
结论:byte、char、short做混合运算的时候,各自先转换成int再做运算。
- 多种数据类型
多种数据类型做混合运算的时候,最终的结果类型是“最大容量”对应的类型。char+short+byte 这个除外。 因为char + short + byte混合运算的时候,会各自先转换成int再做运算。
- 总结:
- 八种基本数据类型中,除 boolean 类型不能转换,剩下七种类型之间都可以进行转换;
- 如果整数型字面量没有超出 byte,short,char 的取值范围,可以直接将其赋值给byte,short,char 类型的变量;
- 小容量向大容量转换称为自动类型转换,容量从小到大的排序为:
byte < short(char) < int < long < float < double
其中 short和 char 都占用两个字节,但是char 可以表示更大的正整数; - 大容量转换成小容量,称为强制类型转换,编写时必须添加“强制类型转换符”,但运行时可能出现精度损失,谨慎使用;
- byte,short,char 类型混合运算时,先各自转换成 int 类型再做运算;
- 多种数据类型混合运算,各自先转换成容量最大的那一种再做运算;
- 所有的笔试题都超不出以上的6条规则。死记硬背。
5. 运算符
5.1 算术运算符
- 运算符号:
小数运算特点:对于小数运算出来的结果都是一个近似值
+求和 |
* 乘积 |
++ 自加1 |
- 相减 |
/ 商 |
-- 自减1 |
% 求余数(求模) |
- 对于++运算符来说:可以出现在变量前,也可以出现在变量后。
- 不管出现在变量前还是后,总之++执行结束之后,变量的值一定会自加1。
- 当++出现在变量后面先赋值在运算,出现在变量的前面先运算再复值
- 出现在变量后面
int a = 10 ;
int b = a++ ;
System.out.println(b);//此时b的值为:10
System.out.println(a);//此时a的值为:11
- 当++出现在变量前先运算在赋值
int i = 20 ;
int c = ++i ;
System.out.println(c);//此时c的值为:21
System.out.println(i);//此时i的值为:21
😄 :分析以下代码
int c = 90 ;
System.out.println(c++); // 输出结果为90
/*
分析如下:
拆分第二行代码得:
int temp = c++
System.out.println(temp);
即temp的值为90
*/
- % 小数求余数公式
5.2. 关系运算符
> = < <= == !=
- 所有的关系运算符的运算结果都是布尔类型,不是true就是false,不可能是其他值
- 在java语言中: = : 赋值运算符 == :关系运算符,判断是否相等
- 关系运算符中如果有两个符号的话,两个符号之间不能有空格。
5.3. 逻辑运算符
- & 逻辑与(可以翻译成并且)
对于逻辑与&运算符来说,只要有一边是false,结果就是false。 只有两边同时为true,结果才是true。 - | 逻辑或(可以翻译成或者)
对于逻辑或呢只要有一边是true,结果就是true。 - ! 逻辑非(取反)
- 逻辑运算符两边要求都是布尔类型,并且最终的运算结果也是布尔类型。这是逻辑运算符的特点。
- && 短路与
- || 短路或
- 短路现象:右边表达式不执行,这种现象叫做短路现象。
- 什么时候发生短路或现象
- || 短路或
- “或”的时候只要有一边是true,结果就是true。所以,当左边的表达式结果是true的时候,右边的表达式不需要执行,此时会短路。
- 什么时候使用&&,什么时候使用&
- 从效率方面来说,&&比&的效率高一些。因为逻辑与&不管第一个表达式结果是什么,第二个表达式一定会执行。
- 以后的开发中,短路与&&和逻辑与还是需要同时并存的。大部分情况下都建议使用短路与 &&只有当既需要左边表达式执行,又需要右边表达式执行的时候,才会选择逻辑与&。其余同理
网络异常,图片无法展示|
5.4. 赋值运算符
- 赋值运算符包括“基本赋值运算符”和“扩展赋值运算符”:基本的、扩展的。
- 基本赋值运算符: =
- 扩展的赋值运算符:
+= -= *= /= %=
注意: 扩展赋值运算符在编写的时候,两个符号之间不能有空格。 + = 错误的。 += 正确的。
- 使用扩展赋值运算符的时候,永远都不会改变运算结果类型。
- 问题:byte i = 100 ; i += 10 和 i = i + 10 真的是完全一样吗?
答案:不一样,只能说相似,其实本质上并不是完全相同。
i += 110 ; // 可以理解为 :i=(byte)(100+110) 超出了 byte的取值范围 会自然损失精度
5.5. 条件运算符(三目运算符)
- 语法格式: 布尔表达式 ? 表达式1 : 表达式2
- 执行原理:
布尔表达式的结果为true时,表达式1的执行结果作为整个表达式的结果。
布尔表达式的结果为false时,表达式2的执行结果作为整个表达式的结果。 - 分析以下代码是否存在语法错误
5.6. +运算符
- +运算符在java语言中有两个作用。
作用1:求和
作用2:字符串拼接
- 什么时候求和?什么时候进行字符串的拼接呢?
当 + 运算符两边都是数字类型的时候,求和。
当 + 运算符两边的“任意一边”是字符串类型,那么这个+会进行字符串拼接操作。
- 字符串拼接完之后的结果还是一个字符串。当一个表达式当中有多个加号的时候遵循“自左向右”的顺序依次执行。
5.7. 键盘输入
- 方法一:
import java.util.Scanner; //导入Scanner扫描仪
public clss Test{
public static void main(String[] args){
Scanner n = new Scanner(System.in); //创建键盘扫描对象n,n可以改动
System.out.print("请输入一个数字:
"); //向控制台输出一个欢迎信息
int num = n.nextInt(); //从键盘接收一个int类型的变量,然后复制一份值,赋
值给 num
}
}
- 方法二:
public clss Test{
public static void main(String[] args){
java.util.Scanner n = new java.util.Scanner(System.in); //创建键盘
扫描对象
System.out.print("请输入一个数字:
"); //向控制台输出一个欢迎信息
int number = n.nextInt();
}
}
6. 控制语句
6.1. 控制语句
- 什么是控制语句:控制语句的出现可以让我们的程序具有逻辑性/条理性,可以使用控制语句来实 现一个“业务”了。
- 控制语句包括三类:
选择语句(分支语句): if语句 switch语句
循环语句:主要循环反复的去执行某段特定的代码块。 for循环 while循环 do..while..循环
转向语句:break continue return
6.2. 分支语句
- if语句
if语句是分支语句,也可以叫做条件语句。
- 对于if语句来说,在任何情况下只能有1个分支执行,不可能存在2个或者更多个分支执行。
- if语句 中只要有1个分支执行了,整个if语句就结束了。(对于1个完整的if语句来说的。)
- 4种语法机制中,凡是带有else分支的,一定可以保证会有一个分支执行。
- { }只有1条语句时,那么大括号{}可以省略,但为了可读性,最好不要省略。
- 控制语句和控制语句之间是可以嵌套的,但是嵌套的时候大家最好一个语句一个语句进行分析,不 要冗杂在一起分析。
- 程序分析
网络异常,图片无法展示|
- switch语句
- switch语句的语法格式:
- switch后面的()里面不能出现空格等其它字符,()里面支持int类型以及String类型。
- switch语句中“值”与“值1”、“值2”比较的时候会使用“==”进行比较。
- switch语句的执行原理:
拿“值”与“值1”进行比较,如果相同,则执行该分支中的java语句,然后遇到"break;"语句,switch语句就结束了。
注意:如果分支执行了,但是分支最后没有“break;”,此时会发生case穿透现象。
所有的case都没有匹配成功,那么最后default分支会执行。
- 语法:
网络异常,图片无法展示| - 关于case合并的写法:
case 值1 : case 值2 :
java语句;
breal;
6.3. 循环语句
- for循环
- 语法机制:
for(初始化表达式; 条件表达式; 更新表达式){ 循环体; // 循环体由java语句构成
java语句; java语句;
....
} - 注意:
- 第一:初始化表达式最先执行,并且在整个循环中只执行一次。
- 第二:条件表达式结果必须是一个布尔类型,也就是:true或false
- 第三:for循环结束内存就释放了
- 执行原理:
先执行初始化表达式,并且初始化表达式只执行1次。
然后判断条件表达式的结果,如果条件表达式结果为true,则执行循环体。
循环体结束之后,执行更新表达式。更新完之后,再判断条件表达式的结果,如果还是true,继续 执行循环体。
直到更新表达式执行结束之后,再次判断条件时,条件为false,for循环终止。 - 更新表达式的作用是:控制循环的次数,换句话说,更新表达式会更新某个变量的值,这样条件表达式的结果才有可能从true变成false,从而终止for循 环的执行,如果没有更新表达式,很有可能会导致死循环。
- 初始化表达式、条件表达式、更新表达式 其实都不是必须的!!!
- 分析以下程序:
分析:15行 语法格式错误
改正: 将红线的number 改成 int i = number
只能出现这种语法格式 (int number= 0其 余不对或者将number 去除
- while语句
- while循环的语法机制以及执行原理语法机制:
while(布尔表达式){
循环体;
} - 执行原理:
判断布尔表达式的结果,如果为true就执行循环体,循环体结束之后,再次判断布尔表达 式的 结果,如果还是true,继续执行循环体,直到布尔表达式结果为false,while循环结束。 - while的循环次数:0~n次。
- for与while可以互换,只是语法格式不同
- do while 循环
- 语法机制:
do {
循环体;
} while(布尔表达式);
注意:do..while循环最后的时候别漏掉“分号”
执行原理:(先执行在判断)
对于do..while循环来说,循环体至少执行1次。循环体的执行次数是:1~n次。
6.4. 转向语句
- break语句
- break语句比较特殊,特殊在:break语句是一个单词成为一个完整的java语句。另外:continue也是这样,他俩都是一个单词成为一条语句。
- break 翻译为折断、弄断。
- break;语句可以用在哪里呢?
- switch语句当中,用来终止switch语句的执行。
- 用在switch语句当中,防止case穿透现象,用来终止switch。
- break;语句用在循环语句当中,用来终止循环的执行。以下程序主要是以for循环为例学习break转向语句。
- break;语句的执行并不会让整个方法结束,break;语句主要是用来终止离它最近的那个循环语句。
- break语句终止指定的循环: 语法 :
网络异常,图片无法展示|
- 终止了外层的 for循环,这种方法用来终止指定的循环
- continue语句
- continue翻译为:继续
- continue语句的作用是:终止当前"本次"循环,直接进入下一次循环继续执行。
- continue语句指定循环
网络异常,图片无法展示|
- return
- 用来终止当前方法的执行
7. 方法
7.1. 方法
- 方法的语法:
- 方法(英语单词: method )是可以完成某个特定功能的并且可以被重复利用的代码片段。
在C语言中,方法被称为“函数”。在java中不叫函数,叫做方法。 - 对于一个java程序来说,如果没有“方法”,代码无法得到复用。(怎么提高复用性,可以定义方法, 然后需要使用该功能的时候,直接调用一下方法即可。这样代码就得到复用了。)
- 程序开始执行的时候是先执行main方法。因为main方法是一个入口。
- 在java语言中所有的方法体中的代码都必须遵循自上而下顺序依次逐行执行。
- main方法不需要程序员手动调用,是由JVM调用的。
- 但是除了main方法之外其他的方法,都需要程序员手动调用,方法只有调用的时候才会执行 ,方法不调用是不会执行的。
- 语法机制:
- [修饰符列表] 返回值类型 方法名( 形式参数列表 ) {
方法体;
}
- 注意:
- 符号叫做中括号,以上中括号 [ ] 里面的内容表示不是必须的,是可选的。方法体由Java语句构成。
- 方法定义之后需要去调用,不调用是不会执行的。
- 关于修饰符列表:修饰符列表不是必选项,是可选的。目前为止,大家统一写成:public static后面你就理解应该怎么写了。
- 关于返回值类型:
第一:返回值类型可以是任何类型,只要是java中合法的数据类型就行。
第二:什么是返回值?
- 返回值一般指的是一个方法执行结束之后的结果。结果通常是一个数据,所以被 称为“值”,而且还叫“返回值”。
- 方法就是为了完成某个特定的功能,方法结束之后大部分情况下都是有一个结果 的,而体现结果的一般都是数据。数据得有类型。这就是返回值类型。
- 方法执行结束之后的返回值实际上是给调用者了,谁调用就返回给谁。
第三:当一个方法执行结束不返回任何值的时候,返回值类型也不能空白,必须写上void关键字。所 以void表示该方法执行结束后不返回任何结果。
第四:如果返回值类型“不是void”,那么你在方法体执行结束的时候必须使用"return值;"这样的语句来完成“值”的返回,如果没有“return 值;”这样的语句那么编译器会报错。
- return 值; 这样的语句作用是什么?
作用是“返回值”,返回方法的执行结果。
第五:只要有“return”关键字的语句执行,当前方法必然结束。return只要执行,当前所在的方法结束,记住:不是整个程序结束。return后面不能跟java语句。
第六:如果返回值类型是void,那么在方法体当中不能有“return 值;”这样的语句。但是可以有”return;”语句。这个语句“return;”的作用就是用来终止当前方法的。
第七:除了void之外,剩下的都必须有“return 值;”这样的语句。
- 方法名称
方法名要见名知意。(驼峰命名方式)
方法名在标识符命名规范当中,要求首字母小写,后面每个单词首字母大写。只要是合法的标识符就行。
- 形式参数列表
简称:形参
注意:形式参数列表中的每一个参数都是局部变量,方法结束之后内存释放。形参的个数是:0~N个。
形参有多个的话使用“逗号,”隔开。逗号是英文的。
形参的数据类型起决定性作用,形参对应的变量名是随意的。形参对应数据可以与形参数据类型不同
实参要与形参数据相匹配
- 方法体
- 由Java语句构成。java语句以“;”结尾。
- 方法体当中编写的是业务逻辑代码,完成某个特定功能。
- 在方法体中的代码遵循自上而下的顺序依次逐行执行。
- 在方法体中处理业务逻辑代码的时候需要数据,数据来源就是这些形参。
- 方法定义之后怎么调用呢?
- 方法必须调用才能执行。
- 调用语法:
类名.方法名(实际参数列表); - 在同一个类当中,调用方法可以不加类名。
- 实参和形参的类型必须一一对应,另外个数也要一一对应。
- 方法定义应在类体中,在类体中没有顺序的要求
- 方法调用的代码优化
- 也可以 直接System.out.println(sum(100,200));
- 在方法调用的时候,什么时候“类名.”是可以省略的。什么时候不能省略?
a()方法调用b()方法的时候,a和b方法都在同一个类中,“类名.”可以省略。如果不在同一个类中 “类名.”不能省略。 - 注意:
- 任何一个方法体当中的代码都是遵循自上而下的顺序依次逐行执行的。
- main方法最先执行, 并且 main方法是最后一个结束。
- main结束,整个程序就结束了。调用程序不一定写到main方法中,不要把main方法特殊化。main方法也是一个普通方法。
- break;语句和return;语句有什么区别?
不是一个级别。
- break;用来终止switch和离它最近的循环。
- return;用来终止离它最近的一个方法。
- return语句后面不能跟代码 否则编译器会报错。
- 分析以下代码
7.2. jvm内存结构图
- javac 命令是编译期
- 将字节码文件装载是运行期(即Java命令后)
- 要明白这个的原理:
网络异常,图片无法展示|
Jvm内存重要的三块内存结构图:
- 画图时在内存中应该只能有数据,不能有代码,出现代码是为了 方便理解。
- JVM中栈数据结构详解:
7.3. 代码的升级
- 第一个
7.4. 方法的重载
- 方法重载的详解
使用方法重载机制。解决之前的两个缺点。
优点1:代码整齐美观。
优点2:“功能相似”的,可以让“方法名相同”,更易于以后的代码编写。 - 在java语言中,是怎么进行方法区分的呢?
首先java编译器会通过方法名进行区分。
但是在java语言中允许方法名相同的情况出现。如果方法名相同的情况下,编译器会通过方法的参数类型进行方法的区分。
3. eg:
- 什么时候需要考虑使用方法重载?
在同一个类当中,如果“功能1”和“功能2”它们的功能是相似的,那么可以考虑将它们的方法名一 致,这样代码既美观,又便于后期的代码编写(容易记忆,方便使用)。
注意:方法重载 overload 不能随便使用,如果两个功能压根不相干,不相似,根本没关系,此时两个方法使用重载机制的话,会导致编码更麻烦。无法进行方法功能的区分。
- 什么时候代码会发生方法重载?
条件1:在同一个类当中
条件2:方法名相同
条件3:参数列表不同
参数的个数不同算不同
参数的类型不同算不同
参数的顺序不同算不同
只要同时满足以上3个条件,那么我们可以认定方法和方法之间发生了重载机制。
注意:
不管代码怎么写,最终一定能让java编译器很好的区分开这两个方法。
方法重载和方法的返回值类型无关。
方法重载和方法的“修饰符列表”无关。
7.5. println()详解
7.6. 代码的简单封装
目前就是将方法写在另一个类中。后面详解
7.7. 方法递归
网络异常,图片无法展示
|
- 什么是方法递归?
方法自己调用自己,这就是方法递归
- 当递归时程序没有结束条件,一定会发生:
栈内存溢出错误:StackOverflowError
所以:递归必须要有结束条件。(这是一个非常重要的知识点。)
JVM发生错误之后只有一个结果,就是退出JVM。
- 递归假设是有结束条件的,就一定不会发生栈内存溢出错误吗?
假设这个结束条件是对的,是合法的,递归有的时候也会出现栈内存溢出错误。 因为有可能递归的太深,栈内存不够了。因为一直在压栈。
4. 在实际的开发中,不建议轻易的选择递归,能用for循环while循环代替的,尽量使用循环来做。
因为循环的效率高,耗费的内存少。递归耗费的内存比较大,另外递归的使用不当,会导致JVM死掉。(但在极少数的情况下,不用递归,这个程序没法实现。)
所以:递归我们还是要认真学习的。
- 方法里面调用方法时,方法这一行不结束,后面部分先不执行。
- 在实际的开发中,假设有一天你真正的遇到了:StackOverflowError你怎么解决这个问题,可以 谈一下你的思路吗?
我来谈一下我的个人思路:
第一步:先检查递归的结束条件对不对。如果递归结束条件不对,必须对条件进一步修改,直到正确为止。
第二步:假设递归条件没问题,怎么办?
这个时候需要手动的调整JVM的栈内存初始化大小。可以将栈内存的空间调大点。(可以调整大一些。)
第三步:调整了大小,如果运行时还是出现这个错误,没办法,只能继续扩大栈的内存大小。
(java -X)这个可以查看调整堆栈大小的参数
6.1 此时jvm内存图:
此时的栈内存结构图:
7.8. subString方法
- Java中String类的substring() 方法作用:返回字符串的 子 字符串。
- 语法:
public String substring(int beginIndex)
或
public String substring(int beginIndex, int endIndex)
- 画图了解
- 示例
public class RunoobTest {
public static void main(String args[]) {
String Str = new String("This is text");
System.out.print("返回值 :" );
System.out.println(Str.substring(4) );
System.out.print("返回值 :" );
System.out.println(Str.substring(4, 10) );
}
}
7.9 Java中String类的replace()方法
- 作用:replace() 方法通过用 newChar 字符替换字符串中出现的所有 searchChar 字符,并返回替换后的新字符串。
- 语法:publicString replace(char searchChar,char newChar)
- 参数:searchChar -- 原字符 newChar -- 新字符
- 返回值:替换后生成的新字符串
- 实例:
7.9 HomeWork
题目一:使用递归的方式计算n的阶乘,并画出内存结构图,使用递归的方式实现一个 , 使用for循环方式实现一个5的阶乘为:5x4x3x2x1;
注意:数字不能太大否则会超出整数的取值范围,目前实现整数5就行。