学习日记-day27-6.11
完成目标:
知识点:
1.注解_注解介绍和定义
## 1.注解的介绍1.引用数据类型:类 数组 接口 枚举 注解1.jdk1.5版本的新特性->一个引用数据类型和类,接口,枚举是同一个层次的引用数据类型:类 数组 接口 枚举 注解
2.作用:说明:对代码进行说明,生成doc文档(API文档)检查:检查代码是否符合条件 @Override(会用) @FunctionalInterface 分析:对代码进行分析,起到了代替配置文件的作用(会用)
3.JDK中的注解:@Override -> 检测此方法是否为重写方法jdk1.5版本,支持父类的方法重写jdk1.6版本,支持接口的方法重写@Deprecated -> 方法已经过时,不推荐使用调用方法的时候,方法上会有横线,但是能用@SuppressWarnings->消除警告 @SuppressWarnings("all") public class Person {@Deprecatedpublic void eat(){System.out.println("人要吃饭");}
}@SuppressWarnings("all")
public class Test01 {public static void main(String[] args) {Person person = new Person();person.eat();System.out.println("================");ArrayList list = new ArrayList();list.add(1);}
}========================================================================================
## 2.注解的定义以及属性的定义格式大家需要知道的是,咱们这里说的注解属性,其实本质上是抽象方法,但是我们按照属性来理解,好理解,因为到时候使用注解的时候,需要用=为其赋值1.定义:public @interface 注解名{}2.定义属性:增强注解的作用数据类型 属性名() -> 此属性没有默认值,需要在使用注解的时候为其赋值数据类型 属性名() default 值 -> 此属性有默认值,如果有需要,还可以二次赋值3.注解中能定义什么类型的属性呢?a.8种基本类型b.String类型,class类型,枚举类型,注解类型c.以及以上类型的一维数组public @interface Book {//书名String bookName();//作者String[] author();//价格int price();//数量int count() default 10;
}
知识点 | 核心内容 | 重点 |
注解定义 | 使用@interface关键字定义,本质是特殊接口 | 与普通接口的语法区别 |
注解属性 | 本质是抽象方法,但按属性理解更直观 | 属性必须赋值 vs 带默认值可省略 |
JDK内置注解 | @Override、@Deprecated、@SuppressWarnings | @Deprecated的横线标记效果 |
注解作用 | 代码说明/文档生成、编译检查(@Override)、配置替代(Servlet示例) | XML配置 vs 注解配置的转换逻辑 |
属性类型限制 | 基本类型/String/Class/枚举/注解/一维数组 | 不支持二维数组 |
Servlet配置对比 | XML需配置<servlet>和<servlet-mapping> | @WebServlet("/url")的简化效果 |
默认值语法 | 使用default关键字设置 | 未设默认值必须显式赋值 |
警告控制 | @SuppressWarnings("all")消除所有警告 | 泛型未指定时的黄色警告 |
2.注解_详细注解使用
## 3.注解的使用(重点)1.注解的使用:说白了就是为注解中的属性赋值
2.使用位置上:在类上使用,方法上使用,成员变量上使用,局部变量上使用,参数位置使用等
3.使用格式:a.@注解名(属性名 = 值,属性名 = 值...)b.如果属性中有数组:@注解名(属性名 = {元素1,元素2...})public @interface Book {//书名String bookName();//作者String[] author();//价格int price();//数量int count() default 10;
}@Book(bookName = "水浒传",author = {"大郎","金莲"},price = 10,count = 20)
public class BookShelf {
}注解注意事项:1.空注解可以直接使用->空注解就是注解中没有任何的属性2.不同的位置可以使用一样的注解,但是同样的位置不能使用一样的注解3.使用注解时,如果此注解中有属性,注解中的属性一定要赋值,如果有多个属性,用,隔开如果注解中的属性有数组,使用{}4.如果注解中的属性值有默认值,那么我们不必要写,也不用重新赋值,反之必须写上5.如果注解中只有一个属性,并且属性名叫value,那么使用注解的时候,属性名不用写,直接写值(包括单个类型,还包括数组)public @interface Book1 {String value();
}@Book(bookName = "水浒传", author = {"大郎", "金莲"}, price = 10, count = 20)
@Book1("水浒野传")
public class BookShelf {@Book(bookName = "水浒传", author = {"大郎", "金莲"}, price = 10, count = 20)public void method() {}
}
知识点 | 核心内容 | 考试重点/易混淆点 |
注解的使用本质 | 为注解中的属性赋值 | 必须为所有属性赋值(除非有默认值) |
注解的使用位置 | 类、方法、成员变量、局部变量、参数等 | 相同位置不可重复使用同一注解 |
注解的使用格式 | @注解名(属性名=值, ...) | 多属性需用逗号隔开 |
数组属性赋值 | 使用大括号包裹元素(如属性名={值1, 值2}) | 与普通数组声明语法区分 |
默认值特性 | 有默认值的属性可省略赋值 | 需明确注解中是否有默认值 |
value属性简化 | 当注解仅含value属性时,可省略属性名直接赋值 | 适用于单值或数组(如@Book1("水浒")) |
空注解使用 | 无属性的注解可直接使用(如@Override) | 需确认注解定义是否包含属性 |
3.注解_详细注解解析
## 注解解析的方法->AnnotatedElement接口注解的解析:就是将注解中的属性值获取出来1.注解解析涉及到的接口:AnnotatedElement接口实现类: AccessibleObject, Class, Constructor, Executable, Field, Method, Package, Parameter 2.解析思路:先判断指定位置上有没有使用指定的注解,如果有,获取指定的注解,获取注解中的属性值a.boolean isAnnotationPresent(Class<? extends Annotation> annotationClass)->判断指定位置上有没有指定的注解比如:判断BookShelf上有没有Book注解Class bookShelf = BookShelf.classbookShelf.isAnnotationPresent(Book.class) b.getAnnotation(Class<T> annotationClass) ->获取指定的注解,返回值类型为获取的注解类型比如:获取BookShelf上的Book注解Class bookShelf = BookShelf.classboolean result = bookShelf.isAnnotationPresent(Book.class) 如果result为true,证明BookShelf上有Book注解,那就获取Book book = bookShelf.getAnnotation(Book.class) public @interface Book {//书名String bookName();//作者String[] author();//价格int price();//数量int count() default 10;
}@Book(bookName = "金瓶梅", author = {"涛哥", "金莲"}, price = 10, count = 20)
public class BookShelf {
}public class Test01 {public static void main(String[] args) {//1.获取BookShelf的class对象Class<BookShelf> bookShelfClass = BookShelf.class;//2.判断bookShelf上有没有Book注解boolean b = bookShelfClass.isAnnotationPresent(Book.class);//3.判断,如果b为true,就获取if (b){Book book = bookShelfClass.getAnnotation(Book.class);System.out.println(book.bookName());System.out.println(Arrays.toString(book.author()));System.out.println(book.price());System.out.println(book.count());}}
}以上代码没有解析出来:猜想:如果Book注解被加载到内存了,那么我们一定能判断出来BookShelf上有没有Book注解;但是现在没有判断出来,但是BookShelf上确实用了Book注解了,所以Book注解有可能就没有在内存中出现
知识点 | 核心内容 | 考试重点/易混淆点 |
注解解析 | 通过反射机制获取注解中的属性值 | 注解必须加载到内存才能被解析 |
AnnotatedElement接口 | 提供isAnnotationPresent()和getAnnotation()方法 | 实现类包括Class/Constructor/Field/Method |
解析流程 | 1. 判断是否存在注解; 2. 获取注解对象; 3. 读取属性值 | 判断阶段常因注解未加载而失败 |
反射关联 | 注解解析依赖Class/Method等反射对象 | 与AccessibleObject.setAccessible()方法关联 |
实际应用 | 替代XML配置文件的框架实现原理 | 需注意注解作用范围(类/方法/字段) |
4.注解_超详细的元注解使用
1.概述:元注解就是管理注解的注解
2.从哪些方面管理呢?a.控制注解的使用位置控制注解是否能在类上使用控制注解是否能在方法上使用控制注解是否能在构造上使用等b.控制注解的生命周期(加载位置)控制注解是否能在源码中出现控制注解是否能在class文件中出现控制注解是否能在内存中出现3.怎么使用:a.@Target:控制注解的使用位置属性:ElementType[] value();ElementType是一个枚举,里面的成员可以类名直接调用ElementType中的成员:TYPE:控制注解能使用在类上FIELD:控制注解能使用在属性上METHOD:控制注解能使用在方法上PARAMETER:控制注解能使用在参数上CONSTRUCTOR:控制注解能使用在构造上LOCAL_VARIABLE:控制注解能使用在局部变量上 b.@Retention:控制注解的生命周期(加载位置)属性:RetentionPolicy value();RetentionPolicy是一个枚举,里面的成员可以类名直接调用RetentionPolicy中的成员:SOURCE:控制注解能在源码中出现 -> 默认CLASS:控制注解能在class文件中出现RUNTIME:控制注解能在内存中出现 @Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Book {//书名String bookName();//作者String[] author();//价格int price();//数量int count() default 10;
}## 注解再次解析(成功了)public class Test01 {public static void main(String[] args) {//1.获取BookShelf的class对象Class<BookShelf> bookShelfClass = BookShelf.class;//2.判断bookShelf上有没有Book注解boolean b = bookShelfClass.isAnnotationPresent(Book.class);//3.判断,如果b为true,就获取if (b){Book book = bookShelfClass.getAnnotation(Book.class);System.out.println(book.bookName());System.out.println(Arrays.toString(book.author()));System.out.println(book.price());System.out.println(book.count());}}
}
知识点 | 核心内容 | 易混淆点/关键细节 | 应用示例 |
注解(Annotation) | 用于为代码添加元数据的标记机制,需通过反射解析 | 默认注解仅存在于源码阶段,需通过元注解控制其生命周期和适用范围 | @Book 注解未加载到内存导致解析失败 |
元注解(Meta-Annotation) | 用于管理其他注解的注解(如 @Target、@Retention) | @Target 控制注解使用位置(类/方法/属性等),@Retention 控制生命周期(源码/Class/内存) | @Target(ElementType.TYPE) 限制注解仅用于类 |
@Target 参数 | 通过 ElementType 枚举指定注解作用目标(如 TYPE、METHOD、FIELD) | 未指定时注解可任意使用,显式定义后严格受限 | @Target({ElementType.TYPE, ElementType.METHOD}) 允许注解用于类和方法 |
@Retention 参数 | 通过 RetentionPolicy 枚举控制注解存在阶段(SOURCE/CLASS/RUNTIME) | RUNTIME 是反射解析的必要条件,默认值为 CLASS | @Retention(RetentionPolicy.RUNTIME) 确保注解在内存中可被解析 |
注解解析流程 | 反射机制读取内存中的注解信息 | 若注解未保留至 RUNTIME 阶段,反射无法获取其内容 | 修正 @Retention 后成功解析 @Book 注解 |
5.枚举的介绍和使用
## 1.枚举介绍1.概述:五大引用数据类型:类 数组 接口 注解 枚举2.定义:public enum 枚举类名{}所有的枚举类父类都是Enum3.定义枚举值:a.枚举值特点:都是static final,但是定义的时候不要写出来,写出来报错写完所有的枚举值之后,最后加个;枚举值名字要大写 -> 开发习惯b.使用:类名直接调用c.注意:每一个枚举值都是当前枚举类的对象 4.问题:枚举类中的枚举值都是什么类型的?本类类型5.枚举类中其他成员:构造在枚举类中定义的构造,默认都是private的6.枚举类的使用场景:表示对象的状态public enum State {//State WEIFUKUAN = new State()//State WEIFUKUAN = new State("未付款")WEIFUKUAN("未付款"),//State YIFUKUAN = new State()//State YIFUKUAN = new State("已付款")YIFUKUAN("已付款"),//State WEIFAHUO = new State()//State WEIFAHUO = new State("未发货")WEIFAHUO("未发货"),//State YIFAHUO = new State()//State YIFAHUO = new State("已发货")YIFAHUO("已发货");private String name;private State() {}State(String name) {this.name = name;}public String getName() {return name;}
}public class Test01 {public static void main(String[] args) {State weifahuo = State.WEIFAHUO;System.out.println(weifahuo);//默认调用toStringState yifukuan = State.YIFUKUAN;System.out.println(yifukuan.getName());}
}==============================================================================
## 2.枚举的方法_Enum| 方法名 | 说明 |
| ------------------ | ----------------------- |
| String toString() | 返回枚举值的名字 |
| values() | 返回所有与的枚举值 |
| valueOf(String str) | 将一个字符串转成枚举类型 |public enum State {//State WEIFUKUAN = new State()WEIFUKUAN("未付款"),//State YIFUKUAN = new State()YIFUKUAN("已付款"),//State WEIFAHUO = new State()WEIFAHUO("未发货"),//State YIFAHUO = new State()YIFAHUO("已发货");private String name;private State() {}State(String name) {this.name = name;}public String getName() {return name;}
}public class Test01 {public static void main(String[] args) {State weifahuo = State.WEIFAHUO;System.out.println(weifahuo);//默认调用toStringState yifukuan = State.YIFUKUAN;System.out.println(yifukuan.getName());System.out.println("====================");String string = State.WEIFUKUAN.toString();System.out.println("string = " + string);System.out.println("===================");State[] values = State.values();for (State value : values) {System.out.println(value);}System.out.println("==================");State yifahuo = State.valueOf("YIFAHUO");System.out.println("yifahuo = " + yifahuo);}
}
知识点 | 核心内容 | 易混淆点 | 应用场景 |
枚举定义 | 五大引用数据类型之一(类/数组/接口/注解/枚举) | 与常规类定义的区别 | 表示对象状态(如物流状态) |
枚举值特性 | 1. 本质是static final常量; 2. 每个枚举值都是枚举类的实例对象; 3. 命名规范要求大写 | 1. 不能显式写static final; 2. 枚举值后必须加分号(若定义其他成员) | 状态机实现、配置选项管理 |
枚举构造方法 | 1. 默认private修饰; 2. 支持有参构造(用于状态描述) | 显式声明public会报错 | 增强枚举可读性(中英文状态映射) |
常用方法 | 1. values(): 获取所有枚举值; 2. valueOf(): 字符串转枚举; 3. toString(): 获取枚举名 | valueOf()需严格匹配大小写 | 动态获取枚举集合、配置解析 |
开发规范 | 1. 枚举值命名全大写; 2. 通过有参构造附加描述信息; 3. 优先用枚举而非数字常量 | 小写命名虽可用但不专业 | 团队协作代码维护 |