`
sungang_1120
  • 浏览: 323529 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类

JAVA自定义注解与通过反射去解析注解参数

 
阅读更多

 

一,概念:

 

注解是 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自定义注解的一个小例子,深入的在去研究,先入个门再说,呵呵........

 

 

分享到:
评论

相关推荐

    【面试必备】JAVA 最常见面试题全解析 附 PDF.pdf_java面试_javapdf_java_面试题_

    4. 枚举与注解:枚举的使用,注解的定义和元注解,以及注解在反射中的应用。 三、高级篇 1. 内存管理:JVM内存模型,堆内存、栈内存、方法区,以及垃圾收集机制(GC)的工作原理。 2. 类加载器:理解双亲委派模型,...

    疯狂JAVA讲义课后习题解析.pdf

    8. **反射和注解**:介绍了JAVA的反射机制,如何在运行时获取类信息和动态调用方法,以及注解的使用场景和自定义注解的创建。这些习题解析将加深读者对JAVA动态性及元编程的理解。 9. **JDBC数据库编程**:讲解了...

    JAVA解惑.大全和问题解析

    - 注解的使用,如@Override、@Deprecated等,以及自定义注解。 - APT(Annotation Processing Tool):利用注解进行源码生成。 10. **JVM优化**: - 参数调整:了解JVM的启动参数,如堆大小、新生代比例等,以...

    Java最新开发手册(黄山版)

    2. 注解:讲解注解的定义、使用和元注解,以及如何自定义注解并进行处理。 七、JVM优化 1. 内存模型:分析JVM的内存结构,包括堆、栈、方法区等,理解内存溢出问题。 2. 类加载机制:阐述类的加载、验证、准备、...

    java八股文共10章八股文.rar

    - 自定义注解:创建、使用和解析自定义注解。 - 元注解:@Override、@Deprecated、@ SuppressWarnings等元注解的作用和使用场景。 以上知识点覆盖了Java编程的大部分核心内容,熟练掌握这些知识将有助于你在面试...

    Mybatis注解手写源码篇

    这涉及到对Java反射、注解处理、JDBC API的深入理解和运用。同时,我们还需要理解Mybatis是如何通过动态代理生成Mapper实例的,以便在运行时调用我们自定义的SQL执行逻辑。 通过这个手写源码的过程,开发者不仅可以...

    Java中高级核心知识全面解析

    8. **注解与元编程**:了解自定义注解的创建和使用,以及如何通过反射利用注解实现元编程功能。 9. **Spring框架**:理解IoC(控制反转)和DI(依赖注入)的概念,学习Spring的核心模块,如Bean管理、AOP、事务管理...

    (小鱼)sun公司java培训资料

    17. 注解:了解注解的元数据功能,以及自定义注解和使用反射处理注解。 七、Java虚拟机(JVM) 18. 内存管理:理解JVM内存模型,包括堆、栈、方法区、本地方法栈等区域的用途。 19. 垃圾回收:探讨垃圾收集器的工作...

    Java课程PPT含有例题及解析

    12. **枚举与注解**:讲解枚举类型以及其在Java中的使用,以及注解(Annotation)的定义、使用和元注解。 13. **IO和NIO**:对比传统IO和New IO(NIO)的区别,介绍NIO的非阻塞特性,通道(Channel)和缓冲区...

    Java开发技术大全 清晰版

    14. 注解:自定义注解,了解编译时注解和运行时注解,以及元注解的使用。 七、JVM 15. 类加载机制:类加载过程(加载、验证、准备、解析、初始化),双亲委派模型。 16. 内存区域:堆、栈、方法区、本地方法栈、...

    面试题汇总:Markdown编写,作为Java知识库提供给Java面试必考小程序使用.zip

    7. **反射与注解**:反射的概念、API使用,动态代理,以及注解的定义、元注解、自定义注解及其实现原理。 8. **设计模式**:常见的23种设计模式,如单例、工厂、装饰、观察者、适配器、代理、建造者等模式在实际...

    【Java面试资料】-(机构内训资料)深圳-银盛支付-Java中级

    2. 注解:自定义注解,元注解,使用反射获取注解信息。 六、网络编程 1. Socket编程:TCP和UDP通信的基本原理与实现。 2. HTTP协议:了解HTTP请求与响应的结构,模拟发送HTTP请求。 七、Spring框架 1. Spring核心...

    JAVA笔试面试宝典--JAVA笔试面试必看

    2. 注解:理解元数据的概念,自定义注解,注解的处理机制,如Java的保留注解如@Override、@Deprecated等。 七、JVM优化 1. 类加载机制:理解双亲委派模型,类加载器的工作原理。 2. 垃圾回收:了解GC的工作过程,...

    java 核心(上下册)

    2. **注解(Annotation)**:介绍注解的使用,元注解,自定义注解以及如何通过反射处理注解。 3. **Java集合高级主题**:包括并发集合,如ConcurrentHashMap,以及Map的高级特性,如NavigableMap和TreeMap。 4. **...

    CoreJava上下册

    5. **Java注解**:阐述注解的作用,自定义注解的创建,以及如何在编译时和运行时处理注解。 6. **Java数据库编程**:通过JDBC(Java Database Connectivity)介绍如何与各种数据库进行交互,包括连接,查询,事务...

    java(ppt)课件

    9. **反射与注解**:解释Java反射机制,如何在运行时动态获取类信息,以及注解的使用和自定义注解。 10. **Java泛型**:理解泛型的引入,其在集合、接口和方法中的应用,以及类型擦除的概念。 11. **Java GUI编程*...

    Java高级实用教程

    理解注解的定义、使用及自定义注解,如@Override、@Deprecated、@ SuppressWarnings,以及元注解,能够改善代码的可维护性和可读性。 7. **枚举**:Java的枚举类型增强了传统的常量表示,提供了更安全的类型系统。...

    java笔试题大集合及答案(另附各大公司笔试题)

    2. 注解:理解元数据的概念,自定义注解以及使用反射处理注解。 八、Java框架 1. Spring:依赖注入、AOP、事务管理等核心概念。 2. MyBatis:SQL映射文件、动态SQL、缓存机制等。 3. Struts或Spring MVC:MVC设计...

    JAVA书本复习题答案整合

    复习题可能要求你利用反射创建和操作对象,或者理解注解的使用和自定义注解的实现。 9. **Java Swing与JavaFX**:这两个是Java的图形用户界面(GUI)库,复习题可能涉及组件的使用、布局管理器、事件处理等,帮助你...

    《Java语言程序设计(进阶篇)》 课后习题第23章代码chapter23.rar

    习题可能包含了自定义注解及其处理器的实现。 通过这个压缩包中的代码,读者可以实践以上各个知识点,进一步巩固理论学习。解压并分析这些代码,对于深化对Java语言的理解和提升编程技能是非常有益的。

Global site tag (gtag.js) - Google Analytics