异常
-
定义:程序中出现的不正常的情况
-
异常的由来:程序在运行时出现了不正常的情况,java提取了对应的属性,名字,原因等,形成了异常对象,进而形成了各种异常类、
-
异常的分类(throwable):
1.error:运行中出现的严重错误,不需要我们改正。java程序运行中不可预料的异常情况,这种异常发生以后,会直接导致JVM不可处理或者不可恢复的情况。 2.exception:运行中出现的不严重的错误,我们可以尝试去改正。java程序运行中可预料的异常情况,咱们可以获取到这种异常,并且对这种异常进行业务外的处理。
-
Exception:分类
(第一种分类)
- 系统异常:系统提前定义好的,我们直接使用
- 自定义异常:需要我们自己定义
(第二种分类)
- 编译异常:在编译阶段抛出异常,处理异常
- 运行时异常:在运行阶段抛出异常,处理异常
-
异常的特点:程序出现异常的时候,会打印异常的信息并中断程序,所以当有多个异常同时出现的时候,默认只能执行第一个.
public class Demo2 { public static void main(String[] args) { int[] arr = new int[] {4,5,6,6}; //会报NullPointerException异常:空指针异常 arr = null; //会报ArrayIndexOutOfBoundsException异常:数组下标越界异常 System.out.println(arr[10]); } }
-
JVM会调用异常类的打印方法,将异常的信息打印到控制台
-
catch会对try里面的代码进行监听,如果try里面的代码没有发生异常,catch不会执行,会直接执行后面的代码.
-
如果try里面的代码发生了异常,catch会立刻捕获(效果:try里面的代码会立刻中断,直接执行catch)
* try{ * 可能发生异常的代码 * }catch(Exception e){ //捕获异常 e就是要捕获的异常 * 对当前异常的处理 * }
-
-
多异常处理
-
catch会对try里面的代码进行监听,如果try里面的代码没有发生异常,catch不会执行,会直接执行后面的代码.
-
如果truy里面的代码发生了异常,catch会立刻捕获(效果:try里面的代码会立刻终端,直接执行catch)
-
* try{ * 可能发生异常的代码 * }catch(异常一 e){ //捕获异常 e就是要捕获的异常 * 对当前异常的处理 * }catch(异常二 e){ //捕获异常 e就是要捕获的异常 * 对当前异常的处理 * }catch(Exception e){ //捕获异常 e就是要捕获的异常 * 对当前异常的处理 * }
-
-
throw和throws的区别
throws是用来声明一个方法可能抛出的所有异常信息,throws是将异常声明但是不处理,而是将异常往上传,谁调用我就交给谁处理。
throw:就是自己进行异常处理,处理的时候有两种方式,要么自己捕获异常(也就是try catch进行捕捉),要么声明抛出一个异常(就是throws 异常~~)。 -
finally
/* * try{ * 可能发生异常的代码 * }catch(Exception e){ //捕获异常 e就是要捕获的异常 * 对当前异常的处理 * }finally{ * //必须执行的代码:主要用于资源的释放:比如关闭数据库,关闭流,关闭锁等 * } * * * 这个结构跟异常没有关系 * try{ * 获取资源 * }finally{ * 释放资源 * } */
-
自定义异常
/* * 什么是自定义异常:自己定义的异常类,由于Exception已经有了异常的基本功能,所以一般写的是他的子类 * * 为什么要自定义异常? * 系统没有定义的异常需要我们自己来定义,我们要解决的是系统没有解决的问题 * * 分类: * 编译异常:发生在编译阶段.---对应的异常是除了RumtimeException之外的所有异常 * 特点:对异常进行处理的所有工作都要我们手动完成 * 运行时异常:发生在运行阶段.---RumtimeException * 特点:所有的工作我们都可以不管 * * 常见的自定义异常:订单异常 用户异常 负数异常 * * 以负数异常为例: * 对于编译异常需要我们进行处理的有: * 异常类的创建----FuShuException * 异常对象的创建---应该是在发生异常的位置 * 异常对象的抛出---throw * 异常的声明(我们要给可能发生异常的方法进行异常的声明)----throws * 作用:告诉别人我有可能发生异常 */ class FuShuException extends Exception{ public FuShuException() { // TODO Auto-generated constructor stub } public FuShuException(String message) { //这行代码必须写 super(message); } } public class Demo6 { public static void main(String[] args) //throws FuShuException { Math4 math4 = new Math4(); //第一种方式:继续向上抛,最后交给JVM //math4.div(3, -2); //第二种:tryCatch try { math4.div(3, -2); } catch (Exception e) { e.printStackTrace(); } } } class Math4{ //声明异常,告诉别人我是有可能发生这个异常. //当需要声明多个异常的时候,直接用,隔开 public int div(int a,int b) throws FuShuException { if (b < 0) { throw new FuShuException("除数为负数了"); } return a/b; } }
-
自定义异常实例
/* 题目:老师使用电脑上课 * 上课时电脑可能发生蓝屏异常---重启电脑 * 死机异常---- 老师上课异常-----去苹果店修电脑 * * 注意:什么时候使用trycatch合适? * 在调用可能发生异常的方法时使用合适 */ public class Demo8 { public static void main(String[] args) { Teacher1 teacher1 = new Teacher1(new Computer()); try { teacher1.work(); } catch (ClassingException e) { e.printStackTrace(); System.out.println("去中关村修电脑"); } } } //创建三个异常类 class ClassingException extends Exception{ public ClassingException() {} public ClassingException(String message) { super(message); } } class LanPingException extends Exception{ public LanPingException() { } public LanPingException(String message) { super(message); } } class MaoYanException extends Exception{ public MaoYanException() { } public MaoYanException(String message) { super(message); } } class Teacher1 { Computer computer; public Teacher1(Computer computer) { super(); this.computer = computer; } //老师上课 public void work() throws ClassingException { try { computer.computerWork(); } catch (LanPingException e) { e.printStackTrace(); computer.reset(); } catch (MaoYanException e) { e.printStackTrace(); throw new ClassingException("老师无法继续上课"); } catch (Exception e) { e.printStackTrace(); } } } class Computer{ //设定当前的状态值:代表要发生的异常 1.蓝屏 2.冒烟 int status = 2; //重启方法 public void reset(){ System.out.println("重启电脑"); } //电脑工作 public void computerWork() throws LanPingException,MaoYanException { switch (status) { case 1://蓝屏 throw new LanPingException("电脑蓝屏了"); //break; case 2://冒烟 throw new MaoYanException("电脑冒烟了"); //break; default: break; } } } //在重写的方法中使用异常的注意点: /* * 1.子类的同名方法中声明的异常等级要=<父类的. * 2.子类的同名方法中声明的异常可以与父类的不一致,也可以不声明异常.但是此时子类方法不能再抛出异常 * 3.如果子类同名方法声明了异常,父类必须声明异常. */ class BadComputer extends Computer{ public void computerWork() { } }
模板设计模式
-
定义:我们在实现一个功能的时候,功能分成两部分,一部分是确定的,一部分是不确定的。将确定的部分交给当前类来实现,将不确定的部分交给子类实现,子类实现的结果又会反过来影响确定部分的功能。
-
实例
计算一个功能的耗时
固定的功能:开始时间,结束时间。
不固定的功能:程序运行的时间
public class Demo9 { public static void main(String[] args) { //测试 Zi zi = new Zi(); long value = zi.getTime(); System.out.println(value); } } abstract class Fu{ abstract public void function(); public long getTime() { //开始时间 long startTime = System.nanoTime();//获取的系统时间,单位纳秒 //程序运行的时间 function(); //结束时间 long endTime = System.nanoTime(); return endTime-startTime; } } class Zi extends Fu{ public void function() { for (int i = 0; i < 10; i++) { System.out.println("i:"+i); } } }
包装类
-
将简单数据类型的数据进行封装,形成的对应类
简单数据类型 包装类 byte Byte short Short int Integer long Long float Float double Double boolean Boolean char Character
-
自动装箱与自动拆箱
-
从jdk1.5开始可以实现自动拆箱,装箱
-
自动装箱:将数据装入对应的包装类对象的过程。在进行运算的过程中(一般是赋值运算),基本类型的值转换成对应包装类型的对象。底层调用静态方法
Integer.valueof(int i)
方法/*Integer a = 1; 实际上,在编译之后是 integer a = Integer.valueof(1) */ public static Integer valueOf(int i) { /**IntegerCache.low = -128 IntegerCache.high = 127 IntegerCache 是Integer对象的缓存器 */ if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }
它的执行过程是这样的:当i的值在-128到127之间时,返回的是缓存器中缓存的对象,否则返回的是新创建的对象。因此
Integer a = 1 ; Integer b = 1; a==b // 结果为true,a和b都是对象,比较的是地址。
-
自动拆箱:从包装类对象中取出简单数据类型数据的过程。在进行运算的过程中(赋值、算数、比较运算等),包装类型的对象转换成对应基本类型的值。底层调用实例方法
Integer.intValue()
Integer a = new Integer(1); int b = a; 实际上执行的是:int b = a.intValue();
-
-
代码实例
public class Demo10 { public static void main(String[] args) { // 基本类型转成字符串类型 // static String Integer.toString(int i) // static String Double.toString(double d) String value1 = Integer.toString(12); System.out.println(value1+2); // 字符串类型转基本类型 // int Integer.parseInt("23") // double Double.parseDouble("3.45") //注意:这里的字符串必须是数值型的字符串 int a = Integer.parseInt("234"); System.out.println(a+2); // // 把十进制转成其它进制 // Integer.toHexString() 十六进制 // Integer.toOctalString() 八进制 // Integer.toBinaryString() 二进制 System.out.println(Integer.toHexString(10)); System.out.println(Integer.toOctalString(10)); System.out.println(Integer.toBinaryString(10)); // 把其它进制转十进制 // Integer.parseInt(数据,进制) System.out.println(Integer.parseInt("10",2)); } }
枚举
-
默认对应的是数字,从0开始计数
-
枚举是一个被命名的整型常数的集合,用于声明一组带标识符的常数。
-
枚举在曰常生活中很常见,例如一个人的性别只能是“男”或者“女”,一周的星期只能是 7 天中的一个等。
-
类似这种当一个变量有几种固定可能的取值时,就可以将它定义为枚举类型。
-
代码实例
enum EnumTest{ First, Second, Third, Fourth, Fifth, Sixth } public class Demo12 { public static void main(String[] args) { EnumTest test = EnumTest.Fifth; System.out.println(test.compareTo(EnumTest.First)); switch (test.compareTo(EnumTest.First)) { case -1: System.out.println("不相等"); break; case 0: System.out.println("相等"); break; case 4: System.out.println("不相等"); break; default: System.out.println("hah"); break; } System.out.println(EnumTest.First); System.out.println(test.getDeclaringClass().getName()); System.out.println(test.name()); System.out.println(test.toString()); System.out.println(test.ordinal()); } }
Math类
装的是数学方法。
public class Demo13 {
public static void main(String[] args) {
System.out.println(java.lang.Math.abs(-10));//绝对值
System.out.println(java.lang.Math.cos(3.14159));//三角余弦
System.out.println(java.lang.Math.ceil(3.4));//向上取整
System.out.println(java.lang.Math.floor(3.4));//向下取整
System.out.println(java.lang.Math.random());//随机数 [0,1.0)
//求[0,10)之间的整数
System.out.println((int)java.lang.Math.floor(java.lang.Math.random()*10));
//Random类
//求[0,10)之间的整数
Random random = new Random();
System.out.println(java.lang.Math.abs(random.nextInt()%10));
System.out.println(random.nextInt(10));//直接获取的是[0,10)之间的数
}
}