目录
1-递归
介绍:方法自己调用自己
-
注意:设计递归的出口,如果没有设计出口
-
StackOverflowError:栈内存溢出
案例1:求阶乘
5 * 4 * 3 * 2 * 1
6 * 5 * 4 * 3 * 2 * 1
...
package com.lyl.method;
public class MethodDemo1 {
public static void main(String[] args) {
System.out.println(jiecheng(5));
}
/*
定义方法求进阶:
!5 :5*4的阶乘
!4 :4*3的阶乘
!3 :3*2的阶乘
!2 :2*1的阶乘
!1 :1
*/
private static int jiecheng(int num) {
if (num == 1) {
return 1;
} else {
//思路:我要调用方法解决问题,发观自己这个方法,就是解决河题的方法,就递归调用
return num * jiecheng(num - 1);
}
}
}
案例2:求1~n之间的数字之和(递归)
package com.lyl.method;
public class MethodDemo2 {
public static void main(String[] args) {
System.out.println(sum(5));
}
public static int sum(int num) {
if (num == 1){
return 1;
}else {
return num + sum(--num);
}
}
}
案例3:不死神兔(斐波那契数列)
描述:从前有一对小兔子,过了一个月之后可以长成大兔子,再过一个月又能生下一对小兔子...
-假如兔子不死,10个月后有多少对兔子...
package com.lyl.method;
public class MethodDemo3 {
/*
1 1 2 3 5 8 13 21
从第三个月开始:兔子的对数,是前两月相加的和
*/
public static void main(String[] args) {
System.out.println(get(8));
}
public static int get(int month) {
if (month == 1 || month == 2) {
return 1;
} else {
//思路: 第month的数量=month-1 + month-2;
return get(month - 1) + get(month - 2);
}
}
}
-
需求:让D盘下所有的.java文件找出来
-
D:获取所有的文件和文件夹 文件:获取文件名,判断是否以.java为结尾文件夹:进入文件夹继续查找
递归的细节:
-
直接递归
-
间接递归(A调B,B调C,C调A),了解即可
2-日期类
-
需求:注册XXX社交账户
输入自己的生日: 1990-2-6
-
计算出年龄
-
-
需求:疯狂星期四
周一,周二:不展示疯狂星期四的套餐
周四:展示疯狂星期四的套餐
JDK8之前(今日学习)
-
Date类(时间)
注意:是在util包下
package com.lyl.time;
import java.util.Date;
public class DateDemo1 {
/*
Date类代表时间
1.构造方法:
public Date():将当前时间封装为Date时间对象
*/
public static void main(String[] args) {
Date d1 = new Date();
System.out.println(d1);
}
}
输出结果:Sun Mar 26 10:23:49 CST 2023
package com.lyl.time;
import java.util.Date;
public class DateDemo1 {
/*
Date类代表时间
1.构造方法:
public Date():将当前时间封装为Date时间对象
public Date(long time):根据传入的毫秒值,来封装时间对象
*/
public static void main(String[] args) {
Date d1 = new Date();
System.out.println(d1);
Date d2 = new Date(1000L);
System.out.println(d2);
}
}
输出结果:Sun Mar 26 10:26:08 CST 2023 Thu Jan 01 08:00:01 CST 1970
package com.lyl.time;
import java.util.Date;
public class DateDemo1 {
/*
Date类代表时间
1.构造方法:
public Date():将当前时间封装为Date时间对象
public Date(long time):根据传入的毫秒值,来封装时间对象
2.成员方法:
public long getTime():获取毫秒值
public void setTime(long time):根据传入的毫秒值,来封装时间对象
*/
public static void main(String[] args) {
Date d1 = new Date();
System.out.println(d1);
Date d2 = new Date(); //Student stu = new Student();
d2.setTime(1000); //stu.setAge(23);
System.out.println(d2);
System.out.println(d1.getTime());
System.out.println(d2.getTime()); // 时间原点 ~ 1970-1-1 00:00:01
System.out.println(System.currentTimeMillis()); // 时间原点 ~ 此刻时间
}
}
-
SimpleDateFormat类(时间格式化)
package com.lyl.time;
import java.text.SimpleDateFormat;
import java.util.Date;
public class SimpleDateFormatDemo1 {
/*
SimpleDateFormat:时间格式化
构造方法:
public SimpleDateFormat(String pattern):根据传入的字符串模式,来格式化时间对象
常用成员方法:
public String format(Date date) 将日期格式化成日期/时间字符串
*/
public static void main(String[] args) {
Date time = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
String format = sdf.format(time);
System.out.println(format);
}
}
输出结果:2023年03月26日 10:37:51
// public Date parse(String source) 将参数中的日期字符串,解析为Date日期对象
public static void main(String[] args) throws ParseException {
String s = "2008年8月8日";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
Date date = sdf.parse(s);
System.out.println(date);
}
输出结果:Fri Aug 08 00:00:00 CST 2008
练习
-
键盘录入用户生日,计算活了多少天
package com.lyl.time;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;
public class BirthdayTest {
/*
需求:键盘录入用户的生日,程序计算出用户来到了这个世界多少天
1.键盘录入生日(以字符串的形式接受)
String birthday;
2.将生日字符串转换Date日期对象
Date birthdayDate
3.创建Date对象,封装此刻的时间
Date todayDate
4.计算附间差(毫秒)
todayDate.getTime()-birthdayDate.getTime();
5.将毫秒值转换为天的单位
毫秒值/1000/60/60/24
*/
public static void main(String[] args) throws ParseException {
System.out.println("请输入生日(格式:xxxx年xx月xx日)");
//1.键盘录入生日(以字符串的形式接受)
String birthday = new Scanner(System.in).nextLine();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
//2.将生日字符串转换Date日期对象
Date birthdayDate = sdf.parse(birthday);
//3.创建Date对象,封装此刻的时间
Date todayDate = new Date();
//4.计算附间差(毫秒)
Long time = todayDate.getTime() - birthdayDate.getTime();
//5.将毫秒值转换为天的单位
System.out.println(time / 1000 / 60 / 60 /24);
}
}
-
Calendar类(日历)
Calendar类是一个抽象类,用Calendar rightNow = Calendar.getInstance ();获取子类对象
package com.lyl.calendar;
import java.util.Calendar;
public class Test {
/*
Calendar类创建对象:
static Calendar getInstance() :获取对象
常用成员方法:
public int get(int field) :根据传入的字段,获取对应的日历信息
常用字段:
Calendar.YEAR :获取年
Calendar.MONTH :获取月 注意:月份是0~11,月份获取出来需要+1操作
Calendar.DAY_OF_MONTH :获取日
Calendar.DAY_OF_WEEK : 获取星期 注意:日 一 二 三 四 五 六
解决:使用查表法
Calendar.DAY_OF_YEAR : 获取一年中的多少天
*/
public static void main(String[] args) {
Calendar calendar = Calendar.getInstance();
System.out.println(calendar.get(Calendar.YEAR));
System.out.println(calendar.get(Calendar.MONTH)+1);
System.out.println(calendar.get(Calendar.DAY_OF_MONTH));
char[] weekDay = {' ','日','一','二','三','四','五','六'};
// 0 1 2 3 4 5 6 7
int index = calendar.get(Calendar.DAY_OF_WEEK);
System.out.println(weekDay[index]);
System.out.println(calendar.get(Calendar.DAY_OF_YEAR));
}
}
输出结果:2023 3 26 日 85
3-异常
-
异常介绍:指的是程序在执行过程中,出现的非正常的情况,最终会导致JVM的非正常停止
ArrayIndexOutofBoundsException ClassCastException NullPointerException ...
-
异常学什么?
能够看懂异常信息 掌握异常的两种处理方式 自定义异常
-
从下往上慢慢看,看不懂异常信息就翻API
-
异常体系
Exception类的异常:编码可以解决。
-
1.异常是什么?
异常是代码在编译或者执行的过程中可能出现的错误。
-
2.异常分为几类?
编译时异常、运行时异常。
-
编译时异常:没有继承RuntimeExcpetion的异常,编译阶段就会出错。
-
运行时异常:继承自RuntimeException的异常或其子类,编译阶段不报错,运行可能报错。
-
3.学习异常的目的?
避免异常的出现,同时处理可能出现的异常,让代码更稳健。
异常的处理方式
1,自己能够解决,自己处理
2,自己解决不了,找上级处理(抛出异常)
异常的默认处理流程
-
虚拟机会在出现异常的代码那里自动的创建一个异常对象:ArithmeticException
-
异常会从方法中出现的点这里抛出给调用者,调用者最终抛出给VM虚拟机
-
虚拟机接收到异常对象后,先在控制台直接输出异常信息数据
-
直接从当前执行的异常点干掉当前程序
-
后续代码没有机会执行了,因为程序已经噶了
异常处理方案
异常的第一种处理方案:throws抛出异常
在方法的后面,编写throws关键字,再跟上异常类名
细节1:你调用的方法,如果抛出了异常,就需要继续声明throws抛出异常
细节2:如果一个方法中抛出的异常特别多,可以选择抛出一个大的异常
细节3:子类在重写父类方法的时候,不能抛出父类中没有的异常,或者是比父类更大的异常(父亲坏了,儿子不能比父亲还坏)
异常的第二种处理方案:try...catch
快捷键(IDEA开发工具):选中要包裹的代码,ctrl+alt+t
try{
可能会出现异常的代码
}catch(要捕获的异常类名对象名){
异常的处理方案
}
好处:不会将程序终止,后续的代码还可以继续执行
注意:1.如果编写了多个cath,最大的异常一定要放最后捕获
2.cath中可以同时捕获多个异常,中间用 | 隔开,但是不推荐。(无法具体明确是何异常)
练习
-
以字符串的形式,从键盘录入学生的姓名和年龄,将数据封装为学生对象
package com.lyl.exception;
import com.lyl.domain.Student;
import java.util.Scanner;
public class ExceptionTest1 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入学生姓名:");
String name = sc.nextLine();
System.out.println("请输入学生年龄:");
int age = 0;
while (true){
try {
age = Integer.parseInt(sc.nextLine());
break;
} catch (NumberFormatException e) {
System.out.println("您的输入有误,请重新输入:");
}
}
Student stu = new Student(name,age);
System.out.println(stu);
}
}
输出结果:
请输入学生姓名:
zhangsan
请输入学生年龄:
28.5
您的输入有误,请重新输入:
dfsd
您的输入有误,请重新输入:
23
Student{name = zhangsan, age = 23}
代码增强:
Student类中:
public Student(String name, int age) {
this.name = name;
setAge(age);
}
public void setAge(int age) {
if (age >= 0 && age <= 120){
this.age = age;
}else {
throw new RuntimeException("年龄有误,请检查是否为0~120之间");
}
}
测试类中:
while (true) {
try {
age = Integer.parseInt(sc.nextLine());
Student stu = new Student(name, age);
System.out.println(stu);
break;
} catch (NumberFormatException e) {
System.out.println("输入有误,请重新输入:");
} catch (RuntimeException e) {
System.out.println(e.getMessage());
}
}
输出结果:
请输入学生姓名:
zhangsan
请输入学生年龄:
-23
年龄有误,请检查是否为0~120之间
23.5
输入有误,请重新输入:
asd
输入有误,请重新输入:
23 Student{name = zhangsan, age = 23}
总结
异常处理方式1——throws
throws:用在方法上,可以将方法内部出现的异常抛出去给本方法的调用者处理。
这种方式并不好,发生异常的方法自己不处理异常,如果异常最终抛出去给虚拟机将引起程序死亡。
异常处理方式2——try...catch...
监视捕获异常,用在方法内部,可以将方法内部出现的异常直接捕获处理。
这种方式还可以,发生异常的方法自己独立完成异常的处理,程序可以继续往下执行。
异常处理方式3——两者结合
自定义异常的必要?
●Java无法为这个世界上全部的问题提供异常类。
●如果企业想通过异常的方式来管理自己的某个业务问题,就需要自定义异常类了。
自定义异常的好处:
可以使用异常的机制管理业务问题,如提醒程序员注意。
同时一旦出现bug,可以用异常的形式清晰的指出出错的地方。
自定义异常的分类
1、自定义编译时异常
定义一个异常类继承Exception.
重写构造器。
在出现异常的地方用throw new自定义对象抛出
作用:编译时异常是编译阶段就报错,提醒更加强烈,一定需要处理!
2、自定义运行时异常
定义一个异常类继承RuntimeException.
重写构造器。
在出现异常的地方用throw new自定义对象抛出!
作用:提醒不强烈,编译阶段不报错!!运行时才可能出现!!
e.printStackTrace();
展示完整的异常信息,虽然是红色的字体,但是不会影响后续代码的执行!!!