您的位置:首页 > 编程语言 > Java开发

java注解的学习

2016-02-04 12:47 609 查看

一、为什么学习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属性设置值
自定义注解 中还可以定义枚举类型,并同时设置枚举的变量。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: