一、枚举和注解
引出:
分析:
解决方案:枚举
枚举实现方式
自定义类实现枚举
四步走
package com.bijing.enum_;
/**
* @author 毕晶
* @date 2022/6/2 10:10 AM
*/
public class Enumeration01 {
public static void main(String[] args) {
System.out.println(Season.AUTUMN);
}
}
class Season {
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 String name;
private String desc;
// 1.私有化构造器
// 2.去掉set方法
// 3.在Season内部直接创建固定对象
// 4.加入final修饰符,final修饰的对象只是引用值不可更改,但是它里面的属性可以通过set进行更改
private Season(String name, String desc) {
this.name = name;
this.desc = desc;
}
public String getName() {
return name;
}
public String getDesc() {
return desc;
}
@Override
public String toString() {
return "Season{" +
"name='" + name + '\'' +
", desc='" + desc + '\'' +
'}';
}
}
使用enum关键字实现枚举
特点
- 枚举类的对象默认都是public
- 枚举类的构造器都是 private ,故无法在外部创建其实例,这也决定了枚举类实例的个数的确定性
- enum类不可被继承。
- enum类默认extends java.lang.Enum,所以无法再继承其他类
五步走
// 1.使用关键字 enum替代class
// 2.public static final Season02 SPRING = new Season02("春天", "温暖");直接使用
// SPRING("春天","温暖");代码要在属性上面写
// 3.有多个常量(对象),使用,间隔即可
// 4.如果使用enum来实现枚举,要把定义的常量对象写在最前面
// 5.如果我们使用的是无参构造器,创建常量对象,则可以省略(〕
enum Season02 {
SPRING("春天", "温暖"), SUMMER("夏天", "炎热");
/* public static final Season02 SPRING = new Season02("春天", "温暖");
public static final Season02 WINTER = new Season02("冬天", "寒冷");
public static final Season02 AUTUMN = new Season02("秋天", "凉爽");
public static final Season02 SUMMER = new Season02("夏天", "炎热");*/
private String name;
private String desc;
private Season02(String name, String desc) {
this.name = name;
this.desc = desc;
}
public String getName() {
return name;
}
public String getDesc() {
return desc;
}
@Override
public String toString() {
return "Season02{" +
"name='" + name + '\'' +
", desc='" + desc + '\'' +
'}';
}
}
enum关键字实现枚举的注意事项
6.枚举的toString()方法返回的是name
枚举常用方法
enum继承了Enum
Season02 season = Season02.SPRING;
//name()方法输出常量的名称,即SPRING
System.out.println(season.name());
//ordinal()方法输出的是该枚举对象的次序/编号 ,下标从0开始
System.out.println(season.ordinal());
// values()方法返回一个season02数组
Season02[] seasons = Season02.values();
for (Season02 season02 : seasons) {
System.out.println(season02);
}
//valueOf() 将字符串转换成枚举对象,要求字符串必须为己有的常量名,否则报异常
//1.根据你输入的 "AUTUMN" 到 Season2的枚举对象去查找
//2.如果找到了,就返回,如果没有找到,就报错
Season02 autumn1 = Season02.valueOf("AUTUMN");
System.out.println("autumn1=" + autumn1);
System.out.println(Season02.AUTUMN == autumn1);
//compareTo()方法比较的是两个枚举常量,比较它们的编号
//返回SPRING的编号 - AUTUMN的编号
System.out.println(Season02.SPRING.compareTo(Season02.AUTUMN));
}
enum实现接口
/**
* @author 毕晶
* @date 2022/6/2 1:12 PM
*/
enum Spring implements Season03 {
SPRING();
@Override
public void show() {
System.out.println("我是春天");
}
}
interface Season03 {
void show();
}
public class EnumDetail {
public static void main(String[] args) {
Spring.SPRING.show();
System.out.println(Spring.SPRING);
}
}
二、注解
基本注解介绍
@Override
主要是语法校验看你是否真的重写了
Override使用说明
@Deprecated
@SuppressWarnings
关键字 | 用途 |
---|---|
all | to suppress all warnings (抑制所有警告) |
boxing | to suppress warnings relative to boxing/unboxing operations (抑制装箱、拆箱操作时候的警告) |
cast | to suppress warnings relative to cast operations (抑制映射相关的警告) |
dep-ann | to suppress warnings relative to deprecated annotation (抑制启用注释的警告) |
deprecation | to suppress warnings relative to deprecation (抑制过期方法警告) |
fallthrough | to suppress warnings relative to missing breaks in switch statements (抑制确在switch中缺失breaks的警告) |
finally | to suppress warnings relative to finally block that don’t return (抑制finally模块没有返回的警告) |
hiding | to suppress warnings relative to locals that hide variable(抑制相对于隐藏变量的局部变量的警告) |
incomplete-switch | to suppress warnings relative to missing entries in a switch statement (enum case)(忽略没有完整的switch语句) |
nls | to suppress warnings relative to non-nls string literals( 忽略非nls格式的字符) |
null | to suppress warnings relative to null analysis( 忽略对null的操作) |
rawtypes | to suppress warnings relative to un-specific types when using generics on class params( 使用generics时忽略没有指定相应的类型) |
restriction | to suppress warnings relative to usage of discouraged or forbidden references( 抑制禁止使用劝阻或禁止引用的警告) |
serial | to suppress warnings relative to missing serialVersionUID field for a serializable class( 忽略在serializable类中没有声明serialVersionUID变量) |
static-access | to suppress warnings relative to incorrect static access( 抑制不正确的静态访问方式警告) |
synthetic-access | to suppress warnings relative to unoptimized access from inner classes( 抑制子类没有按最优方法访问内部类的警告) |
unchecked | to suppress warnings relative to unchecked operations( 抑制没有进行类型检查操作的警告) |
unqualified-field-access | to suppress warnings relative to field access unqualified( 抑制没有权限访问的域的警告) |
unused | to suppress warnings relative to unused code( 抑制没被使用过的代码的警告) |
元注解的介绍
用来修饰注解的
@Retention
表示注解作用范围,(源码中,class文件中,jvm中)
@Target
表示注解可以在哪里使用
@Documented
表示javadoc生成文档时能看到该注解
@Inherited
表示子类可以继承该注解
自定义注解
自定义注解类编写的一些规则:
- Annotation 类型定义为@interface, 所有的Annotation 会自动继承java.lang.Annotation这一接口,并且不能再去继承别的类或是接口。
- 参数成员只能用public 或默认(default) 这两个访问权修饰。语法:类型 属性名() [default 默认值]; default表示默认值 ,也可以不编写默认值的.
- 参数成员只能用基本类型byte、short、char、int、long、float、double、boolean八种基本数据类型和String、Enum、Class、annotations等数据类型,以及这一些类型的数组.
- 要获取类方法和字段的注解信息,必须通过Java的反射技术来获取 Annotation 对象,因为你除此之外没有别的获取注解对象的方法。
- 注解也可以没有定义成员,,不过这样注解就没啥用了。
注意: 自定义注解需要使用到元注解。
- 注解方法不能有参数。
- 注解方法的返回类型局限于原始类型,字符串,枚举,注解,或以上类型构成的数组。
- 注解方法可以包含默认值。
代码演示
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
String color() default "blue";// 为属性指定缺省值
String product() default "001";
}
@MyAnnotation
public class UserAnnotation {
@MyAnnotation(color = "colortest2 method")
public static void oldMethod() {
System.out.println("old method, don't use it.");
}
@MyAnnotation(color="colortest",product="producttest")
public static void genericsTest() throws FileNotFoundException {
List<String> l = new ArrayList<>();
l.add("abc");
oldMethod();
}
}
public class AnnotationParsing {
public static void main(String[] args) {
try {
Class<?> loadClass = AnnotationParsing.class
.getClassLoader()
.loadClass("com.lys.myannotation.UserAnnotation");
if (loadClass.isAnnotationPresent(MyAnnotation.class)) {
Annotation[] declaredAnnotations = loadClass.getDeclaredAnnotations();
for (Annotation annotation : declaredAnnotations) {
System.out.println("Annotation in class '" + annotation);
}
}
for (Method method : loadClass.getMethods()) {
// checks if MethodInfo annotation is present for the method
if (method.isAnnotationPresent(MyAnnotation.class)) {
try {
// iterates all the annotations available in the method
for (Annotation anno : method.getDeclaredAnnotations()) {
System.out.println("Annotation in Method '"
+ method + "' : " + anno);
}
MyAnnotation methodAnno = method.getAnnotation(MyAnnotation.class);
if (methodAnno.product().equals("001")) {
System.out.println("Method with product is 001 = "+ method);
}
} catch (Throwable ex) {
ex.printStackTrace();
}
}
}
} catch (SecurityException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
三、异常
入门案例
tips:mac 中try-catch快捷键是option+command+t
介绍
错误Error
异常Exception:运行时异常、编译时异常 ,编译时异常必须要处理,运行时异常不处理会默认throws方式处理
异常体系图(重要)
小结
五大运行时异常
空指针异常
算术异常
数组下标越界异常
类型转换异常
数字格式不正确异常
NumberFormatException和InputMismatchException区别
在scanner接收到输入后,如果输入类型不对会报InputMismatchException异常
在把输入到的内容进行类型转换成数字时如果不对会报NumberFormatException异常
编译异常
异常处理
try-catch-finally
注意细节(注意:4,5)
- 如果异常发生了,则异常发生的代码到catch之间的代码不会执行,直接进入到catch块
- 如果异常没有发生,则顺序执行try的代码块,不会进入到catch
- 如果希望不管是否发生异常,都执行某段代码(比如关闭连接,释放资源等)则使用如下代码- finally
- 可以有多个catch语句,捕获不同的异常(进行不同的业务处理),要求父类异常在后,子类异常在前,比如(Exception 在后,NullPointerException 在前,如果发生异常,只会匹配一个catch
案例演示:
- 可以进行 try-finally 配合使用,这种用法相当于没有捕获异常,因此程序会直接崩掉 (finally执行完毕后退出程序,不执行后面的代码)。
(应用场景:执行程序,不管是否发生异常,都必须要执行一段业务逻辑) - try-catch-finally处理运行时异常时没有catch该类会默认throws Exception
重要习题:
- null没有equals方法,所以发生异常
- finally必须执行,所以会覆盖return 3
- try中有个return 1,所以不会报错
- return ++i后会把结果保存在临时变量temp中
- 继续执行finally中的++i,但是最后会return temp中的值
小结
throws
throws 介绍
throws的使用细节(注意:3)
3. 子类抛出的异常不能比父类抛出异常的辈分更大
自定义异常
基本概念
基本步骤
throw和throws的区别
throws一般在方法的声明处,表示要抛出什么类型的异常,而throw在方法体中,抛出一个异常的对象