文章目录

  • 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(异常类类型 对象名){处理异常
}

执行结果

  1. 没有异常;
    try执行,catch没有执行
  2. 异常类型匹配,
    try执行,catch也执行
  3. 异常类型不匹配:
    try执行,catch不执行;但是程序会中断;

多重catch

语法

try{可能会出现异常的代码
} catch(异常类类型 对象名){处理异常
} catch(异常类类型 对象名){处理异常
} catch(异常类类型 对象名){处理异常
} ……

catch块中异常类类型的顺序

  1. 有普通 到特殊,
  2. 由子类到父类;
  3. catch块中可以增加return;catch块中可以增加return;来结束当前方法;

try-catch-finally

try{可能会出现异常的代码
} catch(异常类类型 对象名){处理异常
} …… catch(异常类类型 对象名){处理异常
}finally{ //关闭流一定会执行
}

特殊情况

  1. catch块中有returnfinally块也会执行;
  2. catch块中System.exit(0),就退出JVM了,因此就不执行finally块了;

throws

  1. 声明异常,把异常抛给调用者;

  2. 方法头部声明了Excepion,那么就说明方法体中存在 非运行时异常,是必须要处理的;

  3. 方法头部声明了RunTimeException,那么就说明方法体中存在 运行时异常,不是必须处理的;

++问题:什么时候需要throws声明异常++
throws与try-catch是一个级别的;
throws是将异常抛出给调用者,try-cathc是将异常自己处理了;
也就是说当调用了一个声明了异常的方法时,要么使用try捕获异常,要么使用throws抛出异常

throw

  1. 抛异常,
  2. 自己抛异常
  • 如果抛出的异常是 运行时异常(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("黑");}
    }
  1. 作用:手动抛出异常;

自定义异常

自定义异常,一般都是继承自两个类,分别是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中有缓存机制,可能会出现跳过赋值,直接抛出异常的情况;

异常处理原则

  1. 只用于处理非正常的情况
  2. 避免过大的try块
  3. 推荐使用多重catch
  4. 不要忽略catch块中的异常
  5. 改正代码
  6. 文档声明 - 声明了异常的方法要详细的说明异常;

泛型

回顾方法重写

  • 子类中,实例方法,方法名相同,参数列表相同,返回值类型形同

    1. 访问修饰符权限比父类要大
    2. 抛出的异常范围要比父类小
    3. 返回值类型可以是父类返回值类型的子类;
    4. 父类参数擦除后与子类一致;

概念

参数化类型

类型参数

  1. 定义时:形式类型参数
  2. 应用时:实际类型参数(必须是引用类型)

参数化类型

类型<实际类型参数>
合在一起就叫参数化类型;

好处

  1. 在编译器进行类型检查;
  2. 类型不确定。

定义泛型类

语法

Class  类名<类型参数1,类型参数2>{}

参数类型

用一个大写字母表示;

  1. T -> Type
  2. K -> Key
  3. V -> Value
  4. E -> Element

多参数类型

可以定义多个类型参数,用逗号分隔;

原生类型

一个类型的后边没有指定具体的类型参数,这样的泛型类型,称为原生类型

字节码文件对泛型的处理

字节码文件中 擦除泛型类型信息

通配符

  1. ? 无界通配符 匹配任意类型
  2. ? extends 上限类 匹配上限类和上限的子类
  3. ? Super 下限类 匹配下限类和下限类的父类

提问

String类 是 Object类 的子类,Object 对象 = String 对象,自动转型,那么Point和Point有什么关系?
Point<String>不是Point<Object>的子类型;
通过查看字节码文件发现 Point的class文件就一个,因此不存在继承关系;

类型参数与通配符的区别

  1. 类型参数可以表示一种类型,泛型类型;通配符不能表示为一种类型。
  2. 类型参数只能指定上限;通配符能指定上限,和下限;
  3. 类型参数 可以指定多个上限;(能匹配各个上限的任一子类,); 通配符不能指定多个上限;

泛型构造器

