Java注解

总结

1.注解只是相当于一种标识,标志着被修饰的类,方法,属性等应该具有的公共的功能。这一点可以从注解的源码看 出来,注解的源码只有属性变量,并没有方法;这些属性变量的不同取值映射为不同的功能
2.通过反射解析出注解的属性值,并根据属性值是否为指定的值,来判断是否执行相关代码

1:Java中常见注解

详细介绍:基本内置注解

  1. @Override
    用在方法上,表示这个方法重写了父类的方法,如toString()。
  2. @Deprecated
    表示这个方法已经过期,不建议开发者使用。(暗示在将来某个不确定的版本,就有可能会取消掉)
  3. @SafeVarargs
    参数安全类型注解。它的目的是提醒开发者不要用参数做一些不安全的操作,它的存在会阻止编译器产生 unchecked 这样的警告
  4. @FunctionalInterface
    用于约定函数式接口。 如果接口中只有一个抽象方法(可以包含多个默认方法或多个static方法),该接口称为函数式接口。函数式接口其存在的意义,主要是配合Lambda 表达式 来使用。

2: 注解分类

按运行机制分:

  1. 源码注解
    注解只在源码中存在,编译成.class文件就不存在了
  2. **编译时注解 **
    注解在源码和.class文件中都会存在。比如说@Override
  3. **运行时注解 **
    在运行阶段还会起作用,甚至会影响运行逻辑的注解。比如说@Autowired

3:自定义注解

  1. **自定义注解的语法要求 **
package grammar;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;



/**
* @Description  自定义注解的语法要求
* @since  2018年10月29日 下午4:47:07
* @author 
*/

/*****************   元注解    **********************************/
/*@Target 表示这个注解能放在什么位置上,是只能放在类上?还是即可以放在方法上,又可以放在属性上
 * 
 *  ElementType.TYPE:能修饰类、接口或枚举类型
	ElementType.FIELD:能修饰成员变量
	ElementType.METHOD:能修饰方法
	ElementType.PARAMETER:能修饰参数
	ElementType.CONSTRUCTOR:能修饰构造器
	ElementType.LOCAL_VARIABLE:能修饰局部变量
	ElementType.ANNOTATION_TYPE:能修饰注解
	ElementType.PACKAGE:能修饰包 
 * */
@Target({ElementType.METHOD ,  ElementType.TYPE})

/*@Retention 
 * 表示生命周期,
 * 
 * RetentionPolicy.SOURCE: 注解只在源代码中存在,编译成class之后,就没了。@Override 就是这种注解
 * 
 * RetentionPolicy.CLASS: 注解在java文件编程成.class文件后,依然存在,但是运行起来后就没了
 * 						  @Retention的默认值,即当没有显式指定@Retention的时候,就会是这种类型。
 * 
 * RetentionPolicy.RUNTIME: 注解在运行起来之后依然存在,程序可以通过反射获取这些信息
 * 
 * */
@Retention( RetentionPolicy.RUNTIME)

/*@Inherited 表示该注解具有继承性
如果一个超类被 @Inherited 注解过的注解进行注解的话,那么如果它的子类没有被任何注解应用的话,那么这个子类就继承了超类的注解。*/
@Inherited

//元注解肯定是和文档有关。它的作用是能够将注解中的元素包含到 Javadoc 中去
@Documented

//使用 @interface 关键字定义注解
public @interface Description {
	
	/* 成员变量
	 * 1. 注解的定义中以“无形参的方法”形式来声明,其方法名定义了该成员变量的名字,其返回值定义了该成员变量的类型
	 * 
	 * 2. 注解中定义属性时它的类型必须是 8 种基本数据类型外加 类、接口、注解及它们的数组
	 * 
	 * 3. 如果注解只有一个成员,则成员名必须取名为 value() ,在使用时可以忽略成员名和赋值号(=)
	 * 
	 * 4. 注解类可以没有成员,没有成员的注解称为标识注解
	 * */
	
	String desc();
	
	String author();
	
	//可以用 default 为成员指定一个默认的值
	int age() default 18;
}
  1. **使用自定义注解 **
@<注解名>(<成员名1>=<成员值1>,<成员名2>=<成员值2>,..)
package grammar;
@Description(desc="I am" ,author="liu",age=22)
public class UseAnnotation {
	public String Test() {
		return "red";
	}
}
  1. **解析注解 **
    概念: 通过反射获取类、函数或成员上的运行时注解信息,从而实现动态控制程序运行的逻辑。注意,解析注解时, @Retention(RetentionPolicy.RUNTIME) 是必须的。
    1. 先获取类对象
    2. 类对象调用 isAnnotationPresent(Class<? extends Annotation> annotationClass)判断是否应用了某个注解
    3. 通过 getAnnotation() 方法来获取 Annotation 对象,或者getAnnotations() 方法获取所有应用在该类上的注解

示例:
注解类:

package grammar;
@Target({ElementType.METHOD ,  ElementType.TYPE})
@Retention( RetentionPolicy.RUNTIME)
@Inherited
@Documented

public @interface DesSimple {
	String value();
}

应用注解类:

package grammar;
@DesSimple("this is a type ano")
public class Child {
	
	@DesSimple("this is a method ano")
	public String name() {
		return "name";
	}
}

解析注解类:

package grammar;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
public class ParseAnnotation {
	public static void main(String[] args) {
		try {
			//1.使用类加载器加载类对象
			Class clazz = Class.forName("grammar.Child");
			//2. 判断是否应用了这个注解
			boolean hasAnno = clazz.isAnnotationPresent(DesSimple.class); 
			//3. 获取Annotation对象
			if(hasAnno) {
				DesSimple ds = (DesSimple)clazz.getAnnotation(DesSimple.class);
				System.out.println(ds.value());
			}
			//4. 找到方法上的注解
			Method[] ms = clazz.getMethods();
			/********  第一种解析方式 ************/
			for(Method m:ms) {
				boolean isMExist = m.isAnnotationPresent(DesSimple.class);
				if(isMExist ) {
					DesSimple dsm = (DesSimple)m.getAnnotation(DesSimple.class);
					System.out.println(dsm.value());
				}
			}
			
			/************  另一种解析方式   ******************/
			for(Method m: ms) {
				Annotation[] ans = m.getAnnotations();//获取所有注解在该方法上的注解
				for(Annotation an:ans) {
					if(an instanceof DesSimple) {
						DesSimple desSimple = (DesSimple)an;
						System.out.println(desSimple.value());
					}
				}
			}
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值