Java 内部类和异常类

1,321 阅读5分钟

内部类

定义: Java支持在一个类中定义另一个类,这样的类称为内部类,而包含内部类的类称为内部类的外嵌类。

内部类和外嵌类的关系:

  1. 内部类的外嵌类的成员变量在内部类中仍然有效

  2. 内部类中的方法也可以调用外嵌类中的方法

  3. 内部类的类体中不可以声明类变量和类方法 static

  4. 外嵌类的类体中可以用内部类声明对象,作为外嵌类的成员

  5. 内部类仅供它的外嵌类使用,其他类不可以使用

  • 内部类对应的字节码文件的名字格式是 “外嵌类名$内部类名”
  • 内部类可以被修饰为static内部类,非内部类不可以是 static 类。
  • static 内部类不能操作外嵌类中的实例成员变量。

匿名类

1. 和子类有关的匿名类

假设没有显式地声明一个类的子类,而又想用·子类创建一个对象,那么该如何实现这一目的呢?

class A{
	void f(){}
}
//正常情况
class B extends A{
	void f(){}
}
B b = new B();
//匿名类
A a = new A(){
	void f(){}  //匿名类的类体
};
b.f();

Java允许我们直接使用一个类的子类的类体创建一个子类对象(这里等同于构造方法)

解释:创建子类对象时,除了使用父类的构造方法外,还可以使用类体,此类体被认为是一个子类去 掉类声明后的类体,称作匿名类。

特点:

  1. 可以继承父类的方法也可以重写父类的方法。
  2. 使用匿名类时,必然是在某个类中直接用匿名类创建对象,因此匿名类一定是内部类。
  3. 匿名类可以访问外嵌类中的成员变量和方法。
  4. 匿名类的类体中不可以声明 static 变量和 static 方法。
  5. 匿名类创建对象时,直接使用父类的构造方法。

2.和接口有关的匿名类

假如没有显式地定义一个实现接口类,而又想实现该接口的类创建一个对象,那么该如何实现这一目的呢?

Com   //假设这是一个接口
Com com = new Com(){
      //用实现接口的匿名类来创建对象,必须重写接口中的方法
}
								//new 接口() {实现接口的匿名类的类体};

异常类

所谓异常就是程序运行时可能出现的一些错误。

​ 比如试图打开一个根本不存在的文件等,异常处理将会改变程序的控制流程,让程序有机会对错误做出处理。

Java使用throw关键字抛出一个Exception子类的实例表示异常发生

  1. try-catch语句

  • try {

    ...可能出现异常的代码

    }

    catch(异常类名 异常变量名){

    ...出现异常后解决问题的代码

    }

  • try {

    ...可能出现异常的代码

    }

    catch(异常类名1 异常变量名1){

    ...出现异常后解决问题的代码

    }

    catch(异常类名2 异常变量名2){

    ...出现异常后解决问题的代码

    }...

  • try {

    ...可能出现异常的代码

    } catch(异常类名1|异常类名2 异常变量名1){

    ...出现异常后解决问题的代码

    }

  • try {

    ...可能出现异常的代码

    } catch(异常类名 异常变量名){

    ...出现异常后解决问题的代码

    }

    finally{ 有没有异常出现,都要执行的代码 释放资源 }

  1. 自定义异常类

    一个方法在声明时可以使用throws关键字声明要产生的若干个异常,并在该方法的方法体中具体给出产生异常的操作,即用相应的异常类创建对象,并使用throw关键字抛出该异常对象,导致该方法结束执行。程序必须在try-catch块语句中调用可能发生异常的方法,其中catch的作用就是捕获throw关键字抛出的异常对象。

throws:一个方法在声明时可以使用throws关键字声明要产生的若干个异常。

throw:throw关键字抛出该异常对象。

BankException.java

public class BankException extends Exception{
    String message;
    public BankException(int m,int n){
        message = "入账资金"+"是负数或支出"+n+"是正数,不符合系统要求。";
    }
    public String warnMess(){
        return message;
    }
}

Bank.java

public class Bank{
    private int money;
    public void income (int in,int out) throws BankException{
        if(in<=0||out>=0||in+out<=0){
            throw new BankException(in,out);//方法抛出异常,导致方法结束
        }
        int netIncome = in + out;
        System.out.printIn("本次计算出的纯收入是:%d元\n",netIncome);
        money = money  + netIncome;
    }
    public int getMoney(){
        return monney;
    }
}

Demo.java

public class Demo{
    public static void main(String args[]){
        Bank bank = new Bank();
        try{
            bank.income(200,-100);
            bank.income(300,-100);
            bank.income(400,-100);
            System.out.printIn("银行目前有%d元\n",bank.getMoney());
            bank.income(200,100);
            bank.income(99999,-100);
        }
        catch(BankException e){
            System.out.printIn("计算收益的过程出现如下问题:");
            System.out.printIn(e.warnMess());
        }
        System.out.printIn("银行目前有%d元\n",bank.getMoney());
    }
}

断言

assert booleanException:messageException:

booleanException的值是true时,程序从断言语句处继续执行:值是false时,程序从断言语句除停止执行,并输出messageException表达式的值,提示用户出现了怎样的问题。

断言语句在调试代码阶段非常有用,断言语句一般用于程序不准备通过捕获异常来处理错误。

例如,当发生某个错误时,要求程序必须立即停止执行。在调试代码阶段让断言语句发挥作用,这样就可以发现一些致命的错误,当程序正式运行时就可以关闭断言语句,但仍把断言语句保留在源代码中,如果以后应用程序又需要调试,可以重新启用断言语句。

-ea启用断言语句:

java -ea MainClass