一、接口
1. 什么是接口:接口是让没有继承关系的类也能共享行为的一种机制,它是对java单继承的一种补充,弥补了java单继承丰富度低的缺陷。
2. 接口声明: public interface 接口名 {
public abstract 返回值类型 方法名;......}
接口中的方法只能是public抽象的,接口中的属性只能是public static final的。1.8版本之后,接口中方法可以写具体实现语句。
3. 接口的实现:通过implements关键字接在类名后,如:public class 类名 implements 接口名{}
4. 接口的特点:a. 除了抽象类以外,凡是应用了接口的类中都必须重写接口中的所有抽象方法。b. 接口的引用只能看到定义在接口中的方法和属性。c. 一个类可以实现多个接口,接口名用逗号隔开。d. 与生俱来的方法一般都写在类中,接口中一般都写附属添加的共同行为。
5. 接口实现原则:a. 接口最小化原则。b. 解决多继承问题。 c. 为外部类添加功能。
6. 接口的优点: a. 将设计与实现分离,对外部隐藏了实现。b. 面向接口的编程是OOP的核心。
二、异常处理
1. 什么是异常:异常(Exception)是程序执行时所产生的问题,异常不是错误(Error),任何软件都会有异常。错误往往是硬件上出了问题所产生的,而异常往往是由于程序编写的问题而产生的,它是可以通过修改程序来解决的,异常分为编译时异常与运行时异常。
2. 每当程序执行过程中产生错误或异常时,JVM都会自动生成一个异常或者错误对象,他们分别由Exception类和Error类产生,这两个类都是Throwable类的直接子类。
3. 异常分析:a. Exception in Thread “main” 表示在哪个线程出现的异常(这里是main方法中)b. java.util.InputMismatchException 这是异常类全名,见名知意可以看出它是什么异常(这里是输入不匹配异常)c. at java.util.Scanner.throw For(Scanner.java.909).......这里可能有很多行at...表示在哪个类程序中的哪一行产生的(这里是909行),一般从上往下数到第一个自己写的类那里找问题。
4. JVM异常处理机制:JVM会根据当前产生的异常生产一个异常对象,如果该方法没有将其捕获,JVM会结束该方法并将其抛出给方法调用者,如果调用者任没对其进行捕获,调用该方法的方法将被结束,并将异常抛出给下一个调用者,直到方法被捕获或者直到main方法被结束然后抛给JVM并导致JVM被强制关闭。
5. 结束方法有三种:运行完成;return语句;产生异常未处理被强制结束。
6. 异常处理:a. 捕获这个异常,不让它沿着调用栈继续抛。b. 捕获异常,并让他继续抛出。 c. 不捕获,从main方法弹出。
7. 捕获异常:try(让JVM试着执行)-catch(捕获异常)-finally(不管是否发生异常都会被执行,且在return前执行,主要写资源清理和关闭工作)语句块。三种用法:try-catch;try-finally;try-catch-finally。finally块只能放在最后,catch块中异常类型如果没有继承关系可随意排列顺序,如有继承关系则父类必须在子类后面。
8. 抛异常:a. throw:放在方法体中异常对象前,表示该方法到这一句时要抛出该异常,如:throw new Exception();b. throws:放在方法声明时方法名后,可写多个,告诉方法调用者可能会出现异常。方法中有throw就必须声明throws,但声明了throws不一定在方法体中写 throw异常。
9. 主动抛出异常有利于后续者对异常做出相应操作(如自定义异常)。
10. 自定义异常:a. 创建一个异常类并继承Exception类。b. 添加构造方法和普通方法。c. 在一个方法中抛出异常并在另一个方法中捕获并处理异常。例如:三层架构中,往往在持久层或业务层中捕获异常并抛出自定义异常,然后在表现层中统一处理该异常。自定义异常还常被用来记录log日志文件。
三、反射
1. 什么是反射:运行时探究和使用编译时未知的类。它是java动态性的最大体现,即在运行起来后再去绑定或改变编译期所要确认的效果。
2. 类加载机制:a. 类加载器将编译好的class文件读入内存后,JVM产生一个该类的java.lang.Class对象,该对象中记录了class文件中相应的信息(属性,方法,子类,父类,接口等)。从而,JVM才知道要划分多少空间给相应类的对象。b. 连接:把类的二进制数据合并到JRE中。c. JVM对类中static数据进行初始化。
3. 一个类对应的Class对象只有一个,他在类加载时就产生了。
4. 使用反射步骤:
a. 获取要操作的类的Class对象:方法1、对象名.getClass()方法(只能用于引用数据类型);方法2、数据类型.class(适用于所有数据类型,包括void);方法3、Class.forName(“全类名”),该方法动态性最高且不受访问修饰符限制。
b. 探究Class对象中类的信息:具体方法见jdk API, 主要常用方法有:getPackage()获取包对象;getName()获取类全名;getSimpleName()获取简单类名;getModifiers()获取修饰符编号;getSuperclass()获取父类Class对象;getInterface()获取接口Class对象;getFields()和getDeclaredFields()获取所有公共属性和所有属性;getField(“属性名”)和getDeclaredField(“属性名”)获取指定属性,要用try-catch捕获异常;获取构造和方法跟获取属性的方法类似,只需要将Field改为Constructor或者Method即可,其中某些方法传参时要注意,根据确定一个方法或者构造所需信息一致。
c. 使用反射获取的信息:1.根据反射产生对象:构造对象.newInstance(“实参”)或者 构造对象.newInstance(),分别调用带参和无参构造。2. 根据反射调用方法:方法对象.invoke(对象名,实参),如没有可用null。3. 根据反射操作属性:属性对象.set(对象名,实参)或者 属性对象.get(对象名)来设置和获取相应对象的属性值。
5. 何时使用反射:当类模板确定后,类名不确定;如搭建框架时。(特别是用在调数据库时)