一,概念:
注解是 JDK5 引入的新特性,最初衍生自代码注释,但现在早已经超出了注释的范畴,以至于我很惶恐,不敢使用注释这个词汇来描述他,尽管现有的很多资料里仍然称其为注释。如果说反射使得很多技术实现(动态代理、依赖注入等)有了基础,那么注解就是使这些技术实现变得平民化的基础。
从 class 文件规范中可以看出, JDK5 开始, class 文件已经引入了注解描述片段。站在 java 虚拟机的角度来看, class 保留和运行时保留的注解已经和 java 二进制码放在了同等的地位。虚拟机在加载 class 文件时,会为注解内容分配空间并进行解析,最终还会为注解和对应的二进制码建立关联。尽管这些注解不会被运行,但其对代码的说明能力,结合反射技术已经足够我们做太多的事情。
我们知道, java 除了内置的注解( @Override 、 @Deprecated 等)以外,还支持自定义注解( Struts 、 Hibernate 等很多框架甚至 java 自身都实现了很多自定义注解)。当然,更为厉害的是元注解,元注解是用来描述注解的注解。
要实现一个自定义注解,必须通过 @interface 关键字来定义。且在 @interface 之前,需要通过元注解来描述该注解的使用范围( @Target )、生命周期( @Retention )及其他(其他的不重要)
@Target 用于描述注解的使用范围(即:被描述的注解可以用在什么地方),其取值有:
取值 | 描述 |
CONSTRUCTOR | 用于描述构造器 |
FIELD | 用于描述域 |
LOCAL_VARIABLE | 用于描述局部变量 |
METHOD | 用于描述方法 |
PACKAGE | 用于描述包 |
PARAMETER | 用于描述参数 |
TYPE | 用于描述类或接口(甚至 enum ) |
@Retention 用于描述注解的生命周期(即:被描述的注解在什么范围内有效),其取值有:
取值 | 描述 |
SOURCE | 在源文件中有效 |
CLASS | 在 class 文件中有效 |
RUNTIME | 在运行时有效(即运行时保留 常用) |
下面直接看例子:
首先定义几种不同类型的注解方式
1,作用于类上面的
@Target(ElementType.TYPE)//用于描述类或接口 @Retention(RetentionPolicy.RUNTIME) public @interface MyClassAnnotation { String uri(); String desc(); }
2,作用于字段上面的
@Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface MyFieldAnnotation { String uri(); String desc(); }
3,作用于构造上面的
@Target(ElementType.CONSTRUCTOR) @Retention(RetentionPolicy.RUNTIME) public @interface MyConstructorAnnotation { String uri(); String desc(); }
4,作用于方法上面
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface MyMethodAnnotation { String uri(); String desc(); }
通过实例看看怎么使用吧....
public class MyAllAnnotationTest { @SuppressWarnings("unchecked") public static void main(String[] args) { MySample sample = new MySample(); Class clazz = sample.getClass(); //类 boolean c = clazz.isAnnotationPresent(MyClassAnnotation.class); if (c) { MyClassAnnotation myClassAnnotation = (MyClassAnnotation) clazz.getAnnotation(MyClassAnnotation.class); printMyClassAnnotation(myClassAnnotation); } //构造 Constructor[] constructors = clazz.getConstructors(); for (Constructor constructor : constructors) { boolean cc = constructor.isAnnotationPresent(MyConstructorAnnotation.class); if (cc) { MyConstructorAnnotation myConstructorAnnotation = (MyConstructorAnnotation) constructor.getAnnotation(MyConstructorAnnotation.class); printMyConstructorAnnotation(myConstructorAnnotation); } } //字段 Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { boolean f = field.isAnnotationPresent(MyFieldAnnotation.class); if (f) { MyFieldAnnotation myFieldAnnotation = (MyFieldAnnotation)field.getAnnotation(MyFieldAnnotation.class); printMyFieldAnnotation(myFieldAnnotation); } } //方法 Method[] methods = clazz.getDeclaredMethods(); for (Method method : methods) { boolean m = method.isAnnotationPresent(MyMethodAnnotation.class); if (m) { MyMethodAnnotation methodAnnotation = (MyMethodAnnotation)method.getAnnotation(MyMethodAnnotation.class); printMyMethodAnnotation(methodAnnotation); } } } public static void printMyClassAnnotation(MyClassAnnotation myClassAnnotation){ if (null == myClassAnnotation) { return; } System.out.println("url = " + myClassAnnotation.url()); System.out.println("desc = " + myClassAnnotation.desc()); } public static void printMyConstructorAnnotation(MyConstructorAnnotation myConstructorAnnotation){ if (null == myConstructorAnnotation) { return; } System.out.println("url = " + myConstructorAnnotation.url()); System.out.println("desc = " + myConstructorAnnotation.desc()); } public static void printMyFieldAnnotation(MyFieldAnnotation myFieldAnnotation){ if (null == myFieldAnnotation) { return; } System.out.println("url = " + myFieldAnnotation.url()); System.out.println("desc = " + myFieldAnnotation.desc()); } public static void printMyMethodAnnotation(MyMethodAnnotation methodAnnotation){ if (null == methodAnnotation) { return; } System.out.println("url = " + methodAnnotation.url()); }
打印结果如下所示:
url = cn.cd.sg.test.reflect.MySample desc = The Class Name For MySample url = cn.cd.sg.test.reflect.MySample#MySample For Constructor desc = The default constuctor Name For MySample() url = cn.cd.sg.test.reflect.MySample#id desc = The Field Name For Id url = cn.cd.sg.test.reflect.MySample#name desc = The Field Name For Name url = cn.cd.sg.test.reflect.MySample#setId desc = The Mrthod Name For setId() url = cn.cd.sg.test.reflect.MySample#getName desc = The Mrthod Name For getName() url = cn.cd.sg.test.reflect.MySample#getId desc = The Mrthod Name For getId() url = com.sg.annotation.MySample#setName desc = The Mrthod Name For setName()
以上就是JAVA自定义注解的一个小例子,深入的在去研究,先入个门再说,呵呵........
相关推荐
4. 枚举与注解:枚举的使用,注解的定义和元注解,以及注解在反射中的应用。 三、高级篇 1. 内存管理:JVM内存模型,堆内存、栈内存、方法区,以及垃圾收集机制(GC)的工作原理。 2. 类加载器:理解双亲委派模型,...
8. **反射和注解**:介绍了JAVA的反射机制,如何在运行时获取类信息和动态调用方法,以及注解的使用场景和自定义注解的创建。这些习题解析将加深读者对JAVA动态性及元编程的理解。 9. **JDBC数据库编程**:讲解了...
- 注解的使用,如@Override、@Deprecated等,以及自定义注解。 - APT(Annotation Processing Tool):利用注解进行源码生成。 10. **JVM优化**: - 参数调整:了解JVM的启动参数,如堆大小、新生代比例等,以...
2. 注解:讲解注解的定义、使用和元注解,以及如何自定义注解并进行处理。 七、JVM优化 1. 内存模型:分析JVM的内存结构,包括堆、栈、方法区等,理解内存溢出问题。 2. 类加载机制:阐述类的加载、验证、准备、...
- 自定义注解:创建、使用和解析自定义注解。 - 元注解:@Override、@Deprecated、@ SuppressWarnings等元注解的作用和使用场景。 以上知识点覆盖了Java编程的大部分核心内容,熟练掌握这些知识将有助于你在面试...
这涉及到对Java反射、注解处理、JDBC API的深入理解和运用。同时,我们还需要理解Mybatis是如何通过动态代理生成Mapper实例的,以便在运行时调用我们自定义的SQL执行逻辑。 通过这个手写源码的过程,开发者不仅可以...
8. **注解与元编程**:了解自定义注解的创建和使用,以及如何通过反射利用注解实现元编程功能。 9. **Spring框架**:理解IoC(控制反转)和DI(依赖注入)的概念,学习Spring的核心模块,如Bean管理、AOP、事务管理...
17. 注解:了解注解的元数据功能,以及自定义注解和使用反射处理注解。 七、Java虚拟机(JVM) 18. 内存管理:理解JVM内存模型,包括堆、栈、方法区、本地方法栈等区域的用途。 19. 垃圾回收:探讨垃圾收集器的工作...
12. **枚举与注解**:讲解枚举类型以及其在Java中的使用,以及注解(Annotation)的定义、使用和元注解。 13. **IO和NIO**:对比传统IO和New IO(NIO)的区别,介绍NIO的非阻塞特性,通道(Channel)和缓冲区...
14. 注解:自定义注解,了解编译时注解和运行时注解,以及元注解的使用。 七、JVM 15. 类加载机制:类加载过程(加载、验证、准备、解析、初始化),双亲委派模型。 16. 内存区域:堆、栈、方法区、本地方法栈、...
7. **反射与注解**:反射的概念、API使用,动态代理,以及注解的定义、元注解、自定义注解及其实现原理。 8. **设计模式**:常见的23种设计模式,如单例、工厂、装饰、观察者、适配器、代理、建造者等模式在实际...
2. 注解:自定义注解,元注解,使用反射获取注解信息。 六、网络编程 1. Socket编程:TCP和UDP通信的基本原理与实现。 2. HTTP协议:了解HTTP请求与响应的结构,模拟发送HTTP请求。 七、Spring框架 1. Spring核心...
2. 注解:理解元数据的概念,自定义注解,注解的处理机制,如Java的保留注解如@Override、@Deprecated等。 七、JVM优化 1. 类加载机制:理解双亲委派模型,类加载器的工作原理。 2. 垃圾回收:了解GC的工作过程,...
2. **注解(Annotation)**:介绍注解的使用,元注解,自定义注解以及如何通过反射处理注解。 3. **Java集合高级主题**:包括并发集合,如ConcurrentHashMap,以及Map的高级特性,如NavigableMap和TreeMap。 4. **...
5. **Java注解**:阐述注解的作用,自定义注解的创建,以及如何在编译时和运行时处理注解。 6. **Java数据库编程**:通过JDBC(Java Database Connectivity)介绍如何与各种数据库进行交互,包括连接,查询,事务...
9. **反射与注解**:解释Java反射机制,如何在运行时动态获取类信息,以及注解的使用和自定义注解。 10. **Java泛型**:理解泛型的引入,其在集合、接口和方法中的应用,以及类型擦除的概念。 11. **Java GUI编程*...
理解注解的定义、使用及自定义注解,如@Override、@Deprecated、@ SuppressWarnings,以及元注解,能够改善代码的可维护性和可读性。 7. **枚举**:Java的枚举类型增强了传统的常量表示,提供了更安全的类型系统。...
2. 注解:理解元数据的概念,自定义注解以及使用反射处理注解。 八、Java框架 1. Spring:依赖注入、AOP、事务管理等核心概念。 2. MyBatis:SQL映射文件、动态SQL、缓存机制等。 3. Struts或Spring MVC:MVC设计...
复习题可能要求你利用反射创建和操作对象,或者理解注解的使用和自定义注解的实现。 9. **Java Swing与JavaFX**:这两个是Java的图形用户界面(GUI)库,复习题可能涉及组件的使用、布局管理器、事件处理等,帮助你...
习题可能包含了自定义注解及其处理器的实现。 通过这个压缩包中的代码,读者可以实践以上各个知识点,进一步巩固理论学习。解压并分析这些代码,对于深化对Java语言的理解和提升编程技能是非常有益的。