本笔记基于黑马程序员java教程整理,仅供参考
指系统级别的错误,程序员无法解决,不必理会
分为两类:
RuntimeException:运行时异常,编译时程序不会报错,运行时报错,如数组越界
其他异常:编译时异常,编译时就会报错
运行时异常:
public class Text {
public static void main(String[] args) {
text();
}
public static void text() {
int[] a = new int[]{1, 2, 3};
System.out.println(a[3]); //数组越界,报运行时异常,不会执行下面的代码
System.out.println("程序结束");//不会执行
}
}
编译时异常:
public class Text {
public static void main(String[] args) {
text();
}
public static void text() {
String time="2020-01-01 00:00:00";
//把time解析成java中的一个时间对象
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date=sdf.parse(time); //创建时间对象,编译时报错,表示提示这里很容易出错,提醒程序员,并不是代码错误,如果时间的格式不对就会报异常
}
}
1.2.1抛出异常(throws)
在方法上使用throws关键字,将内部异常抛出去给调用者处理
public class Text {
public static void main(String[] args) throws ParseException { //你抛给我,我也抛出去
text();
}
public static void text() throws ParseException { //抛出异常
String time="2020-01-01 00:00:00";
//把time解析成java中的一个时间对象
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date=sdf.parse(time); //创建时间对象,编译时报错,表示提示这里很容易出错,提醒程序员,并不是代码错误
}
}
1.2.2捕获异常(try...catch)
public class Text {
public static void main(String[] args) { //你抛给我,那我来捕获异常
try { //如果没有异常,执行try代码块
text();
} catch (ParseException e) { //如果出现异常,会被捕获,并执行catch代码块
e.printStackTrace(); //输出异常信息
}
}
public static void text() throws ParseException { //谁调用我我就抛异常给谁
String time="2020-01-01 00:00:00";
//把time解析成java中的一个时间对象
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date=sdf.parse(time); //创建时间对象,编译时报错,表示提示这里很容易出错,提醒程序员,并不是代码错误
System.out.println(date);
}
}
如果看不懂上面的例子,下面还有一个简答例子
public class Text {
public static void main(String[] args) {
try {
test(10,0);
}
catch (RuntimeException e){
System.out.println(e.getMessage());
}
}
// public static int text(int a,int b){
// if(b==0){
// System.out.println("除数不能为0");
// return 0; //一般我们需要截断程序,但是必须要有返回值,但是返回数值不正确,因为程序可能认为是程序没有问题,所以返回结果0
// }
// return a/b;
// }
public static void test(int a,int b){
if(b==0){
throw new RuntimeException("除数不能为0"); //处理方案:返回一个异常告诉程序是执行成功还是失败(编译时异常和运行时异常都可以),可以作为一种特殊的返回方法
}
System.out.println(a/b);
}
}
如果项目中需要自行定义异常,比如收到年龄小于0或者大于200就表示异常,此时需要我们
1.创建一个类继承Exception或者RuntimeException异常类
2.重写Exception或者RuntimeException的构造器
方案一:当底层程序有异常时,将异常全部抛出,到外层调用者,然后捕获异常,响应信息给用户观看
方案二:当底层程序有异常时,将异常全部抛出,到外层调用者,然后捕获异常,尝试重新修复
如输入double型商品定价,用户错误输入其他类型信息,我们可以在try...catch方法外使用while循环,直到用户输入正确定价后结束
public class Demo {
public static void main(String[] args) {
ArrayList list = new ArrayList();//创建集合对象,能存放任意类型的数据
ArrayList list2 = new ArrayList<>();//创建集合对象,只能存放String类型的数据,就是泛型,可以修改
}
}
public class ArryList{ //表示泛型,只能创建该数据类型,常用E,T,K,V
}
public class Demo {
public static void main(String[] args) {
myArrayList list2 = new myArrayList<>();
}
}
public class myArrayList { //泛型类
}
public interface A{ //泛型接口
}
public class Demo {
public static void main(String[] args) {
StudentData sd = new StudentData();
sd.add(...);
TeacherData td = new TeacherData();
td.add(...);
}
}
public interface A {
public void add(E e); //使用泛型既可以接收老师也可以接收学生
// public void add(Students e);//不用泛型只能单独接收老师或学生
}
public class Students {
}
public class Teacher {
}
public class TeacherData implements A{
@Override
public void add(Teacher teacher) {
}
}
public class StudentData implements A {
@Override
public void add(Students students) {
}
}
泛型方法:
public static void text(T t){
}
public class Text {
public static void main(String[] args) {
String []name = new String[3];
name[0]="张三";
name[1]="李四";
name[2]="王五";
print(name);
Students []s = new Students[3];
s[0] = new Students("张三", 16);
s[1] = new Students("李四", 9);
print(s);
}
// public static void print(String[] name){ //只能接收String类型数组,为了能接收其他类型数组,使用泛型
// for (int i = 0; i < name.length; i++) {
// System.out.println(name[i]);
// }
// }
public static void print(E[] name){ //使用泛型
for (int i = 0; i < name.length; i++) {
System.out.println(name[i]);
}
}
}
通配符:?
上下限
//提前创建Car父类和XiaoMi和Bud子类
public class Text {
public static void main(String[] args) {
ArrayList list = new ArrayList<>();
list.add(new XiaoMi());
list.add(new XiaoMi());
ArrayList list2 = new ArrayList<>();
list2.add(new Bud());
list2.add(new Bud());
}
// public static void go(ArrayList list){ //只能单独接XiaoMi或者Bud
//
// }
//或许我们会这样解决,但是这样会报错,因为ArrayList,ArrayList和ArrayList没有关系,好比男女厕所和公厕
// public static void go2(ArrayList list){ //只能接XiaoMi或者Bud
//
// }
//此时我们可以用通配符,通配符就是?,通配符表示什么类型都可以,但是不能用具体的类型,只能用抽象的类型
public static void go3(ArrayList> list){ //只能接XiaoMi或者Bud
}
//但是只用通配符还是有风险,比如我定义了一只狗的集合,也能放进来,这很显然是不对的
//于是我们就可以用上限通配符,上限通配符就是? extends Car,上限通配符表示只能接Car或者Car的子类
public static void go4(ArrayList extends Car> list){ //只能接XiaoMi或者Bud
}
}
泛型只能支持对象类型(引用数据类型),不支持基本数据类型,如int等
public class Demo {
public static void main(String[] args) {
ArrayList list = new ArrayList<>();//支持,不报错
ArrayList list = new ArrayList<>(); //不支持,报错
//我们可以将int 包装成Integer引用数据类型
ArrayList list2 = new ArrayList<>(); //支持,不报错
ArrayList list = new ArrayList<>(); //不支持,报错
ArrayList list3 = new ArrayList<>();//支持
//其他基本的数据类型只要将首字母大写,就是对应的包装类,如Double、Float、Long、Short、Byte、Boolean、Character
}
}