类名<对象泛型> 对象名 = 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 异常 泛型相关推荐

  1. Java全栈(二)JavaSE:22.泛型

    1 泛型的概念 1.1 泛型的引入 例如:生产瓶子的厂家,一开始并不知道我们将来会用瓶子装什么,我们什么都可以装,但是有的时候,我们在使用时,想要限定某个瓶子只能用来装什么,这样我们不会装错,而用的时 ...

  2. 【JavaSe】异常

    学习目录 异常 异常的概念 异常的体系结构 异常的分类 编译时异常 运行时异常 异常的处理 事前防御型 事后认错型 异常的捕获 异常捕获 try-catch throw 和 throws 的区别 异常 ...

  3. 【JAVASE】Java泛型实例化

    实例化具有无参数构造函数的泛型对象 //newInstance() method need constructor without parameter //Class<T> come fo ...

  4. 【JavaSE】异常 超详讲解(编程思想)

    希望通过博客和大家相互交流,相互学习,如有错误,请评论区指正 文章目录 一.什么是异常? Java的异常体系 如何排查异常 二. 处理异常 try-catch基本语法 这个时候就要处理异常 如果我们用 ...

  5. 字符串分割 异常 泛型 练习

    package step1; import java.util.List; import java.util.ArrayList; import java.util.Scanner; import j ...

  6. C#笔记09 结构、枚举、异常、泛型、操作符重载、dll、垃圾回收与资源清理、XML注释

    文章目录 结构体struct 枚举enum 异常Exception 执行try最近的最贴切的catch 继承Exception以定义异常 泛型 泛型的约束where 操作符重载 类型转换操作符重载 d ...

  7. Java中的泛型与异常机制

    Java中的泛型与异常机制 ※泛型的使用 如果在使用集合时没有限定集合所保存的数据类型,则在代码运行期间容易会出现ClassCastException类转换的异常 通过设置泛型,可以在编译期间发生问题 ...

  8. java中的泛型是什么_Java中泛型是什么?Java泛型的详细介绍

    本篇文章给大家带来的内容是关于Java中泛型是什么?Java泛型的详细介绍,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 一.什么是泛型? Java泛型设计原则:只要在编译时期没有出 ...

  9. java泛型常用特点_?你必须知道的Java泛型

    前言 文本已收录至我的GitHub仓库,欢迎Star:https://github.com/bin3923282... 种一棵树最好的时间是十年前,其次是现在 我知道很多人不玩qq了,但是怀旧一下,欢 ...

最新文章

  1. php 惩罚,【后端开辟】php能够怎样处置惩罚json串
  2. Messages 贪心,期望,概率,模拟(2000)
  3. SQL日期时间格式自由转换大全
  4. Symbian中不能跨越线程(RThread)使用的对象/组件(RSocket/Memery Heap,etc)
  5. linux的基础知识——信号的概念
  6. 阶段3 3.SpringMVC·_02.参数绑定及自定义类型转换_5 自定义类型转换器演示异常
  7. java考试时间,Java认证考试知识点:Java时间类的函数
  8. 软件测试薪资高不高?软件测试工资水平调研公布
  9. 单页面网站优化技巧有哪些?
  10. 通过js引入本地图片地址
  11. git 删除本地仓库
  12. laravel 5.3 更换语言包
  13. 开源盛世 Linux 资源导航 —★—
  14. 儿童台灯用白炽灯还是led灯好?盘点眼科医生推荐的儿童LED
  15. 【基础算法】铲雪车问题(BZOJ1190)
  16. HTC One z概念手机 键盘侧滑不侧漏
  17. Web时代,电脑用户的求生之路
  18. .easyui(DataGrid数据查询)
  19. icode编程图形化|一级训练场|基础训练1
  20. 读《影响力 Influence:The psychology of Persuasion》-罗伯特.西奥迪尼著(下)

热门文章

  1. 【CSDN下载】第三期:多AGV调度系统软件、基于PCA的人脸识别系统
  2. scala的变长数组
  3. pgsql 筛选中文字符正则_匹配中文字符的正则表达式
  4. S5PV210 PWM定时器
  5. 【疯壳·机器人教程2】人形街舞机器人-机体组装及测试
  6. 基于 MATLAB 的信号发生器设计
  7. Spring-Boot +Neo4j+实现节点的创建和关系的添加【玩转neo4j】
  8. 来看看移动端小程序技术的前世今生!小白也能看明白
  9. 王炸!!Spring 终于对 JVM 动手了…
  10. 最全的TV视频应用合集,包含50多款客户端,有丰富直播点播