异常处理和线程

异常和错误类型

在这里插入图片描述

java.lang.error——严重错误

  • StackOverflowError栈溢出异常
public class FaFa extends Object {
	char flower;
	int number;
	public FaFa(char flower, int number) {
		plant(number);
		this.flower = flower;
		this.number = number;
	}
	public static int plant(int number) {
		Feed(number);
		System.out.println(number*=2);
		return number*=2;
	}
	public static void Feed(int number){
		plant(number);
	}
	
}


public class Test {
	public static void main(String[] args) throws java.lang.ArithmeticException {
		FaFa f1 = new FaFa('花',2);
		f1.Feed(f1.number);
		//StackOverflowError栈溢出异常,由于feed和plant方法之间循环调用,不停开辟内存,导致栈内存空间不足。
		
	}
}
  • OutOfMemoryError内存溢出异常
public static void main(String[] args) throws java.lang.ArithmeticException {
		List<FaFa> ll=new ArrayList<>();
		for(;;){
			ll.add(new FaFa());
		}
		//OutOfMemoryError内存溢出异常,由于不停创建新的实例,并保证实例一直有被引用无法释放,造成堆内存溢出异常。
	}

java.lang.exception——异常情况(会导致JVM中断运行并提示错误)

	public void printStackTrace();发生异常的位置、类型、原因;
	public String getMessage();发生异常的原因
RuntimeException 的子类
ClassCastException类型转换异常
		Object x = new Integer(0);
	    System.out.println((String)x);
	    //ClassCastException类型转换异常,编译时无法识别x的实际类型是integer;
ArithmeticException算术类异常
		System.out.println(12/0);
		//ArithmeticException算术类异常,发生于除以0等算术运算中的无效运算
NullPointerException空指针异常
		int[] arr ={12,23,435,3125};
		arr=null;
		for(int i=0;i<arr.length;i++){
			System.out.println(arr[i]);
			//NullPointerException空指针异常,arr数组中已经没有内容,无法遍历;
		}
IndexOutOfBoundsException下标越界异常
  • StringIndexOutOfBoundsException字符串下标越界异常
  • ArrayIndexOutOfBoundsException数组下标越界异常
IllegalArgumentException非法参数异常
  • NumberFormatException数字格式异常(extends IllegalArgumentException extends RuntimeException )
    (试图将一个String转换为指定的数字类型,而该字符串不满足数字类型要求的格式)
		System.out.println(Integer.parseInt("123"));
		//正常
		System.out.println(Integer.parseInt("wqe"));
		//NumberFormatException数字格式异常,Integer.parseInt只能将数字格式的字符串转换成数字
Exception(如:IOException等)的其他子类
SQLException extends Exception
NoSuchMethodException(extends ReflectiveOperationException extends Exception )

方法调用时,路径下找不到该方法

ClassNotFoundException(extends ReflectiveOperationException extends Exception )

使用类名时,路径下找不到该类

FileNotFoundException(extends IOException extends Exception)



异常处理方式


自定义异常类

public class MyException extends RuntimeException {
	public MyException() {
	       super();
	       
    }
	public MyException(String s) {
	    super(s);
	}
}

public static void main(String[] args) throws java.lang.Exception {
		System.out.println("输入数字1-10");
		Scanner s1=new Scanner(System.in);
		if(s1.nextInt()<=10&& s1.nextInt()>=1){
			System.out.println(s1.nextInt());
		}else {
			throw new MyException("输入数据超范围:"+s1.nextInt());
		}
	}
  • 必须继承exception (编译时异常一般继承这个) 或runtimeException (运行时异常一般继承这个) 才能被throw
    (只有exception类才能被throw)
  • 自定义异常类中可以封装一些提示信息

throw

  • 方法内使用
  • 一般与判断条件结合用
  • 在throws后面可以写多个异常类,用逗号隔开
  • A调用B,Bthrows了异常,A也必须throws同样的异常 或者 使用try catch处理异常==(runtime异常可以不处理不throws)==;
  • 使用异常类时可以使用其getMessage()获取异常信息、printStackTrace()打印异常的跟踪栈信息并输出到控制台的方法
