定义:异常代表程序出现的问题。
java异常体系:
异常的基本处理:
(1)抛出异常(throws):在方法上使用throws关键字,可以将方法内部出现的异常抛出去给调用者处理。
格式:
方法 throws 异常1,异常2.。。{}
(2)捕获异常(try。。。catch),直接捕获程序出现的异常。
try{
//监视可能出现异常的代码
}catch(异常类型1 变量){
//处理异常
}catch(异常类型2 变量){
//处理异常
}
package com.it.demoexception;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class ExceptionDemo1 {
public static void main(String[] args) {
try {
//监视异常
show3();
} catch (ParseException e) {
e.printStackTrace();//打印信息
}catch ( FileNotFoundException e){
e.printStackTrace();
}
//java.text.ParseException: Unparseable date: "2024-07-09 11:12:13"
// at java.base/java.text.DateFormat.parse(DateFormat.java:403)
// at com.it.demoexception.ExceptionDemo1.show3(ExceptionDemo1.java:43)
// at com.it.demoexception.ExceptionDemo1.main(ExceptionDemo1.java:34)
}
public static void show3() throws ParseException, FileNotFoundException {
System.out.println("程序开始");
String str="2024-07-09 11:12:13";
SimpleDateFormat sdf=new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Date date=sdf.parse(str);//编译出错
System.out.println(date);
System.out.println("程序结束");
InputStream is=new FileInputStream("D:\\a.txt");
}
/*抛异常的做法
public static void main(String[] args) throws ParseException{
//show();
//show1();
show2();
}
//定义一个方法认识编译异常
public static void show2() throws ParseException {
System.out.println("程序开始");
String str="2024-07-09 11:12:13";
SimpleDateFormat sdf=new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Date date=sdf.parse(str);//编译出错
System.out.println(date);
System.out.println("程序结束");
}*/
/*//定义一个方法认识编译异常
public static void show1(){
System.out.println("程序开始");
String str="2024-07-09 11:12:13";
SimpleDateFormat sdf=new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Date date=sdf.parse(str);//编译出错
System.out.println(date);
System.out.println("程序结束");
}*/
//定义一个方法认识运行时异常,编译时不报错,运行出现错误。
public static void show() {
int a = 10;
int b = 0;
int c = a/b;
int[] arr={1,2,3};
/*System.out.println(arr[3]);
//Exception in thread "main" java.lang.ArithmeticException: / by zero
//at com.it.demoexception.ExceptionDemo1.show(ExceptionDemo1.java:20)
//at com.it.demoexception.ExceptionDemo1.main(ExceptionDemo1.java:14)*/
/*System.out.println(c);
//Exception in thread "main" java.lang.ArithmeticException: / by zero
//at com.it.demoexception.ExceptionDemo1.show(ExceptionDemo1.java:20)
//at com.it.demoexception.ExceptionDemo1.main(ExceptionDemo1.java:14)*/
String str=null;
System.out.println(str);
System.out.println(str.length());
// Exception in thread "main" java.lang.NullPointerException
}
}
作用1:异常是用来定位程序bug的关键信息。(这个再上一个环节给出了很多)
作用2:可以作为方法内部的一种特殊返回值,以便通知上层调用者,方法的执行问题。(主要看这个)
package com.it.demoexception;
/**异常的作用?
* 作用1:异常是用来定位程序bug的关键信息。(这个再上一个环节给出了很多)
* 作用2:可以作为方法内部的一种特殊返回值,以便通知上层调用者,方法的执行问题。(主要看这个)
*/
public class ExceptionDemo2 {
public static void main(String[] args) {
System.out.println("main开始");
try{
System.out.println(getResult(10,0));
System.out.println("底层方法成功了");
} catch (Exception e){
e.printStackTrace();//拦截异常
System.out.println("出现了异常");
}
System.out.println("main结束");
}
//需求:求2个数的除结果,并返回这个结果。(这里是作用2的例子)
public static int getResult(int a,int b) throws Exception {
int result = 0;
if(b==0){
System.out.println("除数不能为0,你的参数有问题");
//可以返回一个异常给上面调用者,返回的异常还能告知上层底层是执行成功了还是执行失败了。
throw new Exception("除数不能为0,你的参数有问题");
}
result = a/b;
return result;
}
}
定义:java无法为这个世界上全部问题都提供异常类来代表,如果企业自己的问题,只能通过自定义异常类来表示。
分类:自定义运行异常、自定义编译异常。
自定义编译异常:
过程:
(1)定义一个异常类继承Exception
(2)重写构造器
(3)通过throw new 异常类(XXX)创建异常对象并抛出。
特定:编译阶段就报错,提醒比较激进。
重写构造器写法:
主类代码:
package com.it.demoexception;
public class ExceptionDemo3 {
public static void main(String[] args) {
System.out.println("main开始");
//checkAge(0);这里会直接报错,因为在源程序中也会抛出异常,可以看源码
try {
checkAge(0);
System.out.println( "程序继续执行");
} catch (AgeException e) {
e.printStackTrace();
System.out.println("失败了");
}
System.out.println( "main结束");
}
//需求:我们公司的系统只要收到年龄小于1岁或者大于200岁就是一个年龄非法异常。
public static void checkAge(int age) throws AgeException{
if(age<1||age>200){
throw new AgeException("年龄非法,年龄不能小于1岁或者大于200岁");
}
else{
System.out.println("年龄合法");
System.out.println("保存年龄:"+age);
}
}
}
AgeException类方法:
package com.it.demoexception;
public class AgeException extends Exception{
public AgeException() {
}
public AgeException(String message) {//String message来接异常
super(message);//调用爸爸来封装 错误信息
}
}
自定义运行异常:
过程:
(1)定义一个异常类继承RuntimeException
(2)重写构造器
(3)通过throw new 异常类(XXX)创建异常对象并抛出。
特定:编译阶段不报错,运行才出错。
现在java都在推行使用运行异常
重写构造器写法:
主类代码:
package com.it.demoexception;
public class ExceptionDemo4 {
public static void main(String[] args) {
System.out.println("main开始");
try {
checkAge1(0);
System.out.println( "程序继续执行");
} catch (AgeException1 e) {
e.printStackTrace();
System.out.println("失败了");
}//先不报错,运行出错
System.out.println("main结束");
}
//需求:我们公司的系统只要收到年龄小于1岁或者大于200岁就是一个年龄非法异常。
public static void checkAge1(int age) throws AgeException1{
if(age<1||age>200){
throw new AgeException1("年龄非法,年龄不能小于1岁或者大于200岁");
}
else{
System.out.println("年龄合法");
System.out.println("保存年龄:"+age);
}
}
}
AgeException1类方法:
package com.it.demoexception;
public class AgeException1 extends RuntimeException{
public AgeException1() {
}
public AgeException1(String message) {//String message来接异常
super(message);//调用爸爸来封装 错误信息
}
}
1.底层异常层层往上抛,最外层捕获异常,记录下异常信息,并响应适合用户观看的信息进行提示。
2.最外层捕获异常后,尝试重新修复。
package com.it.demoexception;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class ExceptionDemo5 {
public static void main(String[] args) {
//处理方案1
System.out.println("main开始");
try {
show();
System.out.println( "show方法成功");
} catch (Exception e) {
e.printStackTrace();
System.out.println("show方法出现了异常");
}
System.out.println("main结束");
}
public static void show() throws Exception{
String str="2024-07-09 11:12:13";
SimpleDateFormat sdf=new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Date date=sdf.parse(str);//编译出错
System.out.println(date);
InputStream is=new FileInputStream("D:\\a.txt");
System.out.println("程序结束");
}
}
package com.it.demoexception;
import java.io.FileInputStream;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;
public class ExceptionDemo6 {
public static void main(String[] args) {
//处理方案2
//接受用的一个定价
System.out.println( "mian开始");
double price= 0;//乱输入数据会挂
while (true) {//Ctrl+Alt+T快捷键选择
try {
price = userInputPrice();
System.out.println("用户成功设置了商品定价"+price);
System.out.println("mian结束");
} catch (Exception e) {
System.out.println( "用户输入的定价有误");
}
}
}
public static double userInputPrice(){
Scanner in=new Scanner(System.in);
System.out.println( "请输入商品价格:");
double price=in.nextDouble();
return price;
}
}
定义: 定义类、接口、方法时,同时声明了一个或者多个类型变量(如:)称为泛型类、泛型接口、泛型方法、它们统称为泛型
格式:
public class ArrayList<E>{
}
作用:泛型提供了在编译阶段约束所能操作的数据类型,并自动进行检查的能力!这样可以避免强制类型转换,及其可能出现的问题。
package com.it.demogenericity;
import java.util.ArrayList;
public class GenericityDemo1 {
public static void main(String[] args) {
ArrayList list=new ArrayList();//此时的泛型什么都可以往里加,如果要规定就可以加标签
list.add("hello");
list.add(10);
list.add(true);
list.add('a');
list.add(88.3);
//获取数据
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
ArrayList <String> list1=new ArrayList<String>();//规定类型,但是可以进去。
list1.add("hello");
list1.add("world");
//list1.add(1);
}
}
格式:
修饰符 class 类名<类型变量,变量类型>{
}
注意:类型变量建议用大写的英文单词,常见的单词有E(element)、T(turn)、K(key)、V(value)等。
主类代码:
package com.it.demogenericity;
import java.util.ArrayList;
public class GenericityDemo2 {
public static void main(String[] args) {
//需求:请你模拟ArrayList集合自定一个集合MyArrayList。
MyArrayList<String> list=new MyArrayList<>();//JDK7之后,后面的String不用写。
list.add("hello");
list.add("world");
list.add("java");
System.out.println(list.remove( "hello"));
System.out.println(list);
}
}
MyArrayList类方法:
package com.it.demogenericity;
import java.util.ArrayList;
public class MyArrayList<E> {
//这演示不要当真,就是在欲盖弥彰,真正写很麻烦。这是一种设计模式,叫做装饰设计模式。
private ArrayList list=new ArrayList();
public boolean add(E e)
{
list.add(e);
return true;
}
public boolean remove(E e)
{
return list.remove(e);
}
@Override
public String toString() {
return list.toString();
}
}
格式:
修饰符 interface 类名<类型变量,变量类型>{
}
注意:类型变量建议用大写的英文单词,常见的单词有E(element)、T(turn)、K(key)、V(value)等。
主类代码;
package com.it.demogenericity;
public class GenericityDemo3 {
public static void main(String[] args) {
//需求:需要对学生数据/老师数据都要进行增删改查。
StudentData studentData=new StudentData();
studentData.add(new Student());
studentData.delete(new Student());
studentData.update(new Student());
studentData.query(1);
}
}
Student类方法:
package com.it.demogenericity;
public class Student {
}
StudentData类方法:
package com.it.demogenericity;
public class StudentData implements Data<Student>{
@Override
public void add(Student student) {
}
@Override
public void delete(Student student) {
}
@Override
public void update(Student student) {
}
@Override
public Student query(int t) {
return new Student();
}
}
Teacher类方法:
package com.it.demogenericity;
public class Teacher {
}
Data类方法:
package com.it.demogenericity;
public interface Data<T> {
void add (T t);
void delete (T t);
void update (T t);
T query (int t);
}
格式:
修饰符<类型变量,类型变量>返回值类型 方法名(形参列表){
}
package com.it.demogenericity;
public class GenericityDemo4 {
public static void main(String[] args) {
//需求:打印任意数组的内容
String names[]={"张三","李四","王五"};
printArray(names);
Student[] stus=new Student[3];
printArray(stus);//这样可以导入一个数组,更加强大
Student max=getMax(stus);
String max2=getMax(names);
}
public static <T> void printArray(T[] names){
}
public static <T> T getMax(T[] names){//字符串最大就返回字符串,数组中的元素大,就返回数组
return null;
}
}
定义:就是”?“。可以在”使用泛型“的时候代表一些类型;ETKV常用。
代码演示:
package com.it.demogenericity;
import java.util.ArrayList;
public class GenericityDemo5 {
public static void main(String[] args) {
ArrayList<xiaomi> xiaomiList=new ArrayList<xiaomi>();
xiaomiList.add(new xiaomi());
ArrayList<BYD> bydList=new ArrayList<BYD>();
bydList.add(new BYD());
}
//需求:开发一个极品飞车的游戏
public static void play(ArrayList<? extends Car> car){
}
}
Car类方法:
package com.it.demogenericity;
public class Car {
}
BYD类方法:
package com.it.demogenericity;
public class BYD extends Car{
}
xiaomi类方法:
package com.it.demogenericity;
public class xiaomi extends Car{
}
1.泛型不支持基本数据类型,只能支持对象类型(引用数据类型)。
2.把基本类型数据编程包装类,可以被泛型接受。
package com.it.demogenericity;
import java.util.ArrayList;
public class GenericityDemo6 {
public static void main(String[] args) {
//ArrayList list=new ArrayList();不支持报错
//泛型擦除:泛型在编译期间会被擦除,所以泛型在运行期间不会出现,所以泛型擦除。所有类型都编程Object,只接受对象,所以不支持基本数据类型。
//Integer it=new Integer(10);过时
Integer it=Integer.valueOf(10);//推荐,源码里面给你分装好了,-128到127之间,不会重复创建对象,超过128就会重新创建对象。
Integer it1=Integer.valueOf(10);
System.out.println( it==it1);//true
Integer it2=Integer.valueOf(1000);
Integer it3=Integer.valueOf(1000);
System.out.println( it2==it3);//false
// 自动装箱:基本数据类型可以自动转换为包装类型。
Integer it4=10;
Integer it5=1000;
System.out.println( it4==it5);//true
Integer it6=130;
Integer it7=130;
System.out.println( it6==it7);//false
// 自动拆箱:包装类型可以自动转换为基本数据类型。
int i=it4;
System.out.println(i);
ArrayList <Integer> list2=new ArrayList<Integer> ();
list2.add(10);//这里把10自动装箱了。
list2.add(1000);
int rs=list2.get(0);//自动拆箱
System.out.println("--------------");
//包装类新增的功能:
//1.基本类型的数据转换成字符串类型
int j=23;
String re1=Integer.toString(j);
System.out.println(re1+1);
Integer i2=j;
String res2=i2.toString();
System.out.println(res2+1);
String res3=j+"";
System.out.println(res3+1);
System.out.println("------------------------------");
//2.字符串类型转换成基本类型的数据
String s="123";
//int i1=Integer.parseInt(s);
int i1= Integer.valueOf(s);
System.out.println( i1+1);
String str2="123.23";
//double d1=Double.parseDouble(str2);
double d1=Double.valueOf(str2);
System.out.println(d1+1);
}
}