JAVA异常和匿名内部类

8.3 内部类&异常

内部类

内部类:定义在一个类的内部的类.内部类的地位与外部类的成员变量,成员方法平等,内部类也可以看做是外部类的成员,成员之间可以相互调用

内部类的作用:

1.间接实现了多继承

2.方便定义

3.只有外部类可以访问创建的内部类的属性和方法,包括私有方法

4.同一个包中其他的类不可见,有了很好的封装性

注意:除了new Object类是匿名对象,其他所有类的匿名对象本质上都是匿名子类对象.

class  Outer{
    int age;
//内部类
class  Inner{
    int height;
    public  void run(){
        System.out.println("Inner-run");
    }
}
public void  show(){
    System.out.println("Outer-show");

    Inner inner = new Inner();
    inner.run();
}
}

调用内部类的方法的方式
第一种:借助于外部类的方法实现

        //show是外部类的方法
        public void  show(){
    System.out.println("Outer-show");

    Inner inner = new Inner();
    inner.run();
}

第二种:直接在这里调用
引用:外部类.内部类
构成:外部类对象的引用.new 内部类的构造方法

外部类.内部类=外部类对象的引用.new 内部类的构造方法
    Outer.Inner inner = outer.new Inner();
    //当通过import将Inner直接导入后,可以直接使用Inner,不推荐

内部类实现多继承

class A{

}

class B{

}
要求:要让X同时继承来自A和B的内容,并且A和B没有关系.

我们可以通过内部类让java间接实现多继承

class  X extends  A{
    class  Y extends  B{
}
}

成员内部类

局部内部类

局部内部类:定义在一个类方法中的类
作用范围:从定义开始到当前的方法结束

了解:局部内部类所在的方法中局部变量的使用.
局部变量的作用域:定义变量开始到函数结束
final:被final修饰的变量会被放在常量区,而常量区的值存在的时间要大于局部变量所在的方法,相当于从原来的基础上扩大了作用域
原理:
当方法中同时存在局部内部类与局部变量时,局部变量的使用范围就会从原来的基础上进行扩大.
原因:在当前程序执行时,程序会默认让final去修饰height.所以当局部变量所在的方法结束的时候,变量没有被释放,保存的值还在.

关于变量前面的final:
前提:变量必须与局部内部类同时存在.并且在局部内部类中使用了当前的局部变量
在jdk1.7之前要想保住局部变量的值,要手动添加final
在jdk1.7之后,程序执行时,java的内部机制已经在变量的前面默认添加了final

class  Outer1{
    int age;
public void  show(){
    System.out.println("Outer-show");
 	//隐藏final
    int height=0;
    //局部内部类
    class  Inner{

        public  void run(){
            System.out.println("Inner-run"+height);
        }
    }

    Inner inner = new Inner();
    inner.run();
}
}

局部内部类应用

public class Demo4 {
    public static void main(String[] args) {
        Outer4 outer4 = new Outer4();
        outer4.show();
        outer4.eat();
    }
}


//外部类
class Outer4{
    Object object = null;
    public void show() {
        /*
         * 了解内容:
         *
         * final:被final修饰的变量会被放在常量区,而常量区的值的存在时间要大于当前的方法,相当于扩大了原来局部变量的作用域,
         * 即方法执行完了,变量也不会被释放
         *
         *
         * 只要将下面的结论记住就可以
         *
         * 前提:方法中使用了局部内部类
         * 在jdk1.7之前,要想保住这个值必须手动添加final
         * 在jdk1.8及之后,java的内部机制已经在变量的前面默认添加了final
         */
        int  age = 6;
        class Inner{//局部内部类

            public void run() {
                System.out.println("跑"+age);
            }

            @Override
            public String toString() {
                // TODO Auto-generated method stub
                return "toString    "+age;
            }
        }

        //show的内部使用局部内部类
        object = new Inner();//利用多态

    }

    public void eat(){
        System.out.println(object.toString());
        System.out.println("eat");
    }
}




静态内部类

public class Demo5 {
    public static void main(String[] args) {
//		Out out = new Out();
//		Out.Inn inn = out.new Inn();
        //创建静态内部类对象
        //构成:  new  +  外部类名字.内部类的构造方法
        Out.Inn inn =  new Out.Inn();
        //调用方法
        inn.play();
        //调用静态方法
        // inn.show();
        Out.Inn.show();
    }
}


class Out{
    static int age;
    //静态内部类不一定有静态方法,有静态方法的一定是静态内部类
    static class Inn{//静态内部类
        public void play() {
            System.out.println("play");
        }
        public static void show() {
            System.out.println("show");
        }
    }
}

