内部类:
/*
** 内部类:
** 建立在类中的类称为内部类;
** 内部类中的访问方式:
** 外部类若想访问内部类需简历内部类的对象方可访问;
** 内部类可以直接访问外部类中的成员和私有变量;
** 当内部类在外部类的成员位置时,可以被成员修饰符修饰;
** 如priva static。
** 当内部类用static修饰时:内部类可通过如下访问:
** new Outer.Inner().function();
** 如何直接访问static内部类中的静态成员;
** Outer.Inner.function();
** 注意:
** 非static内部类不能有静态成员(当内部类中定义了静态成员,内部类必为静态类)
** 当外部的静态方法访问内部类时,内部类也必须为静态方法;
** 什么时候使用内部类?
** 当描述事物时,事物的内部还有事物,该事物用内部类来描述;
** 内部事物在使用外部事物的内容;
*/
class Outer{
int num=1;
class Inner{
int num=2;
void function(){
num=3;
/*
** 不同位置三种变量的访问方式;
** 若没有局部成员和局部变量num,直接写num则表示外部成员;
*/
System.out.println("Inner::局部变量:"+num);
System.out.println("Inner::局部成员:"+this.num);
//当内部类用static修饰时,只能通过Out.this.num直接访问;
System.out.println("Inner::外部成员:"+Outer.this.num);
}
}
void method(){
//内部类的访问方式;
Inner in=new Inner();
in.function();
}
}
class InerClass{
public static void main(String[] args){
Outer ou=new Outer();
ou.method();
System.out.println("内部类的直接访问方式:");
Outer.Inner oi=new Outer().new Inner();
oi.function();
}
}
匿名内部类:
/*
** 匿名内部类:
** 1.匿名内部类其实就是内部类的简写格式;
** 2.定义匿名内部类的前提:
** 匿名内部类必须是继承一个类或者实现一个接口;
** 3.匿名内部类就是一个匿名子类对象;
** 该对象比较胖,可以理解为带内容的对象;
*/
class Outer{
int num=3;
public void method(){
System.out.println("Outer class.");
}
public void show(){
//匿名内部类定义在局部变量位置;
new Outer(){ //父类引用指向子类对象;
//子类对象内容;
public void sub(){
System.out.println("hi sub!");
}
}.sub(); //子类内方法调用;
}
}
class niming{
public static void main(String[] args){
Outer ou=new Outer();
ou.show(); //通过父类对象的方法调用匿名内部类;
}
}
异常:
/*
** 1.异常:程序运行时出现的不正常情况;
** 2.异常由来:问题也是现实生活中一个具体的事物,也可以通过
** java的类进行描述;并封装成对象;
** 其实就是java对不正常情况进行描述后的对象体现;
** 3.对于问题的描述:
** 一种是严重的问题,一种是非严重的问题;
** 4.对于严重的问题:java通过Error类进行描述;
** 对于Error,java一般不编写针对性的代码进行处理;
** 5.对于非严重的问题:java通过Exception类进行描述;
** 对于Exception,可以使用针对性的方式进行处理;
** 6.对多异常的处理:
** a.声明异常时,建议声明为更具体的异常,这样更方便处理;
** b.对方声明几个异常,就对应几个catch块;
*/
class Demo{
//使用throws表明该函数有可能出现异常;需对其进行异常捕捉或抛出处理
//此处定义了具体的多异常;
public int div(int x,int y) throws ArithmeticException,ArrayIndexOutOfBoundsException
{
int[] arr=new int[x];
System.out.println(arr[5]);//若此异常先执行,则下面的语句异常将不会执行;
return x/y;
}
}
class ExceptionDemo{
public static void main(String[] args){
int result;
Demo d=new Demo();
//尝试检测的异常代码块;
try{
result=d.div(5,0);
System.out.println("result:"+result);
}
//针对多异常,定义了具体的catch代码块;
catch(ArithmeticException e){ //该异常执行时,下方异常将不会执行;
System.out.println("被0除了。");
System.out.println("get message."+e.toString());;
}
catch(ArrayIndexOutOfBoundsException e){
System.out.println("数组角标越界异常。");
System.out.println("get message."+e.toString());;
}
//针对未知异常,进行如下处理;
//该异常可称为父类异常,需放在子异常后面,否则将优先处理该异常,后面的子异常将不会处理;
catch(Exception e){
System.out.println("未知异常。");
System.out.println("get message."+e.toString());;
}
}
}
自定义异常类:
/*
** 1.自定义异常类:
** 程序在设计时会出现Excepiton未定义的异常,需自定义异常。
** 对于这些问题,可以按照java对异常问题的封装思想,
** 将特有的问题,进行自定义的异常封装;
**
** 2.自定义异常实例:
** 在本例中,视除数为负数的运算也视为异常;
**
** 3.如何自定义异常信息?
** 父类中已经把异常信息的操作完成了,所以子类只要在构造时
** 通过super将异常信息传递给父类就行,
** 随后可通过父类中定义好的方法获取自定义异常信息;
** 4.自定义异常类:
** 自定义异常类必须继承自Exception。
** 5.继承Exception的原因:
** 异常体系有一个特点,异常类和异常对象都被抛出;
** 它们都具有可抛性,该性质是Throwable这个体系中的独有特点;
*/
//自定义异常类,该类继承自Exception
class selfException extends Exception{
//定义异常负数值
private int excNum;
//定义构造函数;
selfException(String mes,int num){
//使用父类Exception构造函数传递异常信息;
super(mes);
//返回异常负值;
this.excNum=num;
}
//该异常数值只读取即可,不可设置;
public int getExcNum(){
return this.excNum;
}
}
class Demo{
int num;
//在此处使用throes抛出自定义异常信息;
//函数内出现异常,函数上需要声明;
public int div(int x,int y)throws selfException
{
if(y<0)
{
//函数内出现异常,函数上需要声明;
//使用thow抛出自定义异常信息;
throw new selfException("除数为负数了!",y); //获取异常负数值;
}
return x/y;
}
}
class selfDefineException{
public static void main(String[] args){
Demo d=new Demo();
//需判断是否异常的语句;
try{
int result=d.div(4,-3);
System.out.println("result:"+result);
}
//捕捉异常信息,参数为自定义异常类,该类继承自Exception类;
catch(selfException e){ //e为自定义异常对象引用;
//使用父类中的toString()方法返回自定义的异常信息;
System.out.println(e.toString());
//获取异常负数值;
System.out.println("负数为:"+e.getExcNum());
}
}
}
自定义RuntimeException子类
/*
** Exception 中有一个特殊的子类异常,RuntimeException 运行时异常
** 如果在函数内部抛出异常,则函数上可以不用声明;
** 如果在函数上声明,则调用者可以不用进行处理;
** 之所以不用在函数上声明,是因为不需要调用者处理;
** 当该异常发生时,往往意味着程序出现了无法运算的情况,
** 希望停止程序,需对代码进行修正;
** 自定义异常时,如果异常的发生导致程序无法再此进行运算,
** 就让自定义异常继承RuntimeException;
** 对于异常分为两种,
** 1.编译时被检测的异常;
** 2.编译时不被检测的异常(运行时异常,RuntimeException及其子类)
*/
//继承自RuntimeException类的自定义异常类;
class RuntimeExc extends RuntimeException{
//需要抛出的异常信息参数;
RuntimeExc(String msg){
super(msg);
}
}
class ExceptionDemo{
int num=0;
public int div(int x,int y){
if(y<0){
//此处抛出异常信息;
//函数体内部抛出异常信息;
//函数名上并未定义throws抛出异常信息;
//继承自RuntimeException的异常类只需在一处定义。
throw new RuntimeExc("wrong!");
}
return x/y;
}
}
class RuntimeExceptionDemo{
public static void main(String[] args){
ExceptionDemo ed=new ExceptionDemo();
int num=ed.div(18,-9);
System.out.println(num);
}
}
关于finally,finally定义在catch代码块后面。finally中的内容是程序不管是否异常都会执行的部分,特别是数据库的关闭,不管对数据的操作是否成功,最后一定要执行的就是关闭数据库的连接;只有一种情况finally不会执行,finally前有System.exit(0);该语句表示jvm退出;
异常代码块的三种格式:
/*
** 第一种格式;
*/
try{
}
catch{
}
/*
** 第二种格式;
*/
try{
}
catch{
}
finally{
}
/*
** 第三种格式;
*/
try{
}
finally{
}
catch是用于处理异常的,如果没有catch,则该异常没有被处理;
如果异常是检测时异常,必须声明。
异常在子父类覆盖中的体现:
1.子类在覆盖父类时,如果父类的方法抛出异常,那么子类的覆盖方法只能抛出父类的异常或者该异常的子类。
2.如果父类方法抛出多个异常,那么子类在覆盖该方法时,只能抛出父类异常的子集。
3.如果父类或者接口的方法中没有异常抛出,那么子类在覆盖方法时,也不可以抛出异常,如果子类的方法发生了异常,就必须要try处理,绝对不能抛。