public static void main(String[] args) throws Exception {
		System.out.println("输入数字1-10");
		int a =new Scanner(System.in).nextInt();
		if(a>10 || a<1){
			Exception s=new MyException("输入数据越界,"+a);
			System.out.println(s.getMessage());
			System.out.println(s.getStackTrace());
			throw s;
			
		}else {
			System.out.println(a*2);
		}
	结果:
	//以下为getmessage
	输入数据越界,12Exception in thread "main" 
	//以下为getStackTrace
	[Ljava.lang.StackTraceElement;@28d93b30
	//以下为throw s;
	com.heima.study.MyException: 输入数据越界,12
	at com.heima.study.TestThrow.main(TestThrow.java:9)
throwthrows
位置方法体内部函数名后或参数列表后
含义表示动作,此处抛出异常表示倾向,可能不发生,即写了throws后面的方法中也可能没有异常、不抛出异常
用法后面跟异常类的对象,只能有一个;
throw之后除了finally语句块,不再执行任何语句
后面跟异常类名,可以多个(逗号间隔)

try catch

格式

try{
     可能会出现异常的代码
}catch(异常类型  e){
     处理异常的代码
     //记录日志/打印异常信息/继续抛出异常
}catch(异常类型  e2){
     处理异常的代码
     //记录日志/打印异常信息/继续抛出异常
}catch(异常类型  e3){
     处理异常的代码
     //记录日志/打印异常信息/继续抛出异常
}finally{

}

优点

catch语句中可以不是抛出,而是解决方案(如打印某部分信息然后跳过此段),这样就不会导致程序中断;

不同使用方式
  • 不处理异常
public class TestThrow {
	public static void main(String[] args) throws Exception {
		System.out.println(1);
			Object x = new Integer(0);
			System.out.println((String)x);
		System.out.println(2);
	}
}
-----------------------------------
运行结果:
1
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
	at com.heima.study.TestThrow.main(TestThrow.java:9)

  • try catch处理异常
public class TestThrow {
	public static void main(String[] args) throws Exception {
		System.out.println(1);
		try {
			Object x = new Integer(0);
			System.out.println((String)x);
		} catch (ClassCastException e) {
			System.out.println("存在异常"+e);
		}
		System.out.println(2);
	}
}
---------------------------------------------
运行结果:
1
存在异常java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
2
  • try catch抛出异常
public class TestThrow {
	public static void main(String[] args) throws Exception {
		System.out.println(1);
		try {
			Object x = new Integer(0);
			System.out.println((String)x);
		} catch (ClassCastException e) {
			throw e;
		}
		System.out.println(2);
	}
}
---------------------运行结果:
1
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
	at com.heima.study.TestThrow.main(TestThrow.java:9)

  • try catch 抛出异常 finally
public static void main(String[] args) throws Exception {
		System.out.println(1);
		try {
			Object x = new Integer(0);
			System.out.println((String)x);
		} catch (ClassCastException e) {
			throw e;
		} finally {
			System.out.println(2);
		}
		System.out.println(3);
	}
---------------------------------------------------
1
Exception in thread "main" 2
java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
	at com.heima.study.TestThrow.main(TestThrow.java:9)

线程与进程

线程与进程

线程:进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程;
进程:程序执行的一次过程,每个进程都有一个独立的内存空间,一个应用程序可以同时运行多个进程;

并发与并行

并发:同一时段执行(微观来看还是交替的,只是线程调度速度快(java是抢占式调度,根据优先级))
并行:同一时间执行(多核处理器可以同时分别处理多个线程)

创建线程

继承thread类
  • 定义子类继承thread类,并重写run()方法(线程执行体),run的方法体就是线程需要完成的任务。

  • 创建Thread子类的实例,调用start()方法启动线程;

      start()  start会开启一条新的线程,在新线程就绪后开始执行重写的run方法;但是start后面的方法不用等start执行,(start会与其交替执行)
      run()  就是个普通的方法,按代码顺序执行;不建议直接使用。
    

例:

public static void main(String[] args) {
		System.out.println("11");
		Test2 t =new Test2("zoya的线程");
		t.start();
		System.out.println("------------");
		for (int i = 0; i < 10; i++) {
			System.out.println("main线程!"+i);
		}
		System.out.println("------------");
		t.run();
		System.out.println("main线程结束");
	}

运行结果如下:(start开辟的方法甚至也可以晚于main方法结束,此处只是偶然)
在这里插入图片描述

实现runnable接口
  • 避免了单继承的限制(单继承导致一个类无法既继承父类又继承thread开辟新线程)
  • 提高效率
  • ==线程池(待学习)==只能放入runnable类线程,不能放入thread的子类。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值