一、创建不可变集合
1、不可变集合概述
- 不可变集合,就是不可被修改的集合
- 集合的数据项在创建的时候提供,并且在整个生命周期中都不可以改变,否则报错
2.为什么创建不可变对象
- 如果某个数据不能被修改,把它防御性地拷贝到不可变集合中是个很好的实践
- 或者当集合对象被不可信任的库调用时,不可变形式是安全的
3.如何创建不可变集合
- 在List、Set、Map接口中,都存在of方法,可以创建一个不可变集合
- 这个集合不能添加,不能删除,不能修改
public class CollectionDemo {
public static void main(String[] args) {
//1.不可变的List集合
List<Double> lists=List.of(569.5,700.5,523.0,570.5);
System.out.println(lists);//[569.5, 700.5, 523.0, 570.5]
// lists.add("345.5");不能添加
// lists.set(2,698.5);
//System.out.println(lists);//不能修改
Double d=lists.get(1);
System.out.println(lists);//[569.5, 700.5, 523.0, 570.5]
System.out.println(d);//700.5
//2.不可变Set集合
// Set<String> names=Set.of("小花","小白","小兰","小哈","小白");
// System.out.println(names);//出现异常IllegalArgumentException不能重复
Set<String> names=Set.of("小花","小白","小兰","小哈");
//names.add("小明");
//System.out.println(names);//UnsupportedOperationException不可以添加元素
//3.不可变Map集合
Map<String,Integer> maps=Map.of("huawei",2,"Java开发",1,"手表",1);
System.out.println(maps);//{手表=1, huawei=2, Java开发=1}
maps.put("HTML",12);
System.out.println(maps);//UnsupportedOperationException不能添加元素
}
}
二、Stream流
1.Stream的概述
1.1Stream流的概述
- 在Java中,得益于Lambda所带来的函数式编程,引入了一个全新的Stream流概念
- 目的:用于简化集合和数组操作的API
1.2案例:体验Stream流的作用
public class StreamTest {
public static void main(String[] args) {
//初步体验Stream流的方便与快捷
List<String> names=new ArrayList<>();
Collections.addAll(names,"张小兰","张芳","张小花","小白","小花");
System.out.println(names);
// //1.将姓张的放在新集合
// List<String> zhanglist=new ArrayList<>();
// for(String name:names){
// if(name.startsWith("张")){
// zhanglist.add(name);
// }
// }
// System.out.println(zhanglist);//[张小兰, 张芳, 张小花]
// //2.找名称长度是3的张的姓名
// List<String> zhangThreelist=new ArrayList<>();
// for(String name:names){
// if(name.startsWith("张")&&name.length()==3){
// zhangThreelist.add(name);
// }
// }
// System.out.println(zhangThreelist);//[张小兰, 张芳, 张小花]
//3.使用Stream流实现
names.stream().filter(s->s.startsWith("张")).filter(s->s.length()==3).forEach(s-> System.out.println(s));
//张小兰
//张小花
}
}
1.3Stream流的思想
- 先得到集合或者数组的Stream流(就是一根传送带)
- 把元素放上去
- 然后就用这个Stream流简化的API来方便的操作元素
2.Stream流的获取
1.1Stream流的三类方法
1.1.1获取Stream流
- 创建一条流水线,并把数据放到流水线上准备进行操作
1.1.2中间方法
- 流水线上的操作,一次操作完毕之后,还可以继续进行其它操作
1.1.3终结方法
- 一个Stream流只能有一个终结方法,是流水线上的最后一个操作
1.2集合获取Stream流的方式
- 可以使用Collection接口中默认方法Stream()生成流
default Stream<E> stream()//获取当前集合对象的Stream流
1.3数组获取Stream流的方式
public static <T> Stream<T> stream (T[] array) //|获取当前数组的Stream流
public static<T> Stream<T> of(T...value)//获取当前数组/可变数据的Stream流
public class StreamDemo2 {
public static void main(String[] args) {
/**------------Collection集合获取Stream流---------------*/
Collection<String> list=new ArrayList<>();
Stream<String> s = list.stream();
/**------------Map集合获取流------------------*/
Map<String,Integer> maps=new HashMap<>();
//键流
Stream<String> keyStream=maps.keySet().stream();
//值流
Stream valuesStream= maps.values().stream();
//键值对流
Stream<Map.Entry<String, Integer>> stream = maps.entrySet().stream();
/**-------------数组获取流--------------*/
String[] names={"小花","小红","小包"};
Stream<String> nameStream = Arrays.stream(names);
Stream<String> nameStream2=Stream.of(names);
}
}
3.Stream流的常用API(中间操作方法)
public class StreamDemo3 {
public static void main(String[] args) {
/*
目标:Stream流常用API
forEach:逐一处理(遍历)
count:统计个数
---- long count();
filter :过滤元素
---- Stream<T> filter(Predicate<? super T>predicate)
limit:取前几个元素
skip:跳过前几个
map:加工方法
concat:合并流
distinct:去重复
*/
List<String> list=new ArrayList<>();
list.add("张小花");
list.add("小红");
list.add("张小百");
list.add("张包");
list.add("张小兰");
// list.add("张小兰");
list.add("小花");
//Stream<T> filter(Predicate<? super T> predicate);
// list.stream().filter(new Predicate<String>() {
// @Override
// public boolean test(String s) {
// return s.startsWith("张");
// }
// });
list.stream().filter( s-> s.startsWith("张")).forEach(s-> System.out.println(s));
//张小花
//张小百
//张包
//张小兰
list.stream().filter(s->s.startsWith("张")).filter(s->s.length()==3).forEach(s-> System.out.println(s));
//张小花
//张小百
//张小兰
long size = list.stream().filter(s -> s.length() == 3).count();
System.out.println(size);//3
// list.stream().filter(s->s.startsWith("张")).limit(2).forEach(s-> System.out.println(s));
list.stream().filter(s->s.startsWith("张")).limit(2).forEach(System.out::println);//上行代码的简化
//张小花
//张小百
list.stream().filter(s->s.startsWith("张")).skip(2).forEach(s-> System.out.println(s));
//张包
//张小兰
//Map加工方法
//给集合元素的前面都加上一个:开心的
// list.stream().map(new Function<String, String>() {
// @Override
// public String apply(String s) {
// return "开心的"+s;
// }
// });
//map加工方法:第一个参数原材料,->第二个参数是加工后的结果
list.stream().map(s-> "开心的"+s).forEach(s-> System.out.println(s));
//list.stream().map(Student::new Student).forEach(System.out::println);//上一行代码简化 构造器引用 方法引用
//开心的张小花
//开心的小红
//开心的张小百
//开心的张包
//开心的张小兰
//开心的小花
//需求:把所有的名称都加工成一个学生对象
//1.创建学生类对象
/*
public class Student {
private String name;
public Student() {
}
public Student(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
'}';
}
}
*/
list.stream().map(s->new Student(s)).forEach(s-> System.out.println(s));
//Student{name='张小花'}
//Student{name='小红'}
//Student{name='张小百'}
//Student{name='张包'}
//Student{name='张小兰'}
//Student{name='小花'}
//concat合并流
Stream<String> s1=list.stream().filter(s->s.startsWith("张"));
Stream<String> s2= Stream.of("Java1","Java2");
// public static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b)
Stream<String> s3= Stream.concat(s1,s2);
s3.forEach(s-> System.out.println(s));
//张小花
//张小百
//张包
//张小兰
//Java1
//Java2
// list.stream().distinct().forEach(s-> System.out.println(s));
//张小花
//小红
//张小百
//张包
//张小兰
//小花
}
}
注意:
- 中间方法也称为非终结方法,调用完成后返回新的Stream流可以继续使用,支持链式编程
- 在Stream流中无法直接修改集合,数组中的数据
4.Stream流的综合应用
public class StreamDemo4 {
public static double allMoney;
public static double allMoney2;
public static double allMoney3;
public static void main(String[] args) {
List<Employee> one=new ArrayList<>();
one.add(new Employee("小红",'女',30000,25000,null));
one.add(new Employee("小明",'男',25000,1000,"顶撞上司"));
one.add(new Employee("小蓝",'女',20000,20000,null));
one.add(new Employee("小白",'男',20000,25000,null));
List<Employee> two=new ArrayList<>();
two.add(new Employee("明明",'女',15000,9000,null));
two.add(new Employee("红红",'男',20000,10000,null));
two.add(new Employee("白白",'女',50000,100000,"被打"));
two.add(new Employee("兰兰",'女',3500,1000,"被打"));
two.add(new Employee("天天",'男',20000,0,"打人"));
//1.开发1部门的最高工资的员工
//指定大小规则
// Employee e=one.stream().max(( o1, o2)-> Double.compare(o1.getSalary()+o1.getBonus(),o2.getSalary()+o2.getSalary())).get();
// //Employee{name='小红', sex=女, salary=30000.0, bonus=25000.0, punish='null'}
// System.out.println(e);
Topperformer t = one.stream().max((o1, o2) -> Double.compare(o1.getSalary() + o1.getBonus(), o2.getSalary() + o2.getSalary())).map(e -> new Topperformer(e.getName(), e.getBonus() + e.getSalary())).get();
System.out.println(t);
//Topperformer{name='小红', money=55000.0}
//2.开发2部门的最高工资的员工
Topperformer t2=two.stream().max((o1, o2) -> Double.compare(o1.getSalary() + o1.getBonus(), o2.getSalary() + o2.getSalary())).map(e -> new Topperformer(e.getName(), e.getBonus() + e.getSalary())).get();
System.out.println(t2);
//Topperformer{name='白白', money=150000.0}
//3.分别统计两个部门的平均工资,去掉最高工资和最低工资
// one.stream().sorted(new Comparator<Employee>() {
// @Override
// public int compare(Employee o1, Employee o2) {
// return Double.compare(o1.getSalary()+o1.getBonus(),o2.getSalary()+o2.getBonus());
// }
// });
one.stream().sorted(( o1, o2)-> Double.compare(o1.getSalary()+o1.getBonus(),o2.getSalary()+o2.getBonus())).skip(1).limit(one.size()-2).forEach(s-> {
//求出总和:剩余员工的工资总和
allMoney+=(s.getBonus()+s.getSalary());
});
//开发一部的平均工资是多少
System.out.println("开发一部的平均工资是:"+allMoney/(one.size()-2));//开发一部的平均工资是:42500.0
开发一部的平均工资是:42500.0
two.stream().sorted((o1,o2)->Double.compare(o1.getSalary()+o1.getBonus(),o2.getSalary()+o2.getBonus())).skip(1).limit(two.size()-3).forEach(s->{
//求出总和,剩余员工的工资总和
allMoney2+=(s.getBonus()+s.getSalary());
});
System.out.println("开发二部的平均工资是:"+allMoney2/(one.size()-3));
//开发二部的平均工资是:44000.0
//4.合并两个流集合,再统计
Stream<Employee> s1=one.stream();
Stream<Employee> s2=two.stream();
Stream<Employee> s3 = Stream.concat(s1, s2);
s3.sorted(( o1, o2) -> Double.compare(o1.getSalary()+o1.getBonus(),o2.getSalary()+o2.getBonus())).skip(1).limit((one.size()+two.size())-2).forEach(s->{
allMoney3+=s.getBonus()+s.getSalary();
});
//BigDecimal
BigDecimal a=BigDecimal.valueOf(allMoney3);
BigDecimal b=BigDecimal.valueOf((one.size()+two.size())-2);
System.out.println("开发部的平均工资为:"+a.divide(b,2, RoundingMode.HALF_UP));
//开发部的平均工资为:34285.71
}
}
5.收集Stream流
5.1Stream流的收集操作
- 收集
- Stream流的含义:把Stream流操作后的结果数据转回到集合或者数组中去
- Stream流:方便操作集合/数组的手段
- 集合/数组:才是开发中的目的
5.2Stream流的收集方法
public class StreamDemo5 {
/**
* 目标:收集Stream流的数据到集合或者数组中去
*/
public static void main(String[] args) {
List<String> list=new ArrayList<>();
list.add("张小花");
list.add("小红");
list.add("张小百");
list.add("张包");
list.add("张小兰");
list.add("小花");
Stream<String> stream =list.stream().filter(s->s.startsWith("张"));
//List<String> zhangLists=stream.collect(Collectors.toList());
List<String> zhangLists=stream.toList();//得到不可变集合
System.out.println(zhangLists);//[张小花, 张小百, 张包, 张小兰]
//注意:流只能使用一次
Stream<String> stream2 =list.stream().filter(s->s.startsWith("张"));
Set<String> zhangSets=stream2.collect(Collectors.toSet());
System.out.println(zhangSets);//[张小兰, 张小花, 张包, 张小百]
Stream<String> stream3 =list.stream().filter(s->s.startsWith("张"));
// Object[] s = stream3.toArray();
// String[] s = stream3.toArray(new IntFunction<String[]>() {
// @Override
// public String[] apply(int value) {
// return new String[value];
// }
// });
String[] s = stream3.toArray(value->new String[value]);
System.out.println("数组内容:"+Arrays.toString(s));//数组内容:[张小花, 张小百, 张包, 张小兰]
}
}
三、异常处理
1.异常概述、体系
1.1异常的概述
- 异常是程序在“编译”或者“执行”过程中可能出现的问题,注意:语法错误不算在异常体系中
- 异常一旦出现,如果没有提前处理,程序就会退出JVM虚拟机而终止
- 研究异常并且避免异常,然后提前处理异常,体现的是程序的安全、健壮性
1.2异常体系
1.2编译时异常和运行时异常
2.常见运行时异常
2.1运行时异常
- 直接继承RuntimeException或者其子类,编译阶段不会报错,运行时可能出现错误
2.2运行时异常示例
- 数组索引越界异常ArrayIndexOutOfBoundsException
- 空指针异常NullPointerException
- 数字操作异常ArithmeticException
- 类型转换异常ClassCastException
- 数字转换异常NumberFormatException
public class ExceptionDemo {
public static void main(String[] args) {
System.out.println("程序开始。。。。。。。。。。。。。");
//1.数组索引越界异常ArrayIndexOutOfBoundsException
int[] arr={1,2,3};
System.out.println(arr[2]);
// System.out.println(arr[3]);//运行出错,程序终止ArrayIndexOutOfBoundsException
//2. 空指针异常NullPointerException
String name=null;
System.out.println(name);
// System.out.println(name.length());//运行出错,程序终止NullPointerException
//3.类型转换异常
Object o=23;
//String s=(String)o;//ClassCastException
//4.数字操作异常ArithmeticException
// int c=10/0;//ArithmeticException
//5.数字转换异常NumberFormatException
// String number="23";
// Integer it=Integer.valueOf(number);
// System.out.println(it+1);//24
String number="23aabb";
Integer it=Integer.valueOf(number);//NumberFormatException
}
}
3.常见编译时异常
3.1编译时异常
- 不是RuntimeException或者其子类的异常,编译阶段就报错,必须处理,否则代码不通过
3.2编译时异常案例
- 日期解析日常:ParseException
public class ExceptionDemo {
public static void main(String[] args) throws ParseException {
String date = "2015-01-12 10:23:21";
//创建一个简单日期格式化类:解析字符串时间成为日期对象
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date d=sdf.parse(date);//ParseException
System.out.println(d);
}
}
3.3编译时异常的作用
- 担心程序员的技术不行,在编译阶段就报出一个错误,目的在于提醒不要出错!
4.异常的默认处理流程
public class ExceptionDemo {
public static void main(String[] args) {
System.out.println("程序开始");
chu(10,0);
//程序开始
//10
//0
//Exception in thread "main" java.lang.ArithmeticException: / by zero
// at com.itheima.d6_exception_default.ExceptionDemo.chu(ExceptionDemo.java:12)
// at com.itheima.d6_exception_default.ExceptionDemo.main(ExceptionDemo.java:6)
System.out.println("程序结束");
}
public static void chu(int a,int b){
System.out.println(a);
System.out.println(b);
int c=a/b;
System.out.println(c);
}
}
- 默认异常处理机制并不好,一旦真的出现异常,程序立即死亡
5.编译时异常的处理机制
5.1编译型异常得处理形式有三种:
- 出现异常直接抛给调用者,调用者也可以继续抛出去
- 出现异常自己捕获,不麻烦别人
- 前两者的结合,出现异常直接抛出去给调用者,调用者捕获处理
5.2异常处理方式1:throws
- throws:用在方法上,可以将方法内部出现的异常抛出去给本方法的调用者处理
- 这种方法并不好,发生异常的方法自己不处理异常,如果异常最终抛出去给虚拟机将引起程序死亡
//抛出异常格式:
方法 throws 异常1,异常2,异常3..{
}
public class ExceptionDemo01 {
public static void main(String[] args) throws ParseException, FileNotFoundException {
System.out.println("程序开始");
parseTime("2011-11-11 11:11:11");
System.out.println("程序结束");
}
public static void parseTime(String date) throws ParseException, FileNotFoundException {
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date d=sdf.parse(date);
System.out.println(d);
InputStream is=new FileInputStream("C:/mei.jpg");
}
}
//规范做法
方法 throws Exception{
}
public class ExceptionDemo01 {
public static void main(String[] args) throws Exception {
System.out.println("程序开始");
parseTime("2011-11-11 11:11:11");
System.out.println("程序结束");
}
public static void parseTime(String date) throws Exception {
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date d=sdf.parse(date);
System.out.println(d);
InputStream is=new FileInputStream("C:/mei.jpg");
}
}
5.3异常处理方式2:try…catch…
- 监视捕获异常,用在方法内部,可以将饭不够发内部出现的异常直接捕获处理
- 这种方法还可以,发生异常的方法自己独立完成异常的处理,程序可以继续往下执行
//格式
try{
//监视可能出现异常的代码
}catch(异常类型1 变量1){
//处理异常
}catch(异常类型2 变量2){
//处理异常
}
public class ExceptionDemo02 {
public static void main(String[] args) {
System.out.println("程序开始");
parseTime("2011-11-11 11:11:11");
System.out.println("程序结束");
//程序开始
//Fri Nov 11 11:11:11 CST 2011
//你的文件不存在
//程序结束
}
public static void parseTime(String date) {
try {
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date d=sdf.parse(date);
System.out.println(d);
} catch (ParseException e) {
//解析出现的问题
System.out.println("出现了解析时间异常哦,走点心");
}
try {
InputStream is=new FileInputStream("C:/mei.jpg");
} catch (FileNotFoundException e) {
System.out.println("你的文件不存在");
}
}
}
public class ExceptionDemo02 {
public static void main(String[] args) {
System.out.println("程序开始");
parseTime("2011-11-11 11:11:11");
System.out.println("程序结束");
// 程序开始
// java.text.ParseException: Unparseable date: "2011-11-11 11:11:11"
// at java.base/java.text.DateFormat.parse(DateFormat.java:399)
// at com.itheima.d7_exception_handle.ExceptionDemo02.parseTime(ExceptionDemo02.java:21)
// at com.itheima.d7_exception_handle.ExceptionDemo02.main(ExceptionDemo02.java:12)
// 程序结束
}
public static void parseTime(String date) {
try {
SimpleDateFormat sdf=new SimpleDateFormat("yyyy、-MM-dd HH:mm:ss");
Date d=sdf.parse(date);
System.out.println(d);
InputStream is=new FileInputStream("C:/mei.jpg");
} catch (ParseException e) {
//解析出现的问题
e.printStackTrace();//打印异常栈信息
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
//官方建议:
public class ExceptionDemo02 {
public static void main(String[] args) {
System.out.println("程序开始");
parseTime("2011-11-11 11:11:11");
System.out.println("程序结束");
// 程序开始
// java.text.ParseException: Unparseable date: "2011-11-11 11:11:11"
// at java.base/java.text.DateFormat.parse(DateFormat.java:399)
// at com.itheima.d7_exception_handle.ExceptionDemo02.parseTime(ExceptionDemo02.java:21)
// at com.itheima.d7_exception_handle.ExceptionDemo02.main(ExceptionDemo02.java:12)
// 程序结束
}
public static void parseTime(String date) {
try {
SimpleDateFormat sdf=new SimpleDateFormat("yyyy、-MM-dd HH:mm:ss");
Date d=sdf.parse(date);
System.out.println(d);
InputStream is=new FileInputStream("C:/mei.jpg");
} catch (Exception e) {
//解析出现的问题
e.printStackTrace();//打印异常栈信息
}
}
}
5.4异常处理方式3:前两者结合
- 方法直接将异常通过throws抛出去给调用者
- 调用者收到异常后直接捕获处理
public class ExceptionDemo03 {
public static void main(String[] args) {
System.out.println("程序开始");
try {
parseTime("2011-11-11 11:11:11");
System.out.println("功能操作成功");
} catch (Exception e) {
e.printStackTrace();
System.out.println("操作失败");
}
System.out.println("程序结束");
}
public static void parseTime(String date) throws Exception {
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date d=sdf.parse(date);
System.out.println(d);
InputStream is=new FileInputStream("C:/mei.jpg");
}
}
6.运行时异常的处理机制
- 运行时异常编译阶段不会出错,是运行时才会出错,所以编译阶段不处理也可以
- 按照规范建议还是处理:建议在最外层调用处理集中捕获处理即可
//目标:运行时异常的处理机制
//可以不处理编译阶段不会报错
//按照理论规则:建议还是处理,只需要在最外层捕获处理
public class Test {
public static void main(String[] args) {
System.out.println("程序开始");
try {
chu(10,0);
} catch (Exception e) {
e.printStackTrace();
}
}
//程序开始
//10
//0
//java.lang.ArithmeticException: / by zero
// at com.itheima.d8_exception_handle_runtime.Test.chu(Test.java:17)
// at com.itheima.d8_exception_handle_runtime.Test.main(Test.java:9)
public static void chu(int a,int b){//throws RunException
System.out.println(a);
System.out.println(b);
int c=a/b;
System.out.println(c);
}
}
7.异常处理使代码更稳健的案例
需求
- 键盘录入一个合理的几个为止(必须是数值,值必须大于0)
分析
- 定义一个死循环,让用户不断地输入价格
public class Test2 {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
while(true){
try {
System.out.println("请您输入合法的价格:");
//请您输入合法的价格:
//345jjj
//请您输入合法的数值,建议为正数
//请您输入合法的价格:
//45
//定价:45
String priceStr=sc.nextLine();
//转换为Double类型的数据
double price=Double.valueOf(priceStr);
if(price>0){
System.out.println("定价:"+priceStr);
break;
}else{
System.out.println("价格必须是正数");
}
} catch (NumberFormatException e) {
System.out.println("请您输入合法的数值,建议为正数");
}
}
}
}
8.自定义异常
8.1自定义异常的必要
- java无法为全部问题提供异常类
- 如果企业想通过异常的方式来管理自己的某个业务,就需要自定义异常类
8.2自定义异常的好处
- 可以使用异常机制管理业务问题,如提醒程序员注意
- 同时一旦出现bug,可以用异常的形式清晰的指出出错的地方
8.3自定义异常的分类
1.自定义编译异常
- 定义一个异常类继承Exception
- 重写构造器
- 在出现异常的地方用throw new自定义对象抛出
/**
* 自定义编译异常
* 1.继承Exception
* 2.重写构造器
*/
public class ItheimaAgeIlleagalException extends Exception{
public ItheimaAgeIlleagalException() {
}
public ItheimaAgeIlleagalException(String message) {
super(message);
}
}
public class ExceptionDemo {
public static void main(String[] args) {
try {
checkAge(34);
} catch (ItheimaAgeIlleagalException e) {
e.printStackTrace();
}
}
public static void checkAge(int age) throws ItheimaAgeIlleagalException {
if(age<0||age>200){
//抛出一个异常对象给调用者
//throw:在方法内部直接创建一个异常对象,并从此点抛出
//throws:用在方法声明上面,抛出方法内部的异常
throw new ItheimaAgeIlleagalException(age + "is illeagal");
}else{
System.out.println("年龄合法:推荐商品给其购买");
}
}
}
- 作用:编译时异常是编译阶段就报错,提醒更加强烈,一定需要处理
2.自定义运行异常
- 定义一个异常类继承RunException
- 重写构造器
- 在出现异常的地方用throw new自定义对象抛出
作用:提醒不强烈,编译阶段不报错,运行时才可能出现
/**
* 自定义编译时异常
* 1.继承RunException
* 2.重写构造器
*/
public class ItheimaIlleagalRunException extends RuntimeException{
public ItheimaIlleagalRunException() {
}
public ItheimaIlleagalRunException(String message) {
super(message);
}
}
public class ExceptionDemo {
public static void main(String[] args) {
// try {
// checkAge(34);
// } catch (ItheimaAgeIlleagalException e) {
// e.printStackTrace();
// }
try {
checkAge2(-34);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void checkAge2(int age) {
if(age<0||age>200){
//抛出一个异常对象给调用者
//throw:在方法内部直接创建一个异常对象,并从此点抛出
//throws:用在方法声明上面,抛出方法内部的异常
throw new ItheimaIlleagalRunException(age + "is illeagal");
}else{
System.out.println("年龄合法:推荐商品给其购买");
}
}
public static void checkAge(int age) throws ItheimaAgeIlleagalException {
if(age<0||age>200){
//抛出一个异常对象给调用者
//throw:在方法内部直接创建一个异常对象,并从此点抛出
//throws:用在方法声明上面,抛出方法内部的异常
throw new ItheimaAgeIlleagalException(age + "is illeagal");
}else{
System.out.println("年龄合法:推荐商品给其购买");
}
}
}