JAVA笔记(十五):枚举类、注解、异常
枚举类Enumeration
1)枚举对应英文(enumeration,简写enum)
2)枚举是一组常量的集合
3)可以理解为:枚举属于一种特殊的类,里面只包含一组 有限的 特定的 对象
1、自定义类实现枚举
不需要提供setXxx方法,因为枚举对象值通常为只读
对枚举对象/属性使用final+static修饰,实现底层优化(类不用加载)
枚举对象名通常使用全部大写,常量的命名规范
枚举对象根据需要,也可以有多个属性
public class Enumeration02 {public static void main(String[] args) {System.out.println(Season.AUTUMN);System.out.println(Season.SPRING);}
}//演示自定义枚举实现
class Season {private String name;private String desc; //描述//定义了四个对象//public final static:类不用被加载,在外部其他类可以直接调用自定义枚举public final static Season SPRING = new Season("春天","温暖");//多个属性(2个)public final static Season SUMMER = new Season("夏天","炎热");public final static Season AUTUMN = new Season("秋天","凉爽");public final static Season WINTER = new Season("冬天","寒冷");//1. 构造器私有化-》防止直接new//2. 去掉set相关方法-》防止属性被修改(只读不能写)//3. 在Season内部,直接创建固定的对象private Season(String name, String desc){this.name = name;this.desc = desc;}@Overridepublic String toString() {return "Season{" +"name='" + name + '\'' +", desc='" + desc + '\'' +'}';}
}
2、enum关键字实现枚举
1)使用注意事项
使用关键字enum替代class
SPRING(“春天”,“温暖”); ==> 常量名(实参列表) =》根据实参列表判断调用的是哪个构造器
如果有多个常量(对象),使用,号间隔。最后一个用;号结束
如果使用enum来实现枚举,要求将定义常量对象写在类体的最前面
当使用enum关键字开发一个枚举类时,默认会继承Enum类(用javap反编译证明),并且是一个final类
enum后不能再继承其他类(不能有extends关键字),因为底层隐式继承了Enum类
如果使用无参构造器创建枚举对象,则实参列表和小括号都可以省略
public class Enumeration03 {public static void main(String[] args) {System.out.println(Season2.AUTUMN);System.out.println(Season2.SPRING);}
}//使用enum关键字来实现枚举类
enum Season2 {//使用enum来实现枚举类//1. 使用关键字enum替代class//2. SPRING("春天","温暖"); ==> 常量名(实参列表)//3. 如果有多个常量(对象),使用,号间隔。最后一个用;号结束//4. 如果使用enum来实现枚举,要求将定义常量对象写在类体的最前面SPRING("春天","温暖"),SUMMER("夏天","炎热"),AUTUMN("秋天","凉爽"),WINTER("冬天","寒冷"),OTHER(); //调用的无参构造器,还可以直接简化成OTHERprivate String name;private String desc; //描述private Season2(){ //无参构造器}private Season2(String name, String desc){this.name = name;this.desc = desc;}public String getName() {return name;}public String getDesc() {return desc;}@Overridepublic String toString() {return "Season{" +"name='" + name + '\'' +", desc='" + desc + '\'' +'}';}
}
2)enum常用方法说明
说明:使用enum时,会隐式继承Enum类,这样我们可以使用Enum类的相关方法
public class EnumMethod {public static void main(String[] args) {//使用Season2 枚举类来演示(只有春夏秋冬四个枚举)Season2 autumn = Season2.AUTUMN;//【对象调用】name:输出枚举对象的名称System.out.println(autumn.name() + "\n"); //AUTUMN//【对象调用】ordinal: 输出该美剧对象的次序/编号(从0开始编号)System.out.println(autumn.ordinal()+ "\n"); //2//【类调用】values: 返回枚举数组,包含定义的所有枚举对象Season2[] values = Season2.values();for (Season2 season : values) {System.out.println(season);}System.out.println();//【类调用】valueOf: 将字符串转换成枚举对象,要求字符串必须为已有的常量名,否则报异常//功能:根据枚举名找到枚举,获得完整的枚举(包括枚举类属性)Season2 autumn1 = Season2.valueOf("AUTUMN");System.out.println("autumn1 = " + autumn1);System.out.println(autumn == autumn1); //true//compareTo:比较两个枚举常量,比较的是编号,①当==0,编号相等 ②当<0,前面的编号比后面的编号小//底层:return self.ordinal - other.ordinal;//Season2.AUTUMN - Season2.SUMMER编号System.out.println(Season2.AUTUMN.compareTo(Season2.SUMMER)); //1//toString:Enum类已经重写过,返回的是当前对象的名字(枚举名),如果自己再在枚举类中重写,则调用自己写的toString方法System.out.println(autumn);}
}
3)课堂练习
第一题
Enum的toString方法返回name,就是枚举的名字
输出:
BOY
true
第二题
public class Test {public static void main(String[] args) {Week[] weeks = Week.values();for(Week week : weeks){System.out.println(week);}}
}enum Week {MONDAY("星期一"),TUESDAY("星期二"),WEDNSDAY("星期三"),THURSDAY("星期四"),FRIDAY("星期五"),SATURDAY("星期六"),SUNDAY("星期日");private String desc;private Week(String desc){this.desc = desc;}@Overridepublic String toString() {return desc;}
}
4)enum实现接口
枚举和普通类一样,可以实现接口,如下形式:
enum 类名 implements 接口1,接口2{}
使用实现接口的方法:枚举类名.枚举名.方法名()
public class Test {public static void main(String[] args) {Music.CLASSICMUSIC.playing(); //使用实现接口的方法,枚举类名.枚举名.方法名()}
}interface IAA {public void playing();
}
enum Music implements IAA{CLASSICMUSIC;@Overridepublic void playing() {System.out.println("播放音乐...");}
}
注解Annotation
1、JDK内置的基本注解类型
1)@Override
限定某个方法,是重写父类方法。该注解只能用于方法
功能:语法校验
如果写了@Override,编译器就会去检查该方法是否真的重写了父类的方法。
如果的确重写了,则编译通过
如果没有构成重写,则编译错误
@Override定义
@interface:表示一个注解类
@Target:可以修饰的类型,这里只能修饰METHOD方法
@Target是修饰注解的注解 ==》元注解
2)@Deprecated
用于表示某个程序元素已过时
功能:做一个过渡,版本升级时的兼容过渡
3)@SuppressWarnings
抑制编译器警告
功能:当我们不希望看到警告信息时,可以使用SuppressWarnings抑制警告信息
用法:
@SuppressWarnings({""})
在{""}
中,可以写入希望抑制的警告信息
一般方便就是@SuppressWarnings({"all"})
注意:
SuppressWarnings作用范围和你放置的位置相关
比如:放在main方法头上,作用域就只有main方法,对其他类成员无效
2、元注解(了解):对注解进行注解
Retention注解
Target注解
Documented注解
Inherited注解
内部类、枚举、注解练习题
第一题
考点:static变量,对不同的对象是共享的
输出:
9.0 red
100 red
第二题
考点:匿名内部类,调用
第一种方法:匿名内部类作为对象,直接调用方法
public class Test {public static void main(String[] args) {CellPhone cellPhone = new CellPhone();cellPhone.testWork();}
}interface Computer {void work();
}
class CellPhone {public void testWork(){new Computer(){@Overridepublic void work() {System.out.println("手机在工作");}}.work();}
}
第二种方法:匿名内部类作为参数传递
public class Test {public static void main(String[] args) {CellPhone cellPhone = new CellPhone();cellPhone.testWork(new Computer() {@Overridepublic void work() {System.out.println("手机在工作");}});}
}interface Computer {void work();
}
class CellPhone {public void testWork(Computer computer){computer.work();}
}
第三题
考点:局部内部类,重名属性
public class Test {public static void main(String[] args) {A a = new A();a.m1();}
}class A {private final String NAME = "李三";public void m1(){class B {private final String NAME = "张三";public void show(){System.out.println(NAME);System.out.println(A.this.NAME);}}//下面这段代码不能放在class B{}前面,因为classB也是一个局部变量//局部变量还没有创建的时候,不能使用它B b = new B();b.show();}
}
第四题
版本一:通过设置isRiver来判断是否过河,输出只有一句
public class Test {public static void main(String[] args) {Boolean isRiver = false;Person person = new Person("唐僧", null);person.work(isRiver);}
}interface Vehicles {void work();
}
class Horse implements Vehicles {@Overridepublic void work() {System.out.println("骑马走...");}
}class Boat implements Vehicles {@Overridepublic void work() {System.out.println("坐船过...");}
}class Factory {//这里,将方法做成static比较方便(不用创建对象)public static Horse getHorse(){return new Horse();}public static Boat getBoat(){return new Boat();}
}class Person {private String name;private Vehicles vehicles;public Person(String name, Vehicles vehicles) {this.name = name;this.vehicles = vehicles;}//这里涉及到一个编程思路,就是可以把具体的要求,封装成方法 -> 这里就是编程思想//如何不浪费属性Vehiclepublic void work(Boolean isRiver){//向上转型if(isRiver){vehicles = Factory.getBoat();} else {vehicles = Factory.getHorse();}vehicles.work(); //动态绑定}public String getName(){return name;}
}
题目增加条件:唐僧过火焰山,用飞机
版本二:分别调用过河和一般情况,参数额外判断
public class Test {public static void main(String[] args) {Boolean isRiver = false;Person person = new Person("唐僧", null);person.Common();person.passRiver();person.passMountain();person.passRiver();person.Common();}
}interface Vehicles {void work();
}
class Horse implements Vehicles {@Overridepublic void work() {System.out.println("Common:一般情况,骑马走...");}
}class Boat implements Vehicles {@Overridepublic void work() {System.out.println("PassRiver:遇到河流,坐船过...");}
}
class Plane implements Vehicles {@Overridepublic void work() {System.out.println("PassMountain: 遇到火山,用飞机...");}
}class Factory {//存储马:static是公共共享空间//饿汉式private static Horse horse = new Horse();private Factory(){};//这里,将方法做成static比较方便(不用创建对象)public static Horse getHorse(){//返回的马应该是只有一匹马,第一次取到马之后就固定了return horse;}public static Boat getBoat(){return new Boat();}public static Plane getPlane() {return new Plane();}
}class Person {private String name;private Vehicles vehicles;public Person(String name, Vehicles vehicles) {this.name = name;this.vehicles = vehicles;}//这里涉及到一个编程思路,就是可以把具体的要求,封装成方法 -> 这里就是编程思想//如何不浪费属性Vehicle//传入的参数vehicles有三种情况:null、Boat、Horsepublic void passRiver() { //当传入null和Horse时,需要将vehicles改为Boatif(!(vehicles instanceof Boat)){vehicles = Factory.getBoat();}vehicles.work();}//过火焰山用飞机public void passMountain() {if(!(vehicles instanceof Plane)){vehicles = Factory.getPlane();}vehicles.work();}public void Common() {if(!(vehicles instanceof Horse)){vehicles = Factory.getHorse();}vehicles.work();}public String getName(){return name;}
}
第五题
考点:成员内部类的调用
public class Test {public static void main(String[] args) {Car car1 = new Car(40.6);Car car2 = new Car(41.6);Car car3 = new Car(25.6);Car car4 = new Car(-3.6);car1.m(); //或者car1.getAir().flow();car2.m();car3.m();car4.m();}
}class Car {private double temperature;public Car(double temperature) {this.temperature = temperature;}class Air {public void flow(){if(temperature > 40) {System.out.println("吹冷气");} else if(temperature < 0){System.out.println("吹暖气");} else {System.out.println("关空调");}}}public Air getAir(){return new Air();}public void m(){Air air = new Air();air.flow();}
}
第六题
考点:枚举、枚举再switch中的使用
switch(枚举对象){case 枚举名1:...break;case 枚举名2:...break;
}
public class Test {public static void main(String[] args) {Color[] colors = Color.values();for(Color color : colors){switch (color){case RED:System.out.println("匹配到红色");break;case BLUE:System.out.println("匹配到蓝色");break;case BLACK:System.out.println("匹配到黑色");break;case YELLOW:System.out.println("匹配到黄色");break;case GREEN:System.out.println("匹配到绿色");break;default:System.out.println("没有匹配到");break;}}}
}enum Color implements IA{RED(255,0,0),BLUE(0,0,255),BLACK(0,0,0),YELLOW(255,255,0),GREEN(0,255,0);private int redValue;private int greenValue;private int blueValue;Color(int redValue, int greenValue, int blueValue) {this.redValue = redValue;this.greenValue = greenValue;this.blueValue = blueValue;}@Overridepublic void show() {System.out.println("redValue=" + redValue + " greenValue=" + greenValue + " blueValue=" + blueValue);}
}interface IA {void show();
}
异常Exception
1、异常的概念
异常的出现:
程序中出现了一个不算致命的问题,就导致整个程序抛出异常后退出(崩溃),这不合理。
所以在发现异常后,程序仍然能够继续执行,这就是java异常处理机制异常基本概念:
java中,将程序执行过程发生的不正常情况称为“异常”(语法错误和逻辑错误和不是异常)
异常分为两类
- Error(错误):Java虚拟机无法解决的严重错误。如StackOverflowError栈溢出,OOM(out of memory)程序会崩溃。
- Exception :其它因编程错误或偶然的外在因素导致的一般性问题,可以使用针对性的代码处理。例如空指针访问,网络连接中断等等。
- Exception分为两大类:
- 运行时异常【程序运行时发生的异常】
- 编译时异常【编程时,编译器检查出的异常】
2、异常体系图⭐⭐⭐
类的异常体系图,体现了继承和实现关系
小结
3、常见的异常
① 常见的运行时异常
1)NullPointerException
空指针异常
当应用程序试图在需要对象的地方使用null时,抛出该异常
public class Test {public static void main(String[] args) {String name = null;System.out.println(name.length());}
}
2)ArithmeticException
数学运算异常
当出现异常的运算条件时,抛出此异常,比如除以0
3)ArrayIndexOutOfBoundsException
数组下标越界异常
用非法所哟i你访问数组时抛出的异常,如果索引为负或者大于等于数组大小,则该索引为非法索引
4)ClassCastException
类型转换异常
当试图将对象强制转换为不是实例运行类型或者其子类时,抛出该异常。(向下向上转型错误)
class A{}
class B extends A{}
class C extends A{}
A a = new B(); //向上转型
B b = (B)a; //向下转型
C c = (C)a; //转型错误,因为a的运行类型是B,和C无关
5)NumberFormatException
数字格式不正确异常
当应用程序试图将字符串转换成一种数值类型,但该字符串不能抓换位适当格式时,抛出该异常 =》 使用异常我们可以确保输入的是 满足条件的 数字
String name = "你好";
int num = Integer.parseInt(name);
② 常见的编译异常
1)SQLException
//操作数据库时,查询表可能发生异常
2)IOException
//操作文件时,发生的异常
3)FILENotFoundException
//当操作一个不存在的文件时,发生异常
4)ClassNotFoundException
//加载类时,该类不存在,发生异常
5)EOFException
//操作文件,到文件末尾,发生异常
6)IllegalArgumentException
//参数异常
4、异常处理概念和处理机制图
- 基本介绍
异常处理就是当异常发生时,对异常处理的方式
异常处理的方式
1)try-catch-finally
程序员在代码中捕获发生的异常,自行处理
2)throws
将发生的异常抛出,交给调用者(方法)来处理,最顶级的处理者就是JVM
不用try-catch时,默认用throws(隐式的)
5、异常处理分类
1)try-catch
如果异常发生了,则异常发生后面的代码不会执行,直接进入到catch块
如果异常没有发生,则顺序执行try代码块,不会进入到catch
如果希望不管是否发生异常,都执行某段代码(比如关闭连接,释放资源等),则使用fianlly{}
public class TryCatchDetail {public static void main(String[] args) {try {String str = "你好";int a = Integer.parseInt(str);System.out.println("数字:" + a); //1. 一旦发生异常,这句代码不会执行,而是直接进入到catch块} catch (NumberFormatException e) {System.out.println("异常信息:" + e.getMessage());} finally {System.out.println("finally代码块被执行...");}System.out.println("程序继续...");}
}
- 可以有多个catch语句,捕获不同的异常(进行不同的业务处理),要求父类异常在后,子类异常在前,比如(Exception在后,NullPointerException在前),如果发生异常,只会匹配一个catch
public class TryCatchDetail {public static void main(String[] args) {try {Person person = new Person();person = null;System.out.println(person.getName()); //NullPointerExceptionint n1 = 10;int n2 = 0;int res = n1 / n2; //ArithmeticException//↓下面捕获三种异常,子类在前,父类在后(否则父类异常包含子类异常,子类异常永远用不到)} catch (NullPointerException e) {System.out.println("空指针异常=" + e.getMessage());} catch (ArithmeticException e) {System.out.println("算术异常=" + e.getMessage());} catch (Exception e) {System.out.println("父类异常=" + e.getMessage());} finally {}}
}class Person {private String name = "jack";public String getName() {return name;}
}
- 可以进行try-finally配合使用,这种用法相当于没有捕获异常,因此程序会直接崩掉/退出。【应用场景:执行一段代码,不管是否发生异常,都必须执行某个业务逻辑(检测到异常时并不马上崩掉,而是执行完这段finally代码后再崩)】
public class TryCatchDetail {public static void main(String[] args) {try {int n1 = 10;int n2 = 0;System.out.println(n1 / n2);} finally {System.out.println("执行了finally..");}System.out.println("程序继续执行..");}
}
输出:
2)throws
注意事项
3)如下图,NullPointerException是RuntimeException的子类
4)抛出的(编译)异常有两种处理方式:调用者也抛出异常,或者调用者内部使用try-catch处理异常
抛出运行异常可以不做处理
6、自定义异常
基本概念
自定义异常的步骤
public class CustomException {public static void main(String[] args) /* throws AgeException */{int age = 80;if(!(age >= 18 && age <= 120)){//这里通过构造器,设置信息throw new AgeException("年龄需要在18 ~ 120之间");//throw和throws的区别看后文}}
}//一般继承运行时异常
//如果是继承编译异常Exception,调用者需要throws AgeException
class AgeException extends RuntimeException {public AgeException(String message) { //构造器super(message);}
}
7、throw和throws的对比
8、异常练习
【第一题】
输出:
i=4
3
【第二题】
如果用户输入的不是一个整数,就提示他反复输入,直到输入一个整数为止
public class Test {public static void main(String[] args) {int n = 0;Scanner scanner = new Scanner(System.in);while(true){System.out.print("请输入一个整数:");try {n = Integer.parseInt(scanner.next()); //容易有NumberFormatExceptionSystem.out.println("你输入的整数为:" + n);break;} catch (NumberFormatException e) {System.out.println("你输入的不是一个整数,请重新输入!");}}}
}
【第三题】
下面的测试输出什么
当try中存在return或者throw时,finally优先于return和throw运行
当存在catch时,catch优先于finally运行
输出:
【第四题】
public class EcmDef {public static void main(String[] args) {try {//ArrayIndexOutOfBoundsExceptionif(args.length != 2) {throw new ArrayIndexOutOfBoundsException("缺少命令行参数或参数个数不对");}//NumberFormatExceptionint n1 = Integer.parseInt(args[0]);int n2 = Integer.parseInt(args[1]);//ArithmeticExceptiondouble res = cal(n1, n2);//三个异常都通过,则执行下面代码(输出结果)System.out.println("n1/n2 => " + n1 + "/" + n2 + "=" + cal(n1, n2));} catch(ArrayIndexOutOfBoundsException e) {System.out.println("缺少命令行参数");//注意,空指针异常是有数组元素,只不过没有初始化,而不是缺少元素(命令行参数)} catch(NumberFormatException e) {System.out.println("数据格式不正确");} catch(ArithmeticException e) {System.out.println("不能除0");}}public static double cal(int n1, int n2) {return n1 / n2;}
}
【第五题】
【第六题】
写出运行结果
JAVA笔记(十五):枚举类、注解、异常相关推荐
- python学习笔记(十五) -- 枚举
枚举 枚举的作用就是定义一组 数据形式为 dict 但却又不可变的常量 比如我们定义一个类,或者定义一个dict ,类中的成员变量可以被更改,而且类又可以被实例化,dict 里面的值也可以被更改. 如 ...
- Effective Java笔记第五章枚举和注解第三节用EnumSet代替位域
Effective Java笔记第五章枚举和注解 第三节用EnumSet代替位域 在以前如果一个枚举类型的元素主要用在集合中,一般就会使用int枚举模式.比如说: public class Demo ...
- Java基础学习——第十章 枚举类注解
Java基础学习--第十章 枚举类&注解 一.枚举类(enum) 1. 枚举类的概念 枚举类:类的对象只有有限个,确定的 线程状态:创建.就绪.运行.阻塞.死亡 当需要定义一组常量时,强烈建议 ...
- Java笔记整理五(Iterator接口,泛型,常见数据结构(栈,队列,数组,链表,红黑树,集合),jdk新特性,异常,多线程,Lambda表达式)
Java笔记整理五 1.1Iterator接口 Collection接口与Map接口主要用于存储元素,而Iterator主要用于迭代访问(即遍历)Collection中的元素,因此Iterator对象 ...
- 《Windows核心编程》读书笔记二十五章 未处理异常,向量化异常处理与C++异常
第二十五章 未处理异常,向量化异常处理与C++异常 本章内容 25.1 UnhandledExceptionFilter函数详解 25.2 即时调试 25.3 电子表格示例程序 25.4 向量化异常 ...
- Polyworks脚本开发学习笔记(十五)-用Python连接Polyworks的COM组件
Polyworks脚本开发学习笔记(十五)-用Python连接Polyworks的COM组件 用Polyworks脚本开发,没有高级语言的支持,功能难免单一,一些比较复杂的交互实现不了,界面和报告也很 ...
- Windows异常学习笔记(五)—— 未处理异常
Windows异常学习笔记(五)-- 未处理异常 要点回顾 最后一道防线 实验一:理解最后一道防线 实验二:新线程的最后一道防线 总结 UnhandledExceptionFilter 实验三:理解U ...
- Java面试知识点:Date类、异常
问题:Java面试知识点:Date类.异常 答案: 1.Date类 代码如下: (1)创建日期: package com.xy;import java.util.Date;/*** @ProjectN ...
- python复制指定字符串_python3.4学习笔记(十五) 字符串操作(string替换、删除、截取、复制、连接、比较、查找、包含、大小写转换、分割等)...
python3.4学习笔记(十五) 字符串操作(string替换.删除.截取.复制.连接.比较.查找.包含.大小写转换.分割等) python print 不换行(在后面加上,end=''),prin ...
- Java学习总结3——枚举类和反射机制
Java枚举类和反射机制 一.Java枚举类(Enum): 在某些情况下,一个类的对象是有限且固定的,对于这种对象的实例有限且固定的类,在 Java 中被称为枚举类(Enum):枚举类是为了提高代码可 ...
最新文章
- 程序员的反击!每天一个离职小技巧
- SwiftSuspenders 1.6 浅出深入 深入 2
- jquery学习之重要知识点
- Spring AOP基础—JDK动态代理
- php框架之laravel
- 无尽包围html5游戏在线玩,小团体激发潜能小游戏突破自我
- C#算法设计查找篇之05-二叉树查找
- IOS端与Java端MD5加密方法
- 爬虫之Xpath的使用
- sap 双计量单位_[原创]浅谈MM模块的双计量单位(二)
- c 标签 foreach里面套choose做判断
- spotfire Document Property
- ubuntu中fcitx输入法不显示拼音与候选词框
- 一文盘点中国商业航天:民营火箭的两类瓶颈和三大趋势
- 标准功能模块组件 -- 内部联络单组件,内部邮件组件,提高多人异地协同办公效率
- 微信企业号开发七:JSAPI模式
- Enriched Feature Guided Refinement Network for Object Detection(面向目标检测的丰富特征引导细化网络)
- week6 day4 并发编程之多线程 理论
- 好久不见,我回来了!
- vue上下全屏翻页_全屏翻页布局
热门文章
- 华为服务器 修改管理地址吗,华为服务器 修改管理地址吗
- 1151. 【克罗地亚】pjesma
- 求字符串长度Strlen的三种方式
- System.Runtime.InteropServices.COMException:“对 COM 组件的调用返回了错误 HRESULT E_FAIL
- 如何配置IIS运行 ASPX
- JDBC插入数据时中文变为问号的解决方法
- Codeforces Round #663 (Div. 2) (CD)
- 文本超出长度用用省略号显示
- 非计算机专业特别是人文社科,中职非计算机专业《计算机应用基础》教学必须重视学情分析...
- 机器人中的数值优化(三)—— 无约束最优化方法基础、线搜索准则