匿名内部类

  • 匿名内部类(对象):定义在一个类方法中的匿名子类对象,属于局部内部类

  • 匿名子类对象:

  • 匿名内部类对象:

  • 创建匿名内部类对象注意点:1.匿名内部类对象必须有父类或者接口

    匿名内部类对象的作用:

  • 1.当只用到当前子类的一个实例对象的时候,定义好马上使用,使用完立刻释放

  • 2.当不好起名字的时候

  • 3.可以更好的定义运行时的回调(知道即可)

构成: new + 父类的名字/接口的名字 + () + {写当前子类的成员} + ;

{是子类的内部}

若是接口需要再{里面重写接口方法}

class  Test1{
    public  void  show(){
        //匿名内部类
        new Animal(){
            @Override
            public void eat() {
                System.out.println("匿名子类对象-eat");
            }
        }.eat();
    }

//匿名内部类使用

//普通的匿名对象作为参数
public void canShuTest(){
    System.out.println(new Animal());
}
//匿名内部类作为参数
public  void  canShuTest1(){
    System.out.println(new Animal(){
        @Override
        public void eat() {
            System.out.println("eat");
        }
    });
}

异常

异常:程序中出现的不正常的情况

异常的由来:程序在运行时出现了不正常的情况,java提取了对应的属性,名字,原因等,形成了异常对象,进而形成了各种的异常类

异常的分类:
throwable异常和错误的超类
1.Error:(错误):运行中出现的严重错误,不需要我们进行更改.
2.Exception(异常):运行中出现的不严重的错误,我们可以尝试去更改.

Exception:分类:
第一种分类:系统异常:系统提前定义好的,我们直接使用
自定义异常:需要我们自己定义.
第二种分类:编译异常:在编译阶段抛出异常,处理异常
运行时异常:在运行阶段抛出异常,处理异常.

异常的特点:程序出现异常的时候,会打印异常的信息并中断程序,所以当有多个异常同时出现的时候,默认只能执行第一个.

异常的常用结构

catch会对try里面的代码进行监听,如果try里面的代码没有发生异常,catch不会执行,会直接执行后面的代码.
如果try里面的代码发生了异常,catch会立刻捕获(效果:try里面的代码会立刻中断,直接执行catch)
try{
可能发生异常的代码
}catch(Exception e){ //捕获异常 e就是要捕获的异常
对当前异常的处理
}

public class Demo9 {
    public static void main(String[] args) {
        Math1 math = new Math1();
        try {
            math.div(3,0);//3.这里也没有处理异常的能力,所以会继续往上抛,抛给他所在的方法
            //只有try里面的代码没有发生异常,这里的代码才能执行
            System.out.println("try");
        }catch (ArithmeticException e){
            //e.printStackTrace();  获取异常的位置,原因,名字
            System.out.println(e.getMessage());//原因
            System.out.println("catch");
        }

        System.out.println("go on");
    }
}

class  Math1{
    public int div(int a,int b){//2.这里也没有处理异常的能力,所以会继续往上抛,抛给调用这个方法的位置
        return  a/b;//1.在这里创建一个异常的对象(new ArithmeticException())  因为这里没有处理异常的能力,所以会将异常往上抛,抛给他所在的方法
    }
}

多异常处理
catch会对try里面的代码进行监听,如果try里面的代码没有发生异常,catch不会执行,会直接执行后面的代码.
如果truy里面的代码发生了异常,catch会立刻捕获(效果:try里面的代码会立刻终端,直接执行catch)
try{
可能发生异常的代码
}catch(异常一 e){ //捕获异常 e就是要捕获的异常
对当前异常的处理
}catch(异常二 e){ //捕获异常 e就是要捕获的异常
对当前异常的处理
}catch(Exception e){ //捕获异常 e就是要捕获的异常
对当前异常的处理
}

  try {
            math2.div(3, 0);
        } catch (ArithmeticException e) {//除数为零异常
            e.printStackTrace();
        } catch (NullPointerException e) {
            e.printStackTrace();
        } catch (Exception e) {//注意:Exception异常必须放在最后一个catch
            e.printStackTrace();
        }

e.getMessage()//原因

e.printStackTrace()//输出异常位置和类型

try finaly

  • try{

  • 可能发生异常的代码

  • }catch(Exception e){ //捕获异常 e就是要捕获的异常

  • 对当前异常的处理

  • }finally{

  • //必须执行的代码:主要用于资源的释放:比如关闭数据库,关闭流,关闭锁等

  • }

  • 这个结构跟异常没有关系

  • try{

  • 获取资源

  • }finally{

  • 释放资源

  • }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值