目录
包和导入
关键字:package、import
包的概念:包的本质就是文件夹,是对项目中的类进行管理的。在代码中,用package明确当前类所在的包。
注:package必须出现在类的第一行
导入的概念:导入是指在一个类中,使用其他类,需要先将其他包中的类引入到本类中。
注:
- 只有其他包中的类需要导入,同包中的类无需导入
- java.lang包(即language语言包中的类)在使用时会自动导入,无须手动导入。
- 可以使用
*通配符,来表示按需导入
包的命名:一般都是域名倒着写
规范:
- 全小写
- 多个单词简用.分隔
权限(范围)修饰符
概念:权限修饰符是用于设置成员对其他类的可见性的,
public>protected>[default]>private
| 权限修饰符 | public | protected | default | private |
|---|---|---|---|---|
| 本类 | √ | √ | √ | √ |
| 本包 | √ | √ | √ | × |
| 其他包的子类 | √ | √ | × | × |
| 其他无关类 | √ | × | × | × |
怎么用?
- public:工具类中的静态常量、方法
- protected:让子类可以任意访问成员的时候
-
[default]:一般包用于进行模块的划分,如果一个成员只与改模块有关,其他包(模块)没有访问它的必要和意义,那么就可以把该成员设成[default]。 - private:属性的封装,父类的独有方法。
总结:public都能用。protected、default只有同包能用,另外protected可让类在其他包也能用。private只有本包。
单例设计模式 Sinleton
设计模式:套路、模板。
单例设立模式:是指在当前工程中的某个类的对象在内存中只有一份,不能有多个对象。
优点目的:
- 节省资源
- 全局共享数据的统一管理
使用场景:工具类,统计访问资源。
代码编写的步骤:
- 构造函数私有化,防止其他类创建本类对象。
- 在本类中创建本类对象。
- 对外提供获取本类对象的方法
饿汉式
//1.私有化构造器
private Tools1(){}
//2.创建本类对象
public static Tools1 t = new Tools1();
//3.对外提供访问本类对象的方法
public static Tools1 getInstance(){
return t;
}
缺点:即使没有调用getInstance方法,也进行了对象的创建
懒汉式
//1.私有化构造器
private Tools2(){}
//2.1定义本类对象
public static Tools2 t = null;
//3.对外提供访问本类对象的方法
public static Tools2 getInstance(){
if(t == null){
t = new Tools2();
}
return t;
}
缺点:不能保证线程安全,存在隐患
线程安全的懒汉式
//1.私有化构造器
private Tools2(){}
//2.1定义本类对象
public static Tools2 t = null;
//3.对外提供访问本类对象的方法
public static Tools2 getInstance(){
synchronized(Tools2.class){
if(t == null){
t = new Tools2();
}
}
return t;
}
异常
Throwable下有两个子类
- Exception:异常类
它指示出了合理的应用程序想要捕获的条件。 - Error:错误类
它用于指示合理的应用程序不应该试图捕获的严重问题。
当发生异常时,jvm会根据异常的类型自动创建该类对象,并通过该类的print方法,将错误信息,以标准错误流打印到控制台上。
一旦异常发生了,要么使用抛出的方式抛给调用者让调用者处理,要么使用捕获的方式对异常进行捕获,否则该异常会由jvm接收并结束程序。
发生异常后,异常后面的代码是不会再执行的,同时也说明异常不会同时发生两个。jvm中调用异常单显示是一个单独的线程。
常见的异常:
- ClassNotFoundException
- IOException
- ArithmeticException
- ClassCastException
- NoSuchElementException
- NullPointerException
- ArrayIndexOutOfBoundsException
- StringIndexOutOfBoundsException
运行时异常
关于RuntimeException:
可以选择手动抛出或者捕获,如果抛出,那么异常就由JVM来接收,当JVM遇到异常时,会进行中断处理。
如果捕获,那么异常就会由相应的catch代码段进行处理,那么JVM就不会接收到异常。
也可以选择不处理,但是当异常发生时,就会由JVM来接收并进行中断处理。
关于非RuntimeException:
必须进行处理,可以选择抛出或者捕获。
运行时异常和非运行时异常
运行时异常都是RuntimeException类及其子类异常,如NullPointerException、IndexOutOfBoundsException等,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。
当出现RuntimeException的时候,我们可以不处理。当出现这样的异常时,总是由虚拟机接管。比如:我们从来没有人去处理过NullPointerException异常,它就是运行时异常,并且这种异常还是最常见的异常之一。
出现运行时异常后,如果没有捕获处理这个异常(即没有catch),系统会把异常一直往上层抛,一直到最上层,如果是多线程就由Thread.run()抛出,如果是单线程就被main()抛出。抛出之后,如果是线程,这个线程也就退出了。如果是主程序抛出的异常,那么这整个程序也就退出了。运行时异常是Exception的子类,也有一般异常的特点,是可以被catch块处理的。只不过往往我们不对他处理罢了。也就是说,你如果不对运行时异常进行处理,那么出现运行时异常之后,要么是线程中止,要么是主程序终止。
如果不想终止,则必须捕获所有的运行时异常,决不让这个处理线程退出。队列里面出现异常数据了,正常的处理应该是把异常数据舍弃,然后记录日志。不应该由于异常数据而影响下面对正常数据的处理。非运行时异常是RuntimeException以外的异常,类型上都属于Exception类及其子类。如IOException、SQLException等以及用户自定义的Exception异常。对于这种异常,JAVA编译器强制要求我们必需对出现的这些异常进行catch并处理,否则程序就不能编译通过。所以,面对这种异常不管我们是否愿意,只能自己去写一大堆catch块去处理可能的异常。
为什么Java能够容忍运行时异常,大于容忍非运行时异常?
因为运行时异常是逻辑错误,所以逻辑错误是检查不出来的,要运行时才能发现。要运行时终止。
小冤家
- Scanner遇到异常就会出现bug,这时候异常会一直拿着原来的输入不释放,无法继续nextInt系列的输入。这时候只能进行new Scanner进行重新的常见对象。
- new Scanner放入循环几乎就释放不了了。
异常的处理
1. try-catch
格式:
try{
需要异常检测的代码(可能发生异常的代码)
}
catch(异常类 变量){
一旦try中的某条语句发生了异常,
就会立即创建该异常类的对象,
并进入catch代码段进行处理。
}
...
catch(异常类 变量){
}
finally{
一定会执行的代码
}
异常捕获的处理方式:
1、多个异常,一次处理
不明确或者无须明确异常的种类,可以直接由Exception进行捕获。
2、多个异常,分别处理
当可以预见try中可能发生何种异常时,由多个对应的Exception的子类进行单独的处理。
好处是可以明确异常种类,有目的对异常进行处理。
这个做法一般最后会使用Exception来处理没有考虑到的异常情况。
多个异常:(存在父级关系)必须将范围大的(父级)放到后面,保证前面的代码也能执行到
3、一个异常,多次处理
关于finally:
finally中的代码一定会执行,一般用于资源的释放,
在释放资源方法被调用前,一般会资源的空指针进行判断。
注:有返回类型的方法,如果finally中有返回值,那么返回的结果一定是finally中的结果。因此不要在finally中返回结果。
2. throws
概念:
throws表示当方法中发生异常时,本方法不做异常处理,而是将异常抛出给调用者,让调用者处理。
调用者可以使用try-catch进行捕获或者继续使用throws抛出。
注:
1、throws用在方法声明(定义)上
2、throws后必须跟上Exception或它的子类
3、如果抛出的是RuntimeException及其子类,那么调用者可以不进行处理,当发生异常时,程序终止。
4、如果抛出的不是RuntimeException及其子类,那么调用者必须对异常进行处理,继续抛出或者捕获。
3 throw
概念:
当方法中发生异常时,在语句中使用throw抛出一个异常对象给调用者,调用者可以使用try-catch进行捕获或者继续抛出。
注:
1、throw是方法中的语句
2、throw抛出的是异常对象
3、可以在抛出异常对象时,传入自定义的异常信息
4、如果抛出的是RuntimeException及其子类,那么调用者可以不进行处理,当发生异常时,程序终止。
5、如果抛出的不是RuntimeException及其子类,那么调用者必须对异常进行处理,继续抛出或者捕获。
异常的方法
1、toString():提示异常类和错误原因
2、getMessage():提示错误原因
3、printStackTrace():提示异常类、错误原因、错误位置
继承关系中的异常
- 父类方法抛出异常,子类重写可以不抛出异常或者抛出和父类相同的异常或者抛出父类异常的子类。(这就是要求子类要越来越细化,也可以理解为子类的捕获范围比父类大,那父类捕获个屁)
- 如果父类没有抛出异常的话子类也不能抛出,如果子类的确有异常只能针对运行时异常进行抛出或捕获。RunTimeException,ArrayIndexOutException,Exception。
- 子类重写可以抛出任意的运行时异常RunTimeException及其子类。
- 当抛出的是运行时异常时不必遵守第一条要求子类重写方法的范围小于等于父类
- 抛出异常时不再乎子父类异常的顺序问题,大的在前小的在后也行,不同于try/catch。
自定义异常
概念:根据程序的特殊要求,将某些特殊情况视为异常,自定义这个异常类来对异常信息进行获取和明确。
步骤:
- 创建自定义类继承Exception
- 写出空参构造函数和重载带有String的构造函数