68.什么是异常
- 异常(Exception)是程序运行过程中发生的事件,该事件可以中断程序指令的正常执行流程
68.异常的处理机制(重点)
- 当Java程序运行出现问题时,系统会自动检测到该错误,并立即生成一个与该错误对应的异常对象
- 然后把该异常对象提交给Java虚拟机
- Java虚拟机会自动寻找相应的处理代码来处理这个异常,如果没有找到,则由Java虚拟机做一些简单的处理后,程序被强行终止!
- 程序员可以自己编写代码来捕捉可能出现的异常,并编写代码来处理相应的异常
69.异常的分类
- Error
- 由Java虚拟机生成并抛出,包括动态链接失败、虚拟机错误等,Java程序无法对此错误进行处理
- RuntinmeException
- Java虚拟机运行时生成的异常,如被0除等系统错误、数组下标越界等,其产生比较频繁、处理麻烦,对程序可读性和运行效率影响太大,因此由系统检测,用户可不做处理,系统将它们交给缺省的异常处理程序
- Exception
- 一般程序中可预知的问题,其产生的异常可能会带来意想不到的结果,因此Java编译器要求Java程序必须捕获或声明所有的非运行时异常
70.异常处理步骤
71.捕捉处理异常注意问题
72.Finally的作用
- 无论try所指定的程序块中是否抛出异常,也无论catch语句的异常类型是否与所抛出的异常的类型一致,finally中的代码一定都会执行
- finally语句为异常处理提供一个统一的出口,使得在流程控制转到程序的其它部分以前,能够对程序的状态作统一的管理
- 通常在finally语句中可以进行资源的清除工作,如关闭打开文件,删除临时文件等
73.throw
- throw用来抛出异常
- 格式:
- Throw new 异常名(参数);
- 假设f方法抛出了A异常,则f方法有两种方式来处理A异常
- Throws A
- 谁调用f方法,谁处理A异常,f方法本身不处理A异常
- try{…….}catch(){……..}
- f方法本身自己来处理A异常
- 要抛出的异常:必须得是throwable的子类
74.throws
- Void f()throws A
{
……
……
}
- throws A 表示调用f方法时f方法可能会抛出A类异常,建议您调用f方法时,最好对f方法可能抛出的A类异常进行捕捉
- Throws A 表示f方法不一定会抛出A类异常
- Throws A f方法也可以不抛出A类异常
- Throws A 不表示调用f方法时,必须得对A异常进行捕捉
- 假设A是RuntimeException的子类异常
- 由于RuntimeException的子类异常可以处理也可以不处理,所以编译器允许你调用f()方法时,对f()方法抛出的RuntimeException子类异常可以不进行处理
- 强烈建议:
- 对throws出的所有异常进行处理
- 如果一个方法内部已经对A异常进行了处理,则不要再throws A
75.注意问题
- 所有的catch只能有一个被执行
- 有可能所有的catch都没有执行
- 先catch子类异常再catch父类异常
- 如果先catch父类异常再catch子类异常,则编译时会报错
- catch与catch之间是不能有其它代码的
- 重写方法抛出异常的范围不能大于被重写方法抛出的异常范围
76.异常的优点
77.以常规方法处理错误存在的问题
- 观察前面的程序,大家都会发现大部分精力花在出错处理上了
- 只把能够想到的错误考虑到,对以外的情况无法处理
- 程序可读性差,大量的错误代码混杂在程序中
- 出错返回信息量太少,无法更确切地了解错误状况
78.异常的优缺点
- 优点:
- 强制程序员考虑程序的安全性和健壮性
- 增强了程序员对程序的可控性
- 有利于代码的调试
- 把错误处理代码从常规代码中分离出来
- 注意:
- 异常并不一定能够使程序的逻辑更清晰
- 因为我们有时必须得编写代码捕捉异常,所以可能会导致程序的逻辑非常混乱
- 异常并不能解决所有问题
79.toString方法总结
- 所有的类都默认继承了Object类
- Object类中的toString方法返回的是类的名字和该对象的哈希码组成的一个字符串
- System.out.println(类对象名):实际输出的是该对象的toString()方法所返回的字符串
- 为了实际需要,建议子类重写从父类Object继承过来的toString方法
80.Object类的equals方法
- 所有的类都从Object类中继承了equals方法
- Object类中equals方法源代码如下:
Public boolean equals(Object obj)
{
retun this==obj
}
- Object中的equals方法是直接判断this和obj本身的值是否相等,即用来判断调用equals的对象和形参obj所引用的对象是否是同一对象,所谓同一对象就是指内存中同一块存储单元,如果this和obj指向的是同一块内存对象,则返回true,反之,则返回false
- 如果是同一块内存,则Object中的equals方法返回true,反之返回false
81.何时需要重写equals方法
- 用一个类构造出来的不同内存的两个对象,如果内存中的值相等,我们一般情况下认为这两个对象也相等,很明显Object中的equals方法无法完成这样的重任,Object中的equals方法只有在两个对象是同一块内存时才返回true,这时候我们有必要重写父类Object中的equals方法
- 如果希望不同内存但内容相同的两个对象equals时返回true,则我们需要重写父类的equals方法
82.String类
- Java.lang.String类对象表示不可修改的Unicode编码字符串
- 在Java中双引号括起来的字符串也被当做String对象
- System.out.println("abc".length())// 输出3
- System.out.println(“abc”.equals("abc"))//输出true
83.String类的equals方法
- String类已经重写了Object中的equals方法
- 例子:
- 假设str1和str2都是String对象
- str1.equals(str2):是用来比较str1变量本身所占内存的值所指向的对象和str2变量本身所占内存的值所指向的对象的内容是否相等,如果相等返回true,反之,返回falase
- String类的equals方法是用来判断两个对象的内容是否相等,Object类的equals方法是用来判断两个对象是否是同一个对象
- 一定要注意 == 和 equals的区别
84.String类示例内存示意图
85.String类常用方法
常用方法 | 作用 |
Public char charAt(int index) | 返回字符串第index个字符 |
Public int length() | 返回字符串长度 |
Public int indexOf(String str) | 返回字符串出现str的第一个位置 |
Public int indexOf(String str,int fromindex) | 返回字符串中从fromindex开始出现str的第一个位置 |
Public boolean equalsIgnoreCase(String another) | 比较字符串与another是否一样 |
Public String replace(char oldChar,char newChar) | 在字符串中用newchar字符替换oldchar字符 |
Public boolean startWith(String prefix) | 判断字符串是否以prefix字符串开头 |
Public boolean endwith(String suffix) | 判断字符串是否以suffix字符串结尾 |
Public String toUpperCase() | 返回一个字符串为该字符串的大写形式 |
Public String toLowerCase() | 返回一个字符串为该字符串的小写形式 |
Public String substring(int beginIndex) | 返回该字符串从beginIndex开始到结尾的字符串 |
Public String substring(int beginIndex,int endIndex) | 返回该字符串从beginIndex开始到endIndex结尾的子字符串 |
- 静态重载方法
- Public static string valueOf(…)可以将基本类型数据转换为字符串
- Public static String valueOf(double b)
- Public staitic String valueOf(int i)
- 方法public String[] split(String regex)可以将一个字符串按照指定的分隔符分开,返回分割后的字符串数组
86.StringBuffer类由来
- String类对象一旦创建就不可更改
- 如果经常对字符串内容进行修改,则使用StringBuffer
- 如果经常对字符串内容进行修改而使用String的话,就会导致即耗空间又耗时间
- 例子:
- String s1 = “absasdfas”; String s2 = "123";
- String s1 = s1 + s2;
- 删除S1的字母d
- StringBuffer类对象的内容是可以改变的
- 因为String类中没有修改字符串的方法,但是StringBuffer类中确有大量修改字符串的方法
87.StringBuffer类的构造函数
- Public StringBuffer()
- 创建一个空的没有任何字符的StringBuffer对象
- Public StringBuffer(int cacpacity)
- 创建一个不带字符,但具有指定起始容量的字符串缓冲区
- Public StringBuffer(String str)
- 创建一个StringBuffer对象,包含与str对象相同的字符序列
88.StringBuffer常用方法
- 重载方法public StringBuffer append(…)可以为该StringBuffer对象添加字符序列,返回添加后的该StringBuffer对象引用,例如:
- Public StringBuffer append(String str)
- Public StringBuffer append(StringBuffer sbuf)
- Public StringBuffer append(char【】 str)
- Public StringBuffer append(char【】 str, int offset,int len)
- Public StringBuffer append(double d)
- Public StringBuffer append (Object obj)
- Piblic StringBuffer insert(int offset,String str)
- Public StringBuffer insert(int offset,double d)
- 方法public StringBuffer delete(int start,int end)可以删除从start到end-1为止的一段字符序列,返回修改后的StringBuffef对象引用
- 和String类含义类似的方法:
- Public int indexOf(String str1)
- Public int indexOf(String str1,int fromindex)
- Public String substring(int start)
- Public String substring(int start, int end)
- Public int length()
- 方法public StringBuffer reverse()用于将字符序列逆序,返回修改后的该StringBuffer对象引用
89.数组概述
- 为什么需要数组
- 为了解决大量同类型数据的存储和使用问题
- 为了模拟现实世界
- 什么叫一维数组
- 为n个变量连续分配存储空间
- 所有变量的数据类型相同
- 所有变量所占的字节数相同
- 数组中的元素既可以是基本类型变量,也可以是引用类型变量
90.一维数组的使用
- 一维数组声明的语法格式
- <类型> val【】;
- <类型>【】val;
- 举例:
- 方式一
- Int【】Arr1;
- Arr1 = new int【3】
- 方式二
- Int 【】Arr2 = new int【】{0,1,2}
- 方式三
- Int【】 arr3 = {1,2,3}
91.多维数组
- 多维数组举例
- int【】【】xx = new int【2】【3】 // 等长数组
- int【】【】xx = {{3,1,2},{5,63},{5}} // 不等长数组
92.数组的拷贝(1)
- Public static void arraycopy(Object arr1,int pos1,Object arr2,int
pos2,int length)
- 将arr1所指向的数组中下标从pos1开始的总共length个元素
覆盖掉arr2所指向的数组中从pos2开始的length个元素
- 注意:
- arr1是源数组,arr2是目的数组
- arraycopy()全是小写,不能是大写
93.数组的拷贝(2)
- Int【】 source = {1,2,3,4,5,6}; // 源数组
- Int【】 dest ={10,9,8,7,6,5,4,3,2,1}
- 目的数组System.arraycopy(source,0,dest,2,3)
- 将source数组下标从0开始的总共3个元素的值复制给dest数组中下标从2开始的3个元素
94.数组的排序