一 内部类
1),内部类可以直接访问外部类的成员,包括私有的
若内部类将外部类成员变量覆盖,要访问外部类成员变量 采用格式 :外部类名.this.成员变量
2),外部类要访问内部类的成员必须创建内部类对象
3),内部类的权限可以是private 默认,protected public ,外部类只能是public 默认4), 内部类能被static 修饰,外部类不可以
5), 内部类和外部类都可以的final 和 abstract 的6), 内部类可以继承其他类和实现其他接口
内部类根据其定义的位置分为成员内部类,局部内部类,匿名内部类
不能位置的内部类能够使用的修饰符和访问范围也各不相同
-
内部类的意义:
- -->通过修饰符protected和private来控制访问级别,将一个类中的内部某部分的实现细节隐藏,体现了java封装性
- -->内部类对象可以访问创建它的外部类对象的内容,包括私有成员!
- -->每个内部类都能独立地继承一个接口,而无论外围类是否已经继承了某个接口。
因此,内部类使多重继承的解决方案变得更加完整。集合中的Map.Entry也是内部类的应用
- -->通过修饰符protected和private来控制访问级别,将一个类中的内部某部分的实现细节隐藏,体现了java封装性
-
成员内部类的修饰符及访问方式:
1 , 当内部类定义的外部类成员位置上,而且非私有,可以在外部其他类中直接建立内部类对象
格式:
外部类.内部类 引用变量 = new 外部类().new 内部类();内部类具有指向外部类的引用,所以能够访问外部类的成员包括私有的
2, 当内部类定义在成员的位置上被成员修饰符所修饰
比如private 将内部类在外部类中进行封装 除了它的外部类以外其他类中都无法访问。
通过这种方式可以完全阻止任何依赖于类型的编码,并完全隐藏实现的细节。
static 修饰内部类 内部类就具备static的特性 也叫静态内部类或嵌套类或静态成员类, 静态内部类中只能直接访问外部类中的static成员,静态内部类没有了指向外部的引用,出现了访问局限,静态
的内部类对象不依赖于外部类对象
静态内部类中可以有static字段与静态内部类,静态内部类中的也可以有非静态的成员
非静态内部类不允许定义静态成员
内部类其他修饰符:
public, friendly ,protected,
也可以将内部类声明为: abstract 和 final
(a) 在外部的其他类中如何直接访问static内部类非静态成员?
new Outer.Inner().function();通过该方式可以访问到静态的和非静态的成员
(b) 在外部类其他类中,如何直接访问static内部类的静态成员?
Outer.Inner.function();通过该方式只能访问到静态成员
注意:
当内部类中定义了静态成员,该内部类必须是static的
当外部类中的静态方法访问内部类时,内部类也必须是static的,静态只能访问静态 ,非静态可以访问静态也可以访问非静态
1)局部内部类不能被静态修饰,因为static是成员修饰符,所以局部内部类中不可能有静态成员。3) 局部内部类权限只能是默认的,不能是public 或 protected 或 private
4) 局部内部类可以被final 和 abstract修饰
5)局部内部类可以直接访问外部类中的成员,因为还持有外部类中的引用,但不可以
访问它所在的方法的局部变量,只能访问被final修饰的局部变量因为这样可以使变量不再是局部而是全局化
6) 局部内部类只能在所定义的外部类的方法中创建对象 , 不能在其外部类或外部类以外的其他类创建对象7) 局部内部类的生命周期跟其所在的外部类方法一样,局部内部类跟方法一样随着外部类的加载而加载,但其中的成员
变量跟其所在的外部类方法中的局部变量一样在使用到的时候才分配到内存空间,随着方法的调用结束而释放内存
- 一个匿名内部类一定是在new的后面,用其隐含实现一个接口或继承一个类以便得到一个实例,没有类名,格式
new 接口\抽象类(){匿名内部类类体}
- 匿名内部类是唯一一种无构造方法类(可以添加匿名构造方法)。
- 匿名类用于继承一个类或是实现接口并得到一个实例, 可以跟普通的实现接口和普通的继承类一样, 可以对继承方法的实现或覆盖,也可以添加新的成员。
- 匿名内部类不能定义任何静态成员、方法和类。
- 匿名内部类不能被权限修饰符public,protected,private 和 static 修饰。
- 只能创建匿名内部类的一个实例。
- 一个匿名内部类一定是在new的后面,用其隐含实现一个接口或继承一个类。
- 因匿名内部类为局部内部类,所以跟局部内部类的一样的限制
- 匿名内部类适用于类在定义后马上用到,如:
- 只是为了获得一个继承来的类的对象或获得一个接口的实现类实例
- 只是想调用一次一个接口的实现类的一个方法或调用一次继承来的类的一个方法
- 只是想作为方法的实际参数
- 类非常小(SUN推荐是在4行代码以下)
- 定义匿名内部类的前提:内部类必须是且只能继承一个类或者实现了一个接口
二 异常
程序运行时出现的不正常情况 ,如:想打开的文件不存在、网络连接中断、操作数超出预定范围、正在装载的类文件丢失
表达式的计算违反了Java语言的语义 内存溢出等需要阻止当前方法或作用域继续执行 , java中有异常处理机制
异常处理机制,就是要告诉开发人员,你的程序出现了不正常的情况,请注意。
java中所有的异常都由类来表示,所有的异常类都从一个名为Throwable的类派生类出来的。
Throwable 类是 Java 语言中所有错误或异常的超类。只有当对象是此类(或其子类之一)的实例时,才能通过 Java 虚拟机或者 Java
throw
语句抛出。当发生一个异常时,就会生成 一个Throwable类或其子类的对象。
1)对于一般的问题通过Excepttion描述
程序运行所导致的错误由Exception类来表示,该异常类定义了程序中可能遇到的轻微的错误条件。可以编写代码处理异
常并继续执行程序,而不是让程序中断。它代表轻微的故障,可以恢复的故障,接收到异常信号后,调用方法捕获抛出的异
常,在可能时,再恢复回来。这类异常一般由程序员来处理。
2)对于严重的问题通过error描述
error类型的异常相关的错误发生在Java虚拟机中,而不是在程序中。Error类定义了被认为是不能恢复的严重错误。在大多数
情况下,当遇到这样的错误时,建议让该程序中断。这样的异常超出了程序可控制的范围,因此,程序员一般不处理这类异常。
- 异常的特殊子类异常:运行时异常 RuntimeException
- Exception分两种:
1,编译时被检测到的异常
函数内抛出编译时异常,函数上必须声明;函数上声明编译时异常,调用者必须处理(继续往外抛或try...catch处理).
抛出去或try{}catch(){}, 否则编译失败。该异常被标识,代表这可以被处理。
2,编译时不能被检测到的异常(运行时异常,RuntimeException及其子类)
不用声明的;声明了也不用处理。
- RuntimeException 特点:不抛不处理
(1)如果在函数内抛出 RuntimeException 异常(含子类异常),函数上可以不用声明,编译一样通过。
(2)如果在函数上声明了 RuntimeException 异常(含子类异常),调用者可以不处理,编译一样通过。
对于函数内抛出非 RuntimeException 异常函数上必须做声明
(3)之所以不用在函数上声明,是因为不需要让调用者处理,只希望程序停止,因为运行时出现了无法
继续进行的情况,必须对代码修正才行,Java运行系统能自动抛出,处理, 所以调用者可以不抛不处理
- 常见的RuntimeException异常:
ArithmeticException :算术运算异常
IndexOutOfBoundsException:角标越界异常
|--ArrayIndexOutOfBoundsException: 数组角标越界异常
|_StringIndexOutOfBoundsException:字符串角标越界异常
ClassCastException:类型转换异常
NullPointerException :空指针异常
SecurityException:安全侵犯异常
自定义异常时,如果该异常的发生,无法再继续进行运算,就让自定义异常继承RuntimeException
java在运行时环境发生异常而产生异常对象时,会寻找处理该异常的catch块,如果找到则将该异常对象交给catch块进行处理
这个过程就捕获异常,如果java运行时环境找不到异常的catch块则运行时环境终止,java程序退出
程序中,把需要被检查的代码段放在一个以关键字try开头的代码块中。try代码块如果有异常发生就会抛出该异常。若有异常抛出则用catch捕获这个异常,并在catch的语句中加以适当的处理或者可以使用关键字throw手动抛出自定义异常。
而从一个方法抛出异常必须用throws。异常可能导致一个终止当前方法的错误,造成其方法返回。finally语句块在退出
try/catch异常处理代码块时执行 ,可以将退出时必须的操作可放在finally代码块中。
所以finally语句块是一定会执行的无论是否有异常发生 , 除非在try catch中用exit()函数终止程序
- 异常处理语句:
try
{
需要被检测的代码;
}
catch (异常类型)
{
处理异常的代码;
}
finally
{
一定会执行的代码(除非在其他地方调用了exit());//用于关闭释放资源
}
- 异常处理语句的三种格式
第一个格式:try{}catch (){}
第二个格式:try{}catch (){}finally{}
第三个格式:try{}finally{}catch必须配合try使用,finally也必须配合try使用
- catch
catch是用于捕获异常catch块处理异常。如果没有catch就代表异常没有被处理过,
如果该异常是编译检测时异常。那么必须声明。catch中异常信息输出:
catch(Exception e)
e.getMessage(); //返回throwable的详细的字符串。
e.toString(); //返回异常对象名称及异常信息简述
e.printStackTrace();//返回追踪到的异常位置信息
1,声明异常时,建议声明更具体的异常,使处理可以更具体2,对方声明几个异常,就对应有几个catch块,不要定义多余的catch块
3, 如果多个catch块中的异常出现继承关系,父类异常catch块放在最下面
4, catch处理时。catch一定要定义具体处理方式
不要简单定义异常信息的提示语句 e.printStackTrace()
也不要简单的就一条输出语句