java注解的学习

一、为什么学习java注解?

java注解是在1.5时,才有的特性。对于安卓的开发者来说,可能用到注解的地方比较少,但我们也会涉及到一些常用的注解:比如:1、@Override当我们重写一个方法时,该注释表示这个方法是重写    
    2、@Deprecated在安卓中一些老版本SDK的方法会被丢弃    
    3、@SuppressWarnings表示去掉某个警告。
   警告是分等级的:
           deprecation   使用了过时的类或方法时的警告
       unchecked  执行了未检查的转换时的警告,例如当使用集合时没有用泛型 (Generics) 来指定集合保存的类型
               fallthrough   当 Switch 程序块直接通往下一种情况而没有 Break 时的警告
               path   在类路径、源文件路径等中有不存在的路径时的警告
               serial 当在可序列化的类上缺少 serialVersionUID 定义时的警告
               finally    任何 finally 子句不能正常完成时的警告
               all 关于以上所有情况的警告
        但是在开发的过程中,我们并没有真正的去用过注释,也许你在gson中用到过。
        java注释一般在java开发中用的比较多有依赖注入等框架,前两天看到Dagger2看到好多的都是和注解有关的,所以拿出点时间来学习下。

二、java注解的元注解

       我们可以定义一个我们自己的注解:
<pre name="code" class="java">    public @interface MyAnotation {

       }


       什么是元注解?
      
       @interface 后面的名称就是注解的名字,这就是一个简单的注解
       所谓的元注解,就是可以注解我们自定义的注解的元注解。
以下都以我们自定义个这个MyAnotation为例来解释。

1、@Retention 

@Retention(RetentionPolisy.RUNTIME)
   public @interface MyAnotation {

   }
在我们自定义的注解上注解Retention注解的话就会对我们的注解起到保留策略:是在源代码中,还是在class文件中,还是在运行中都可见。
分为以下三种类型:
     ①Retention.SOURCE仅在源代码中可见,在被MyAnotation注解的类编译后的class文件中是看不到我们的MyAnotation的注解的
    ②Retention.CLASS 在源代码和class中都可见,但是在运行时就不可见了,
    ③Retention.RUNTIME 在源代码,在class中,在运行时都是可见的,我们可以通过反射得到我们的MyAnotation

2、@Target

 @Target(ElimentType.TYPE)
   public @interface MyAnotation {

   }
@Target(ElementType.TYPE)    // 注解我们的自定义注释后,我们的注释可以在接口、类、枚举、注解,上注释,不能应用于方法,局部变量等其他类型
@Target(ElementType.FIELD)  // 字段、枚举的常量
@Target(ElementType.METHOD)  // 方法
@Target(ElementType.PARAMETER)  // 方法参数
@Target(ElementType.CONSTRUCTOR)   // 构造函数
@Target(ElementType.LOCAL_VARIABLE) // 局部变量
@Target(ElementType.ANNOTATION_TYPE) // 注解
复合的方式,比如我们想我们自定义的注释既能应用于类,又能应用于方法那么我们就这样写元注解
@Target(ElementType.TYPE,ElementType.METHOD)

3、@Document

 @Document
   public @interface MyAnotation {

   }
 这样我们的自定义注解MyAnotation在注视到一个类或者方法中,那么我们的注释在javadoc中是可以看到的

4、@Inherited

子类可以继承父类中的注解
  @Document
  @Inherited
  @Retention(RetentionType.RUNTIM)
  @Target(ElementType.TYPE)
   public @interface MyAnotation {

   }

举例说明:
如果我们自定义注解在我们的一个类中如
我们自定义注解AnotationTest2
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Inherited
public @interface AnotationTest2 {
	abstract String value() default "默认值";
}


@AnotationTest2(value="sss")
public class Test {
	
	
}
然后:TestImp继承Test类
public class TestImp extends Test {
	
	
	public void testImp(){
		
	}
	
	public static void main(String[] args){
		try {
			ParseAnnotation.parseType(TestImp.class);
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
类ParseAnotation类
public class ParseAnnotation {
	
	public static void parseMethod(Class clazz) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException{
		Object obj = clazz.getConstructor(new Class[]{}).newInstance(new Object[]{});
		for(Method method:clazz.getDeclaredMethods()){
			AnotationTest1 anotation1 = method.getAnnotation(AnotationTest1.class);
			if(anotation1!=null){
				String value;
				value = anotation1.value();
				method.invoke(obj, value);
			}
		}
	}
	
	public static void parseType(Class clazz) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException{
		
		AnotationTest2 anotation2 = (AnotationTest2) clazz.getAnnotation(AnotationTest2.class);
			if(anotation2!=null){
				String value;
				value = anotation2.value();
				System.out.println("我的values:"+value);
			}
	}
}

如果AnotationTest2中的元注解有@Inherited的话,那么在子类TestImp中通过ParseAnotaion.parseType()方法就可以得到父类AnotationTest2的注解并获得注解中的值。如果我们去掉@Inherited的话,就获取不到Anotation的对象,anotation2为null。

三、自定义注解

在上面中我们已经涉及到自定义注解AnotationTest2。
我们除了为自定义注解设置元注解的属性外,我们还可以为自定义注解设置一些基本的属性。
@Inherited
public @interface Greeting {
   String name() default "蓝色";  
   public enum FontColor{ BULE,RED,GREEN};
   FontColor fontColor() default FontColor.GREEN;
}
name是我们为自定义注释Greeting添加变量,同时我们还可以为其设置 默认值
String name();
如果我们没有设置默认值的话,那么在设置属性的时候必须为name属性设置值
自定义注解 中还可以定义枚举类型,并同时设置枚举的变量。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值