JavaSE Day14 异常 泛型
文章目录
- Lambda表达式调用Arrays类中的方法
- parallelSetAll()
- parallelPrefix()
- Stream()
- Lambda练习
- 异常处理
- 异常的分类
- Error 异常
- Exception异常
- 运行时异常
- 非运行时异常
- 常见的异常
- 异常的处理方式
- try-catch
- 语法:
- 执行结果
- 多重catch
- 语法
- catch块中异常类类型的顺序
- try-catch-finally
- 特殊情况
- throws
- throw
- 自定义异常
- 自定义 运行时异常
- 自定义 非运行时异常
- 总结
- throw和throws的区别
- 关于循环中Scanner重复输入的问题
- 异常处理原则
- 泛型
- 回顾方法重写
- 概念
- 类型参数
- 参数化类型
- 好处
- 定义泛型类
- 语法
- 参数类型
- 多参数类型
- 原生类型
- 字节码文件对泛型的处理
- 通配符
- 提问
- 类型参数与通配符的区别
- 泛型构造器
- 泛型方法
- 擦除的原则
- 对于参数化类型,
- 对于类型参数
- 无界类型参数,擦除后为Object;
- 有一个上限的类型参数,用上限类型替换;
- 有多个上限的类型参数,用第一个上限来替换;
- 泛型重载和重写
Lambda表达式调用Arrays类中的方法
parallelSetAll()
package day14;import java.util.Arrays;
import java.util.function.IntUnaryOperator;public class TestLambda2 {public static void main(String[] args) {int[] arr = {1, 2, 3, 4, 5};// 一元运算,用运算的结果来替换数组中的所有元素Arrays.parallelSetAll(arr, new IntUnaryOperator() {@Override // 数组的索引,public int applyAsInt(int operand) {return operand + 1;}});Arrays.parallelSetAll(arr, index -> {return index+1;});System.out.println(Arrays.toString(arr));}
}
parallelPrefix()
package day14;import java.util.Arrays;
import java.util.function.IntBinaryOperator;public class TestLambda2 {public static void main(String[] args) {int[] arr = {1, 2, 3, 4, 5};// 二元运算,用于运算的结果,来替换数组中的所有元素Arrays.parallelPrefix(arr, new IntBinaryOperator() {@Override // left:前一个元素,right当前元素,当前元素是数组中第一个元素,前一个元素是1;public int applyAsInt(int left, int right) {return left * right;}});// 当前元素 和 替换后的元素进行计算,得出的结果在赋值给当前元素的位置;System.out.println(Arrays.toString(arr));Arrays.parallelPrefix(arr,((left, right) -> {return left* right;}));System.out.println(Arrays.toString(arr));}
}
Stream()
package day14;import java.util.Arrays;
import java.util.function.IntConsumer;public class TestLambda2 {public static void main(String[] args) {int[] arr = {1, 2, 3, 4, 5};// StreamArrays.stream(arr).forEach(new IntConsumer() {@Override // value 数组中的每个元素public void accept(int value) {System.out.println(value);}});// LambdaArrays.stream(arr).forEach(value -> System.out.println(value));// 方法引用Arrays.stream(arr).forEach(System.out::println);}
}
Lambda练习
package day14;abstract class Animal{public abstract void breed();
}@FunctionalInterface
interface Fly{void fly();
}@FunctionalInterface
interface Talk{void talk();
}class WileGoose extends Animal{@Overridepublic void breed() {System.out.println("大雁能繁殖");}Fly fly = () -> System.out.println("大雁能飞");/*public void fly(Fly fly){fly.fly();}*/
}class Duck extends Animal{@Overridepublic void breed() {System.out.println("鸭子能繁殖");}public void swimming(){System.out.println("鸭子会游泳");}
}class DonaldDuck extends Duck{// 直接在属性中设置Lambda,Talk talk = ()-> System.out.println("唐老鸭能说话");// 需要在主函数设置;不推荐;public void speak(Talk talk){talk.talk();}
}public class TestLamabda3 {public static void main(String[] args) {DonaldDuck donaldDuck = new DonaldDuck();donaldDuck.talk.talk();WileGoose wileGoose = new WileGoose();wileGoose.fly.fly();}
}
异常处理
一般都是为了处理非正常的情况,改变程序的执行流程。
异常的分类
异常分类图
Error 异常
Error异常都是用代码处理不了的
Exception异常
用代码可以处理的异常;
Exception类的包含了运行时异常和非运行时异常;
运行时异常
RunTimeException类和它的子类;
编译可以通过,但是在运行期出现的问题;使程序中断了;
非运行时异常
Exception自身 和 它的部分子类(因为包含了RunTimeException)
编译时出现问题
是必须要处理的异常。
常见的异常
package day14;import java.lang.reflect.Field;
import java.util.Scanner;
class A{private int x;}
public class TestException1 {public static void main(String[] args) throws Exception {//空指针 java.lang.NullPointerExceptionString s = " ";System.out.println(s.equalsIgnoreCase("abc"));// java.util.InputMismatchExceptionScanner input = new Scanner(System.in);int n = input.nextInt();// 类型转换java.lang.ClassCastException/* Object obj = new String();String s1 = (String)obj;Integer n1 = (Integer)obj;*/// 数字格式化 java.lang.NumberFormatExceptionString s2 = "12a";//int n3 = Integer.valueOf(s2);// 不能加载类 java.lang.ClassNotFoundException// ClassLoader.getSystemClassLoader().loadClass("day14.TestException");// 访问x:到字节码文件中Class c = A.class;Field f = c.getDeclaredField("x");f.setAccessible(true);//需要授权,否则报错Object o = c.newInstance();//java.lang.IllegalAccessException 参数异常f.set(o,22);System.out.println(f.get(o));}}
异常的处理方式
try-catch
语法:
try{可能会出现异常的代码
} catch(异常类类型 对象名){处理异常
}
执行结果
- 没有异常;
try执行,catch没有执行 - 异常类型匹配,
try执行,catch也执行 - 异常类型不匹配:
try执行,catch不执行;但是程序会中断;
多重catch
语法
try{可能会出现异常的代码
} catch(异常类类型 对象名){处理异常
} catch(异常类类型 对象名){处理异常
} catch(异常类类型 对象名){处理异常
} ……
catch块中异常类类型的顺序
- 有普通 到特殊,
- 由子类到父类;
- catch块中可以增加return;catch块中可以增加return;来结束当前方法;
try-catch-finally
try{可能会出现异常的代码
} catch(异常类类型 对象名){处理异常
} …… catch(异常类类型 对象名){处理异常
}finally{ //关闭流一定会执行
}
特殊情况
- catch块中有
return
,finally
块也会执行; - catch块中System.exit(0),就退出JVM了,因此就不执行finally块了;
throws
声明异常,把异常抛给调用者;
方法头部声明了Excepion,那么就说明方法体中存在 非运行时异常,是必须要处理的;
方法头部声明了RunTimeException,那么就说明方法体中存在 运行时异常,不是必须处理的;
++问题:什么时候需要throws声明异常++
throws与try-catch是一个级别的;
throws是将异常抛出给调用者,try-cathc是将异常自己处理了;
也就是说当调用了一个声明了异常的方法时,要么使用try捕获异常,要么使用throws抛出异常
throw
- 抛异常,
- 自己抛异常
- 如果抛出的异常是 运行时异常(RunTimeException),在方法头部不用throws声明Exception
package homework02;/*** 自定义颜色异常,继承自RunTimeException*/
class ColorException extends RuntimeException{private String emessage;ColorException(String emessage){super();this.emessage = emessage;}@Overridepublic String toString() {return this.emessage;}
}/*** 猫类*/
class Cat{/*** 颜色*/private String color;public String getColor() {return color;}/*** 如果颜色不是红,黄,蓝,就抛出异常* @param color*/public void setColor(String color) {if("红".equals(color) || "黄".equals(color) || "蓝".equals(color)) {this.color = color;}else{throw new ColorException("颜色只能是红、黄、蓝");}}
}
public class TestException {public static void main(String[] args) {Cat cat = new Cat();cat.setColor("红");cat.setColor("黑");}
}
如果抛出的异常是 非运行时异常,那么就需要使用throws在方法头部声明Exception;
package homework02;/*** 自定义颜色异常,继承自Exception*/ class ColorException extends Exception{private String emessage;ColorException(String emessage){super();this.emessage = emessage;}@Overridepublic String toString() {return this.emessage;} }/*** 猫类*/ class Cat{/*** 颜色*/private String color;public String getColor() {return color;}/*** 如果颜色不是红,黄,蓝,就抛出异常* @param color*/public void setColor(String color) throws Exception {if("红".equals(color) || "黄".equals(color) || "蓝".equals(color)) {this.color = color;}else{throw new ColorException("颜色只能是红、黄、蓝");}} } public class TestException {public static void main(String[] args) throws Exception{Cat cat = new Cat();cat.setColor("红");cat.setColor("黑");} }
- 作用:手动抛出异常;
自定义异常
自定义异常,一般都是继承自两个类,分别是RunTimeException(运行时异常)和 Exception(非运行时异常);
当自定义异常继承自 Excetpion时,手动抛出异常的方法的头部必须 声明异常(throws Exception),
- 并且如果在调用时使用try-catch捕获异常,那么最后必须有一个catch (Exception e)的catch语句;
- 如果不捕获异常,那么需要在主方法的头部,声明异常(throws Exception);
当自定义异常继承自 RunTimeExcetpion时,手动抛出异常的方法的头部不需要 声明异常(throws),
- 在使用try-catch捕获异常时,也不需要catch (Exception e)语句。
- 如果不捕获异常,那么需要在主方法的头部,也不需要声明异常;
自定义 运行时异常
package homework01;import java.util.Scanner;/*** 自定义分数异常类,继承自RunTimeException,*/
class ScoreException extends RuntimeException{/*** 分数错误时的信息*/private String smessing;public ScoreException(String smessing) {super();this.smessing = smessing;}@Overridepublic String getMessage() {return this.smessing;}
}/*** 学生类*/
class Student {private int Score;public int getScore() {return Score;}/*** 当分数不在 0~100之间时,抛出分数异常,* @param score 分数*/public void setScore(int score) {if (score >=0 && score <=100) {Score = score;}else{throw new ScoreException("分数必须在0-100之间");}}
}public class TestStudent{public static void main(String[] args) {Student s1 = new Student();Scanner input = new Scanner(System.in);/*** 当分数不在1~100范围时,需要重新输入;*/while(true) {try {System.out.println("请输入成绩:");s1.setScore(input.nextInt());break;} catch (ScoreException e) {System.out.println(e.getMessage());// 由于Scanner里面有缓存,无法将错误的值赋值给变量。因此需要清空缓存,重新创建一个Scanner类;input = new Scanner(System.in);} }System.out.println("设置成功。。。");}
}
自定义 非运行时异常
package homework01;import java.util.Scanner;/*** 自定义分数异常类,继承自Exception,*/
class ScoreException extends Exception{/*** 分数错误时的信息*/private String smessing;public ScoreException(String smessing) {super();this.smessing = smessing;}@Overridepublic String getMessage() {return this.smessing;}
}/*** 学生类*/
class Student {private int Score;public int getScore() {return Score;}/*** 当分数不在 0~100之间时,抛出分数异常,* @param score 分数*/public void setScore(int score) throws Exception{if (score >=0 && score <=100) {Score = score;}else{throw new ScoreException("分数必须在0-100之间");}}
}public class TestStudent{public static void main(String[] args) {Student s1 = new Student();Scanner input = new Scanner(System.in);/*** 当分数不在1~100范围时,需要重新输入;*/while(true) {try {System.out.println("请输入成绩:");s1.setScore(input.nextInt());break;} catch (ScoreException e) {System.out.println(e.getMessage());} catch (Exception e){System.out.println("未知错误");}}System.out.println("设置成功。。。");}
}
总结
throw和throws的区别
- throw
在代码块中执行,主要是手工进行异常类的抛出 - throws
在方法定义上使用,表示此方法可能产生的异常明确告诉给调用处,有调用处进行处理;
关于循环中Scanner重复输入的问题
Scanner 类的input方法在try语句中时,如果需要在catch语句中重新赋值,那么就需要在catch中重新创建一个Scanner的对象,否则Scanner中有缓存机制,可能会出现跳过赋值,直接抛出异常的情况;
异常处理原则
- 只用于处理非正常的情况
- 避免过大的try块
- 推荐使用多重catch
- 不要忽略catch块中的异常
- 改正代码
- 文档声明 - 声明了异常的方法要详细的说明异常;
泛型
回顾方法重写
- 子类中,实例方法,方法名相同,参数列表相同,返回值类型形同
- 访问修饰符权限比父类要大
- 抛出的异常范围要比父类小
- 返回值类型可以是父类返回值类型的子类;
- 父类参数擦除后与子类一致;
概念
参数化类型
类型参数
- 定义时:形式类型参数
- 应用时:实际类型参数(必须是引用类型)
参数化类型
类型<实际类型参数>
合在一起就叫参数化类型;
好处
- 在编译器进行类型检查;
- 类型不确定。
定义泛型类
语法
Class 类名<类型参数1,类型参数2>{}
参数类型
用一个大写字母表示;
- T -> Type
- K -> Key
- V -> Value
- E -> Element
多参数类型
可以定义多个类型参数,用逗号分隔;
原生类型
一个类型的后边没有指定具体的类型参数,这样的泛型类型,称为原生类型
字节码文件对泛型的处理
字节码文件中 擦除泛型类型信息
通配符
- ? 无界通配符 匹配任意类型
- ? extends 上限类 匹配上限类和上限的子类
- ? Super 下限类 匹配下限类和下限类的父类
提问
String类 是 Object类 的子类,Object 对象 = String 对象,自动转型,那么Point和Point有什么关系?
Point<String>
不是Point<Object>
的子类型;
通过查看字节码文件发现 Point的class文件就一个,因此不存在继承关系;
类型参数与通配符的区别
- 类型参数可以表示一种类型,泛型类型;通配符不能表示为一种类型。
- 类型参数只能指定上限;通配符能指定上限,和下限;
- 类型参数 可以指定多个上限;(能匹配各个上限的任一子类,); 通配符不能指定多个上限;
泛型构造器
类名<对象泛型> 对象名 = new <构造器泛型>类名<对象泛型>();
package day14;class Point2<T> {private T x;private T y;// 泛型构造器的定义public <E> Point2(E e) {System.out.println(e);}public T getX() {return x;}public void setX(T x) {this.x = x;}public T getY() {return y;}public void setY(T y) {this.y = y;}
}public class TestPoint3 {public static void main(String[] args) {// 自动类型推断: 用参数的类型 自动推断出构造器的类型Point2<String> p = new Point2<>(11);//构造器的类型如果是显示指定,那么对象的类型也要用显示指定的 格式 new <构造器泛型>类名<对象泛型>();Point2<String> p1 = new <Integer>Point2<String>(11);}
}
泛型方法
package day14;class Demo{// 泛型方法public <T> void f(T t){System.out.println(t);}public <T> T ff(T t){// 类型推断f(22);// 调用方法// 显示指定,必须使用对象调用this.<Double>f(22.2);return t;}
}
public class TestPoint4 {public static void main(String[] args) {Demo demo = new Demo();// 类型推断demo.f("hello");demo.f(123);//显示指定方法类型demo.<Double>f(22.2);}
}
擦除的原则
对于参数化类型,
擦除之后为 原生类型
Point3<String> p; -> point3 p
对于类型参数
无界类型参数,擦除后为Object;
Class Point<T>{T x;} -> class Point<Object>{Object x;}
有一个上限的类型参数,用上限类型替换;
<T extends A> -> A
有多个上限的类型参数,用第一个上限来替换;
<T extends A && B> --> A
泛型重载和重写
package day14;
// 泛型类
class Point3<T>{private T x;private T y;public T getX() {return x;}public void setX(T x) {this.x = x;}public T getY() {return y;}public void setY(T y) {this.y = y;}
}
class Demo2{}
interface IX{}
interface IY{}
class Demo1{// public void f(Object t){}public <T> void f(T t){}// 是否能重载:擦除后就一样了;
// public void f(Point3<String> p){ }public void f(Point3<Integer> p){}// Demo2public <T extends Demo2> void f(T t){}// IXpublic <T extends IX & IY> void f(T t){}// IY
// public <T extends IY & IX> void f(T t){}
}
class Parent1{// f(Point3 p)public void f(Point3<String> p){}}
class Child2 extends Parent1{@Overridepublic void f(Point3 p) {}
}
public class TestPoint5 {public static void main(String[] args) {}
}
JavaSE Day14 异常 泛型相关推荐
- Java全栈(二)JavaSE:22.泛型
1 泛型的概念 1.1 泛型的引入 例如:生产瓶子的厂家,一开始并不知道我们将来会用瓶子装什么,我们什么都可以装,但是有的时候,我们在使用时,想要限定某个瓶子只能用来装什么,这样我们不会装错,而用的时 ...
- 【JavaSe】异常
学习目录 异常 异常的概念 异常的体系结构 异常的分类 编译时异常 运行时异常 异常的处理 事前防御型 事后认错型 异常的捕获 异常捕获 try-catch throw 和 throws 的区别 异常 ...
- 【JAVASE】Java泛型实例化
实例化具有无参数构造函数的泛型对象 //newInstance() method need constructor without parameter //Class<T> come fo ...
- 【JavaSE】异常 超详讲解(编程思想)
希望通过博客和大家相互交流,相互学习,如有错误,请评论区指正 文章目录 一.什么是异常? Java的异常体系 如何排查异常 二. 处理异常 try-catch基本语法 这个时候就要处理异常 如果我们用 ...
- 字符串分割 异常 泛型 练习
package step1; import java.util.List; import java.util.ArrayList; import java.util.Scanner; import j ...
- C#笔记09 结构、枚举、异常、泛型、操作符重载、dll、垃圾回收与资源清理、XML注释
文章目录 结构体struct 枚举enum 异常Exception 执行try最近的最贴切的catch 继承Exception以定义异常 泛型 泛型的约束where 操作符重载 类型转换操作符重载 d ...
- Java中的泛型与异常机制
Java中的泛型与异常机制 ※泛型的使用 如果在使用集合时没有限定集合所保存的数据类型,则在代码运行期间容易会出现ClassCastException类转换的异常 通过设置泛型,可以在编译期间发生问题 ...
- java中的泛型是什么_Java中泛型是什么?Java泛型的详细介绍
本篇文章给大家带来的内容是关于Java中泛型是什么?Java泛型的详细介绍,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 一.什么是泛型? Java泛型设计原则:只要在编译时期没有出 ...
- java泛型常用特点_?你必须知道的Java泛型
前言 文本已收录至我的GitHub仓库,欢迎Star:https://github.com/bin3923282... 种一棵树最好的时间是十年前,其次是现在 我知道很多人不玩qq了,但是怀旧一下,欢 ...
最新文章
- php 惩罚,【后端开辟】php能够怎样处置惩罚json串
- Messages 贪心,期望,概率,模拟(2000)
- SQL日期时间格式自由转换大全
- Symbian中不能跨越线程(RThread)使用的对象/组件(RSocket/Memery Heap,etc)
- linux的基础知识——信号的概念
- 阶段3 3.SpringMVC·_02.参数绑定及自定义类型转换_5 自定义类型转换器演示异常
- java考试时间,Java认证考试知识点:Java时间类的函数
- 软件测试薪资高不高?软件测试工资水平调研公布
- 单页面网站优化技巧有哪些?
- 通过js引入本地图片地址
- git 删除本地仓库
- laravel 5.3 更换语言包
- 开源盛世 Linux 资源导航 —★—
- 儿童台灯用白炽灯还是led灯好?盘点眼科医生推荐的儿童LED
- 【基础算法】铲雪车问题(BZOJ1190)
- HTC One z概念手机 键盘侧滑不侧漏
- Web时代,电脑用户的求生之路
- .easyui(DataGrid数据查询)
- icode编程图形化|一级训练场|基础训练1
- 读《影响力 Influence:The psychology of Persuasion》-罗伯特.西奥迪尼著(下)