1.Throwable 子类
内容来源:
Java Throwable类及其子类_loongshawn的博客-CSDN博客_java throwable
Error类:就是程序运行时候抛出的最严重级别的错误了,如VirtualMachineError,ThreadDeath。抛出了Error的程序从Java设计的角度来讲,程序基本不可以通过后续代码修复,从而理应终止。
Exception类,分为checked和unchecked。
checked Exception就是在写代码的时候,IDE会要求你写try catch的那种Exception,比如IOException。这种Exception是Java的设计者要求你的程序去处理的。这种异常一般不会影响程序的主体,容易手动诊断修复,所以Java要求你在catch下面写出处理的代码,以保证程序遇到此类exception之后还可以正常运行。
unchecked这一类就是你在代码处理了checked exception之后,你在运行时候依然会遇到的exception,所以又叫做RunTimeException,比如NullPointerException, IndexOutOfBoundsException。此类exception相较于前面那种更容易影响程序运行,从设计者角度不提倡从程序中catch出来并处理,当然你也可以这么做。
2.StackOverflowError
java虚拟机的栈不够用了,一般是过深递归导致的。
class B
{
void f()
{
f();
}
}
class A
{
public static void main(String[] args)
{
B b = new B();
b.f();
}
}
直接爆栈
class B
{
C c = new C();
}
class C
{
B b = new B();
}
class A
{
public static void main(String[] args)
{
B b = new B();
}
}
循环实例化,爆栈。
3.OutOfMemory
1.java.lang.OutOfMemoryError: Java heap space
原因:Heap内存溢出。
解决:调整java启动参数 -Xms -Xmx 来增加Heap内存。
2.java.lang.OutOfMemoryError: unable to create new native thread
原因:Stack空间不足以创建额外的线程,要么是创建的线程过多,要么是Stack空间确实小了。
解决:由于JVM没有提供参数设置总的stack空间大小,但可以设置单个线程栈的大小;而系统的用户空间一共是3G,除了Text/Data/BSS/MemoryMapping几个段之外,Heap和Stack空间的总量有限,是此消彼长的。因此遇到这个错误,可以通过两个途径解决:1.通过-Xss启动参数减少单个线程栈大小,这样便能开更多线程(当然不能太小,太小会出现StackOverflowError);2.通过-Xms -Xmx 两参数减少Heap大小,将内存让给Stack(前提是保证Heap空间够用)。
3.java.lang.OutOfMemoryError: PermGen space
原因:Permanent Generation空间不足,不能加载额外的类。
解决:调整-XX:PermSize= -XX:MaxPermSize= 两个参数来增大PermGen内存。一般情况下,这两个参数不要手动设置,只要设置-Xmx足够大即可,JVM会自行选择合适的PermGen大小。
4.java.lang.OutOfMemoryError: Requested array size exceeds VM limit
原因:这个错误比较少见(试着new一个长度1亿的数组看看),同样是由于Heap空间不足。如果需要new一个如此之大的数组,程序逻辑多半是不合理的。
解决:修改程序逻辑吧。或者也可以通过-Xmx来增大堆内存。
基本上常见的够了,剩下的遇到再说。
(5条消息) Java中的OutOfMemoryError的各种情况及解决和JVM内存结构_weixin_34380948的博客-CSDN博客
4.异常处理方式
1.抛出异常throw,throws
2.程序捕获处理try,catch,finally
try 用于监听。将要被监听的代码(可能抛出异常的代码)放在try语句块之内,当try语句块内发生异常时,异常就被抛出。
catch 用于捕获异常。catch用来捕获try语句块中发生的异常。
finally finally语句块总是会被执行。它主要用于回收在try块里打开的物力资源(如数据库连接、网络连接和磁盘文件)。只有finally块,执行完成之后,才会回来执行try或者catch块中的return或者throw语句,如果finally中使用了return或者throw等终止方法的语句,则就不会跳回执行,直接停止。
throw 用于抛出异常。
throws 用在方法签名中,用于声明该方法可能抛出的异常。主方法上也可以使用throws抛出。如果在主方法上使用了throws抛出,就表示在主方法里面可以不用强制性进行异常处理,如果出现了异常,就交给JVM进行默认处理,则此时会导致程序中断执行。
class A
{
public static int f(int a,int b,int c,int d)throws Exception
{
try
{
c = a/b;
b = a/d;
}
catch (Exception e)
{
//System.out.println(e);
d = 1;
throw(e);
}
finally
{
System.out.println("!"+a+" "+b+" "+c+" "+d);
//return 12;
}
return 12;
}
public static void main(String[] args)
{
int a,b,c,d;
a = 1;b = 2;c = 3;d = 0;
try
{
int h = f(a,b,c,d);
System.out.println(h);
}
catch (ArithmeticException e)
{
System.out.println("divided by zero!");
}
catch (Exception e)
{
System.out.println("other: "+e);
}
}
}
可以尝试打开那个注释看看警告是啥。
5.RuntimeException
ArithmeticException:数学计算异常。
class A
{
public static void main(String[] args)
{
int a,b,c,d;
a = 1;b = 2;c = 3;d = 0;
try
{
int e = c/d;
}
catch (ArithmeticException e)
{
System.out.println(e);
}
catch (Exception e)
{
System.out.println("other: "+e);
}
}
}
NullPointerException:空指针异常。
int [] a = null;
try
{
a[0] = 1;
}
catch (NullPointerException e)
{
System.out.println(e);
}
NegativeArraySizeException:负数组长度异常。
ArrayIndexOutOfBoundsException:数组索引越界异常。
class A
{
public static void main(String[] args)
{
int [] a = new int [100];
try
{
a[100] = 1;
}
catch (ArrayIndexOutOfBoundsException e)
{
System.out.println(e);
try
{
a = new int[-1];
}
catch(NegativeArraySizeException ee)
{
System.out.println(ee);
}
}
catch (Exception e)
{
System.out.println("other: "+e);
}
}
}
ClassCastException:类型强制转换异常。
class fa
{
}
class son1 extends fa
{
}
class son2 extends fa
{
}
class A
{
public static void main(String[] args)
{
try
{
fa first = new son1();
fa sec = new son2();
first = (son2)(first);
}
catch (ClassCastException e)
{
System.out.println(e);
}
catch (Exception e)
{
System.out.println("other: "+e);
}
}
}
报错就不写了,那玩意看不懂不会自己翻译吗
6.自定义异常
//my_expection.java
package test;
public class my_expection extends Exception
{
my_expection(String msg)
{
super(msg);
}
static void throw_one(int a)throws my_expection
{
if(a>25 || a<15)
{
throw new my_expection("age "+a+" is not allowed");
}
}
}
//1.java
class A
{
public static void main(String[] args)
{
try
{
int age = 10;
my_expection.throw_one(age);
}
catch (ClassCastException e)
{
System.out.println(e);
}
catch (Exception e)
{
System.out.println("other: "+e);
}
}
}
7.throws与throw的区别。
throw 用于抛出异常。
throws 用在方法签名中,用于声明该方法可能抛出的异常。主方法上也可以使用throws抛出。如果在主方法上使用了throws抛出,就表示在主方法里面可以不用强制性进行异常处理,如果出现了异常,就交给JVM进行默认处理,则此时会导致程序中断执行。例子上面就有不少。
8.finally
finally语句块总是会被执行。它主要用于回收在try块里打开的物力资源(如数据库连接、网络连接和磁盘文件)。只有finally块,执行完成之后,才会回来执行try或者catch块中的return或者throw语句,如果finally中使用了return或者throw等终止方法的语句,则就不会跳回执行,直接停止。