java基础十
内部类
1 概述
1、什么是内部类?
在一个A类里面在定义一个B类 则A类为外部类 B类为内部类
2、为什么要声明内部类呢?
遵循高内聚低耦合的面向对象开发总原则。便于代码维护和扩展
换句话来说就是在一个项目中其中一个功能受损 但不会影响其他的功能
3、内部类都有哪些形式?
1.成员内部类:
-
静态成员内部类
-
非静态成员内部类
2.局部内部类
-
有名字的局部内部类
-
匿名的内部类
2 成员内部类
如果成员内部类中不使用外部类的非静态成员,那么通常将内部类声明为静态内部类,否则声明为非静态内部类。
【修饰符】 class 外部类{
【其他修饰符】 【static】 class 内部类{
}
}
1.静态内部类
有static修饰的成员内部类叫做静态内部类 特点是
-
和其他类一样,他只是定义在外部类中的另外一个完整的类结构
-
可以继承自己想要的继承的父类,实现自己想要实现的父类接口们,和外部类的父类和父接口无关
-
可以在静态内部类中声明属性,方法,构造器等结构,包括静态成员
-
可以使用abstract修饰,因此它也可以被其他类继承
-
可以使用final修饰表示不能被继承
-
编译后有自己的独立字节码文件,只不过在内部类名前面冠以外部类名和$符号
-
和外部类不同的是,它可以允许四种权限修饰符:public,protected,缺省,private
-
外部类只允许public或缺省的
-
-
只可以在静态内部类中使用外部类的静态成员
-
在静态内部类中不能使用外部类的非静态成员哦
-
如果在内部类中有变量与外部类的静态成员变量同名,可以使用“外部类名."进行区别
-
-
在外部类的外面不需要通过外部类的对象就可以创建静态内部类的对象(通常应该避免这样使用)
2、非静态成员内部类
没有static修饰的成员内部类叫做非静态内部类。非静态内部类的特点:
-
和其他类一样,它只是定义在外部类中的另一个完整的类结构
-
可以继承自己的想要继承的父类,实现自己想要实现的父接口们,和外部类的父类和父接口无关
-
可以在非静态内部类中声明属性、方法、构造器等结构,但是不允许声明静态成员,但是可以继承父类的静态成员,而且可以声明静态常量。
-
可以使用abstract修饰,因此它也可以被其他类继承
-
可以使用final修饰,表示不能被继承
-
编译后有自己的独立的字节码文件,只不过在内部类名前面冠以外部类名和$符号。
-
-
和外部类不同的是,它可以允许四种权限修饰符:public,protected,缺省,private
-
外部类只允许public或缺省的
-
-
还可以在非静态内部类中使用外部类的所有成员,哪怕是私有的
-
在外部类的静态成员中不可以使用非静态内部类哦
-
就如同静态方法中不能访问本类的非静态成员变量和非静态方法一样
-
-
在外部类的外面必须通过外部类的对象才能创建非静态内部类的对象(通常应该避免这样使用)
-
如果要在外部类的外面使用非静态内部类的对象,通常在外部类中提供一个方法来返回这个非静态内部类的对象比较合适
-
因此在非静态内部类的方法中有两个this对象,一个是外部类的this对象,一个是内部类的this对象
-
4 局部内部类
1、局部内部类
格式:
【修饰符】 class 外部类{
【修饰符】 返回值类型 方法名(【形参列表】){
【final/abstract】 class 内部类{
}
}
}
特点:
-
和外部类一样,它只是定义在外部类的某个方法中的另一个完整的类结构
-
可以继承自己的想要继承的父类,实现自己想要实现的父接口们,和外部类的父类和父接口无关
-
可以在局部内部类中声明属性、方法、构造器等结构,但不包括静态成员,除非是从父类继承的或静态常量
-
可以使用abstract修饰,因此它也可以被同一个方法的在它后面的其他内部类继承
-
可以使用final修饰,表示不能被继承
-
编译后有自己的独立的字节码文件,只不过在内部类名前面冠以外部类名、$符号、编号。
-
这里有编号是因为同一个外部类中,不同的方法中存在相同名称的局部内部类
-
-
-
和成员内部类不同的是,它前面不能有权限修饰符等
-
局部内部类如同局部变量一样,有作用域
-
局部内部类中是否能访问外部类的非静态的成员,取决于所在的方法
-
局部内部类中还可以使用所在方法的局部常量,即用final声明的局部变量
-
JDK1.8之后,如果某个局部变量在局部内部类中被使用了,自动加final
-
为什么在局部内部类中使用外部类方法的局部变量要加final呢?考虑生命周期问题。
-
2、匿名内部类
当我们在开发过程中,需要用到一个抽象类的子类的对象或一个接口的实现类的对象,而且只创建一个对象,而且逻辑代码也不复杂。那么我们原先怎么做的呢?
(1)编写类,继承这个父类或实现这个接口
(2)重写父类或父接口的方法
(3)创建这个子类或实现类的对象
这里,因为考虑到这个子类或实现类是一次性的,那么我们“费尽心机”的给它取名字,就显得多余。那么我们完全可以使用匿名内部类的方式来实现,避免给类命名的问题。
匿名内部类是没有名字的类,因此在声明类的同时就创建好了唯一的对象
注意:
匿名内部类是一种特殊的局部内部类,只不过没有名称而已。所有局部内部类的限制都适用于匿名内部类。例如:
-
在匿名内部类中是否可以使用外部类的非静态成员变量,看所在方法是否静态
-
在匿名内部类中如果需要访问当前方法的局部变量,该局部变量需要加final
7注解
注解是以“@注释名”在代码中存在的,还可以添加一些参数值
虽然说注解也是一种注释,因为它们都不会改变程序原有的逻辑,只是对程序增加了某些注释性信息。不过它又不同于单行注释和多行注释,对于单行注释和多行注释是给程序员看的,而注解是可以被编译器或其他程序读取的一种注释,程序还可以根据注解的不同,做出相应的处理。所以注解是插入到代码中以便有工具可以对它们进行处理的标签。
2 三个最基本的注解
1、@Override
用于检测被标记的方法为有效的重写方法,如果不是,则报编译错误!
只能标记在方法上。
它会被编译器程序读取。
2、@Deprecated
用于表示被标记的数据已经过时,不建议使用。
可以用于修饰 属性、方法、构造、类、包、局部变量、参数。
它会被编译器程序读取。
3、@SuppressWarnings
抑制编译警告。
可以用于修饰类、属性、方法、构造、局部变量、参数
它会被编译器程序读取。
异常
1异常概述
1认识Java的异常
1,什么是异常
指的是程序在执行过程中,出现的非正常的情况,如果不处理最终会导致JVM的非正常停止。
异常指的并不是语法错误,语法错了,编译不通过,不会产生字节码文件,根本不能运行.
异常也不是指逻辑代码错误而没有得到想要的结果,例如:求a与b的和,你写成了a-b
2Java异常体系
1.Throwable
是Java所有异常或错误的超类(父类)
2.Error和Exception
-
Error:表示严重错误,一旦发生必须停下来查看问题并解决问题才能继续,无法仅仅通过try...catch解决的错误。
-
Exception:表示普通异常,其它因编程错误或偶然的外在因素导致的一般性问题,程序员可以通过代码的方式检测、提示和纠正,使程序继续运行,但是只要发生也是必须处理,否则程序也会挂掉。
无论是Error还是Exception,还有很多子类,异常的类型非常丰富。当代码运行出现异常时,特别是我们不熟悉的异常时,不要紧张,把异常的简单类名,拷贝到API中去查去认识它即可。
3受检异常和非受检异常
我们平常说的异常就是指Exception,根据代码的编写编译阶段,编译器是否会警示当前代码可能发生xx异常,并督促程序员提前编写处理它的代码为依据,可以将异常分为:
-
编译时期异常(即checked异常、受检异常):在代码编译阶段,编译器就能明确警示当前代码可能发生(不是一定发生)xx异常,并督促程序员提前编写处理它的代码
-
运行时期异常(即runtime异常、unchecked非受检异常):即在代码编译阶段,编译器完全不做任何检查,无论该异常是否会发生,编译器都不给出任何提示。只有等代码运行起来并确实发生了xx异常,它才能被发现
2异常的处理
Java异常处理的五个关键字:try、catch、finally、throw、throws
1 捕获异常:try…catch
1.try...catch基本格式
捕获异常语法如下:
try{
可能发生xx异常的代码
}catch(异常类型1 e){
处理异常的代码1
}catch(异常类型2 e){
处理异常的代码2
}
....
-
如果在程序运行时,try块中的代码没有发生异常,那么catch所有的分支都不执行。
-
如果在程序运行时,try块中的代码发生了异常,根据异常对象的类型,将从上到下选择第一个匹配的catch分支执行。此时try中发生异常的语句下面的代码将不执行,而整个try...catch之后的代码可以继续运行。
-
如果在程序运行时,try块中的代码发生了异常,但是所有catch分支都无法匹配(捕获)这个异常,那么JVM将会终止当前方法的执行,并把异常对象“抛”给调用者。如果调用者不处理,程序就挂了。
try{
可能发生xx异常的代码
}catch(Throwable e){
处理异常的代码
}
-
程序执行时,try块中代码没有异常,那么catch的异常超类(Throwable)不会执行
-
如果程序执行时,try块中的代码发生了异常,则根据异常类对象类型在超类(Trowable)中查找异常信息并反馈到控制台
2 finally块
1、finally块
try{
}catch(...){
}finally{
无论try中是否发生异常,也无论catch是否捕获异常,也不管try和catch中是否有return语句,都一定会执行
}
注意:finally不能单独使用。
3 转换异常处理位置:throws
如果在编写方法体的代码时,某句代码可能发生某个==编译时异常==,不处理编译不通过,但是在当前方法体中可能不适合处理或无法给出合理的处理方式,就可以通过throws在方法签名中声明该方法可能会发生xx异常,需要调用者处理。
修饰符 返回值类型 方法名(参数) throws 异常类名1,异常类名2…{ }
在throws后面可以写多个异常类型,用逗号隔开。
或者 手动抛出异常对象
try{
可能发生xx异常的代码
}catch (Throwable e) {
e.printStackTrace();
//反馈异常信息类型
}
修饰符 返回值类型 方法名(参数) throws Throwable{
}
3 自定义异常
为什么需要自定义异常类:
我们说了Java中不同的异常类,分别表示着某一种具体的异常情况,那么在开发中总是有些异常情况是核心类库中没有定义好的,此时我们需要根据自己业务的异常情况来定义异常类
异常类如何定义:
自定义一个编译时异常类型:自定义类 并继承
java.lang.Exception。
注意自定义的异常只能通过throw抛出。
自定义异常:
(1)要继承一个异常类型
(2)建议大家提供至少两个构造器,一个是无参构造,一个是(String message)构造器
(3)自定义异常对象只能手动抛出。抛出后由try..catch处理,也可以甩锅throws给调用者处理。
public class AgeException extends Throwable{
public AgeException() {
//无参构造
}
public AgeException(String message) { super(message);
//有参构造
}
}
实例化
try {
age(10);
} catch (AgeException e) { e.printStackTrace();
}
}
public static void age(int x) throws AgeException{ if(x<=12 || x>=86){
throw new AgeException("这b玩意是个变态!"); }else {
System.out.println("这老登要看" + x + "岁美女"); }
}
更多推荐




所有评论(0)