目录
一、异常
1.什么是异常
1.异常是指程序运行中出现的不期而至的各种状况如:文件找不到、网络连接失败、非法参数、内存或硬盘满了、数据为空等等.
2.简单分类
检查型异常(CheckedException)
在Java中所有不是RuntimeException派生的Exception(此处不包含error)都是检查型异常。当函数中存在抛出检查型异常的操作时(即有代码可能会导致抛出检查型异常时),该函数的函数声明中必须包含throws语句。调用改函数的函数也必须对该异常进行处理,如不进行处理则必须在调用函数上声明throws语句。
检查型异常是JAVA首创的,在编译期对异常的处理有强制性的要求。在JDK代码中大量的异常属于检查型异常,包括IOException,SQLException等等。
非检查型异常(UncheckedException)
在Java中所有RuntimeException的派生类都是非检查型异常,与检查型异常对比,非检查型异常可以不在函数声明中添加throws语句,调用函数上也不需要强制处理。
常见的NullPointException,ClassCastException是常见的非检查型异常。非检查型异常可以不使用try...catch进行处理,但是如果有异常产生,则异常将由JVM进行处理。
对于RuntimeException的子类最好也使用异常处理机制。虽然RuntimeException的异常可以不使用try...catch进行处理,但是如果一旦发生异常,则肯定会导致程序中断执行,所以,为了保证程序再出错后依然可以执行,在开发代码时最好使用try...catch的异常处理机制进行处理。
摘自:https://www.cnblogs.com/xh_chiang/p/6850847.html
2.异常的体系结构
图可不清楚去这里看(java异常体系结构详解_Lily的专栏-CSDN博客_java异常体系结构图)
3.捕获和抛出异常
关键字: try、catch 、finally、throw、throws
package com.yves.oop;
public class ExceptionTest {
public static void main(String[] args) {
int a = 1;
int b = 0;
try{//监控区域
System.out.println(a/b);
}catch(ArithmeticException e){
//捕获分析异常部分
System.out.println("算术运算异常");
}finally {
System.out.println("无论是否发生异常都会执行部分");
}
}
}
结果:
算术运算异常
无论是否发生异常都会执行部分
还可以多级捕获异常(多个catch).,多级捕获时应该注意catch覆盖范围应该从小到大递增(最大程度便于分析异常)。
package com.yves.oop;
import java.io.IOException;
public class ExceptionTest {
public static void main(String[] args) {
try{//监控区域
new ExceptionTest().a(); //这里为栈溢出异常 Throwable->Error->StackOverflowError
}catch(RuntimeException e){
//捕获分析异常部分
System.out.println("运行时异常");
}catch (Exception e){
System.out.println("Exception异常");
}catch (Error e){
System.out.println("Error异常"); //应该在这里捕获
}catch (Throwable e){
System.out.println("Throwable异常");
}finally {
System.out.println("无论是否发生异常都会执行部分");
}
}
public void a(){
b();
}
public void b(){
a();
}
}
结果:
Error异常
无论是否发生异常都会执行部分
主动抛出异常:throw,throws
package com.yves.oop;
import java.io.IOException;
public class ExceptionTest {
//假设方法中处理不了这个异常,在方法上抛出异常 用throws
public void test(int a , int b) throws ArithmeticException{
// if(b==0){
// throw new ArithmeticException();//主动抛出异常 用throw
// }
//若有异常 且在方法内主动抛出异常后 抛出异常位置后的代码不会执行 返回方法调用方
//若有异常 且在方法上主动抛出异常后 会执行到抛出异常的那一行代码 返回方法调用方
System.out.println(a/b);
}
public static void main(String[] args) {
try{
new ExceptionTest().test(1,0);
}catch (Exception e){
System.out.println("算术错误");
//利用try catch捕获到异常后 若不结束 程序会继续向下执行 开发中这样不便于我们发现错误
//所以可以使用System.exit(1);结束程序
System.exit(1);
}
System.out.println("剩余代码部分");
}
}
二、枚举
枚举创建的两种方式:
自定义实现枚举;
使用enum关键字实现枚举;
1.自定义实现枚举
1.不提供set方法,因为枚举通常是只读的;
2.对枚举属性使用final+static共同修饰,实现底层优化(static final 属性在被调用的时候不会加载类)
3.枚举对象名通常全部大写
4.属性、构造器私有化;通过为对象添加 public static final 对外暴漏对象
5.通过enum实现枚举默认继承Enum父类 不可继承其他类,但是可以实现接口(实现方法中的接口即可)
代码验证: static + final 属性在被调用的时候不会加载类
package com.yves.enumPackage;
public class Season {
//利用 static final 修饰的属性被 类名.属性名 调用时不会加载类(静态代码块未执行,静态代码块在类加载时执行且仅执行一次)
public static final int AAA = 123;
static{
System.out.println("loading...");
}
}
package com.yves.enumPackage;
public class Application {
public static void main(String[] args) {
System.out.println(Season.AAA);
}
}
结果:
123
自定义枚举类实例:
package com.yves.enumPackage;
public class Season {
private String name;
private String desc;
public static final Season SPRING = new Season("春天","温暖");
public static final Season WINTER = new Season("冬天","寒冷");
public static final Season AUTUMN = new Season("秋天","凉爽");
public static final Season SUMMER = new Season("夏天","炎热");
//构造器私有化 (创建了有参构造器,那么默认的无参构造器想要使用必须显式定义)
private Season(String name,String desc){
this.name = name;
this.desc =desc;
}
//2.只保留get方法,保证属性不被修改
public String getName() {
return name;
}
public String getDesc() {
return desc;
}
@Override
public String toString() {
return "Season{" +
"name='" + name + '\'' +
", desc='" + desc + '\'' +
'}';
}
}
package com.yves.enumPackage;
public class Application {
public static void main(String[] args) {
System.out.println(Season.SPRING);
Season season = Season.AUTUMN;
System.out.println(season);
System.out.println(season.getName());
}
}
结果:
Season{name='春天', desc='温暖'}
Season{name='秋天', desc='凉爽'}
秋天
2.enum关键字实现枚举类
1.使用 enum替代了class 2.SPRING("春天","温暖") 取代了 public static final Season SPRING = new Season("春天","温暖"); 因为 enum替代了class 所以无法new, 使用 常量名(参数列表) 方式即可。 注意:使用 常量名(参数列表) 方式,也会走构造器,本质上等价于 public static final Season SPRING = new Season("春天","温暖"); 3.如果定义多个常量(对象) 使用,隔开即可 4.如果使用enum实现枚举,要求将定义的常量(对象)写在最前面 5.如果使用无参构造器则可以省略() eg: SPRING
enum枚举类实例:
package com.yves.enumPackage;
enum Season {
//如果使用了枚举类
/*
1.使用 enum替代了class
2.SPRING("春天","温暖") 取代了 public static final Season SPRING = new Season("春天","温暖");
因为 enum替代了class 所以无法new, 使用 常量名(参数列表) 方式即可。
注意:使用 常量名(参数列表) 方式,也会走构造器,本质上等价于 public static final Season SPRING = new Season("春天","温暖");
3.如果定义多个常量(对象) 使用,隔开即可
4.如果使用enum实现枚举,要求将定义的常量(对象)写在最前面
*/
SPRING("春天","温暖"),
SUMMER("夏天","炎热"),
AUTUMN("秋天","凉爽"),
WINTER("冬天","寒冷");
private String name;
private String desc;
//构造器私有化 (创建了有参构造器,那么默认的无参构造器想要使用必须显式定义)
private Season(String name,String desc){
this.name = name;
this.desc =desc;
}
//2.只保留get方法
public String getName() {
return name;
}
public String getDesc() {
return desc;
}
@Override
public String toString() {
return "Season{" +
"name='" + name + '\'' +
", desc='" + desc + '\'' +
'}';
}
}
package com.yves.enumPackage;
public class Application {
public static void main(String[] args) {
System.out.println(Season.SPRING);
Season season = Season.AUTUMN;
System.out.println(season);
System.out.println(season.getName());
}
}
结果:
Season{name='春天', desc='温暖'}
Season{name='秋天', desc='凉爽'}
秋天
解释第五条:如果使用无参构造器则可以省略()。
package com.yves.enumPackage;
public class Application {
enum Gender{
//这个BOY是一个对象 默认调用了Gender的无参构造器
//这里的BOY实际上等价于 自定义枚举类的 public static final BOY = new Gender()
BOY,GIRL;
}
public static void main(String[] args) {
Gender boy = Gender.BOY; //boy={name:BOY}
Gender boy2 = Gender.BOY;
//Gender 没有写toString方法,所以会去调父类的toString方法(枚举类默认继承Enum类)
/*
Enum 的toString方法
public String toString() {
return name;
}
因为 boy={name:BOY} 所以 System.out.println(boy); 会输出BOY
*/
System.out.println(boy);
//BOY和BOY2都指向Gender.BOY
System.out.println(boy2 == boy); //ture
}
}
结果:
BOY
true
3.默认继承Enum父类中常用的方法
package com.yves.enumPackage;
enum Season {
SPRING("春天","温暖"),
SUMMER("夏天","炎热"),
AUTUMN("秋天","凉爽"),
WINTER("冬天","寒冷");
private String name;
private String desc;
private Season(String name,String desc){
this.name = name;
this.desc =desc;
}
public String getName() {
return name;
}
public String getDesc() {
return desc;
}
}
package com.yves.enumPackage;
public class Application {
public static void main(String[] args) {
Season season1 = Season.SPRING;
Season season2 = Season.SUMMER;
System.out.println("=====name() 输出枚举对象的名字====");
// .name()方法; 输出枚举对象的名字
System.out.println(season1.name()); //SPRING
System.out.println("=====ordinal() 输出枚举对象所在的次序====");
//ordinal() 输出枚举对象所在的次序
System.out.println(season1.ordinal()); //SPRING:0 SUMMER:1 所以这里为0
System.out.println("=====values() 返回定义的所有枚举对象====");
//values() 返回定义的所有枚举对象
Season valus[] = Season.values();
for (Season s : valus) {
System.out.println(s);
}
System.out.println("=====compareTo() 比较两个枚举对象,比较的是编号====");
//compareTo() 比较两个枚举对象,比较的是编号 返回值为 int 前面的编号-后面的编号
System.out.println(Season.SPRING.compareTo(Season.SUMMER)); //0-1 = -1
System.out.println("valueOf(name) 根据name 查找该枚举对象是否存在====");
//valueOf(name)根据你输入的 “参数名称” 去查找Season的枚举对象
//如果找到则返回 如果没有则报错;
Season sea1 = Season.valueOf("WINTER"); //存在 返回该对象
System.out.println(sea1);
Season sea2 = Season.valueOf("SPRING1"); //不存在SPRING1 报错
System.out.println(sea2);
}
}
结果:
=====name() 输出枚举对象的名字====
SPRING
=====ordinal() 输出枚举对象所在的次序====
0
=====values() 返回定义的所有枚举对象====
SPRING
SUMMER
AUTUMN
WINTER
=====compareTo() 比较两个枚举对象,比较的是编号====
-1
valueOf(name) 根据name 查找该枚举对象是否存在====
WINTER
Exception in thread "main" java.lang.IllegalArgumentException: No enum constant com.yves.enumPackage.Season.SPRING1
at java.lang.Enum.valueOf(Enum.java:238)
at com.yves.enumPackage.Season.valueOf(Season.java:3)
at com.yves.enumPackage.Application.main(Application.java:43)
Process finished with exit code 1
三、注解
1.注解的理解
1. 注解也被 者运行,相当于代码中的补充信息
2.JDK内置的基本注解类型
@override 、@deprecated 、@suppresswarnings
1. @override:限定某个方法,是重写父类方法,该注解只能用于方法
2. @deprecated:用于表示某个程序元素(类、方法)过时
3. @suppresswarnings:抑制编译器警告
3. 元注解
元注解:用于修饰注解的注解叫元注解
1.Retention:指定注解的作用范围
source:源码 class: 类 runtime : 运行时
2.Target :指定注解可以在那些地方使用(类、方法、构造器、变量。。。。。)
3.Documented:指定该注解是否会在javadoc中体现
4.Inherited:子类会继承父类的注解