分享

让我们一起来学习注解

 太极混元天尊 2018-04-13

什么是注解

注解(Annotation),也叫元数据。一种代码级别的说明。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释,解释或提示。能提高程序代码的可读性,以便于以后的参考、修改。注释是解释性文本,在运行程序时,会被程序跳过,不做处理。


注解的作用

1、生成文档。这是最常见的,也是Java 最早提供的注解。常用的有@see @param @return 等。

2、跟踪代码依赖性,实现替代配置文件功能。比较常见的是spring 2.5 开始的基于注解配置。作用就是减少配置。现在的框架基本都使用了这种配置来减少配置文件的数量。以后java的程序开发,最多的也将实现注解配置,具有很大用处。

3、在编译时进行格式检查。如@override 放在方法前,如果你这个方法并不是覆盖了超类方法,则编译时就能检查出


注解的语法

public @interface 注解的名字 {

        变量的类型 变量的名字();

        变量的类型 变量的名字() default 默认值;

}

1如果注解中只有一个变量需要赋值,并且这个变量的名字叫value,'value= '可以省略,直接写值。

2如果注解是数组类型,并且只赋值一个值,{}可以省略;如果赋值多个,则必须使用{......}。

3如果注解中有多个变量,且没有默认值,使用时,必须全部赋值;如果有默认值,使用时,有默认值可以赋值,也可以不赋值。


注解的分类

1、常见注解

a) @Override,表示当前的方法定义将覆盖超类中的方法。

b)@Deprecated,使用了注解为它的元素编译器将发出警告,因为注解@Deprecated是不赞成使用的代码,被弃用的代码。

c) @SuppressWarnings,关闭不当编译器警告信息。

i.deprecation,使用了过时的类戒方法时的警告。

ii.unchecked,执行了未检查的转换时的警告。

iii.fallthrough,当  Switch  程序块直接通往下一种情况而没有  Break  时的警告等等。


2、编写文档:通过代码里标识的元数据生成文档【生成文档doc文档】

a) @Param  注释的时候使用,在其它地方调用时有提示。

b) @Documented  让注解在导出的文档中显示。

首先看怎么导出文档:选中要导出成文档的项目->project->Generate Javadoc…

单击next->next->finish。

当在注解的前面加上@Documented,该注解就会生成在文档中。

导出文档,如果乱码: javadoc -encoding UTF-8 -charset UTF-8。


3、代码分析:通过代码里标识的元数据对代码进行分析【使用反射】

c) @Target,限定注解可以放的位置。

@Target(

    {

       TYPE,  放在类的头部

       FIELD, 放在字段的头部

       METHOD, 放在方法的头部

       PARAMETER, 放在参数的头部

       CONSTRUCTOR, 放在构造器的头部

       LOCAL_VARIABLE 放在局部变量的头部

    }

)

d)@Retention,限定注解的生命周期。source(只在java源码时候有效,编译之后失效),class(只在编译时有效),runtime(运行时有效,最常用的)。

e) 自定义一些功能注解。


注解的使用

示例:
package cn.com.javazysq.test1;
/**
* 自定义注解
* 这个注解里有三个变量,其中id已经有默认值了
*/
public @interface MyAnnotation {
      //private int id() default 110; 错误的,only public & abstract are permitted
      int id() default 110;
      String name() default 'abc';
      float value();
}

package cn.com.javazysq.test1;
/**
* 自定义注解
*/
public @interface MyAnnotation2 {
      int id() default 110;
      String name() default 'abc';
      float[] value();
}

package cn.com.javazysq.test1;
/**
* 自定义注解
*/
public @interface MyAnnotation3 {
      int id() default 110;
      String name() default 'abc';
      Sex[] value();
}

package cn.com.javazysq.test1;
/**
* 自定义注解
* 只能放在方法的头部
* 只有在运行的时候才有效果
*/
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation4 {
      int id() default 110;
}

package cn.com.javazysq.test1;
public enum Sex {
      男,女
}

//测试@Param...
package cn.com.javazysq.test1;
public class AnnotationTest {
      public static void main(String[] args) {
             User u= new User(1, '');
             u.sum(1, 2);
      }
}

package cn.com.javazysq.test1;
@MyAnnotation(name='张三',value = 59.9F)
public class User {
      @MyAnnotation(name='张三',value = 59.9F)
      private int id;
      private String name;
      public int getId() {
             return id;
      }
      @MyAnnotation(59.9F)
      @MyAnnotation2(value={1,2,3})
      @MyAnnotation3(Sex.女)
      @MyAnnotation4()
      public void setId(int id) {
             this.id = id;
      }
      @MyAnnotation2(1)
      public String getName() {
             return name;
      }
      @MyAnnotation3(value={Sex.女,Sex.男})
      public void setName(String name) {
             this.name = name;
      }
      @Override
      public String toString() {
             return super.toString();
      }
      /**
       * 构造方法
       * @param id    编号
       * @param name      名字
       */
      public User(int id, String name) {
             this.id = id;
             this.name = name;
      }
      /**
       * 求和
       * @param a 数字1
       * @param b 数字2
       * @return 两个数字的和
       */
      public int sum(int a,int b){
             return a+b;
      }
}

登陆案例,见代码:
package cn.com.javazysq.test2;
/**
* 自定义注解
* 限定:
* 1.只能放在方法的头部
* 2.只能在运行时有效
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LoginAnnotation {
      String name();
      String pwd();
}

package cn.com.javazysq.test2;
public class UserService {
      @LoginAnnotation(name='bochy',pwd='123dd')
      public boolean login(String name,String pwd){
             if('bochy'.equals(name)&&'123'.equals(pwd)){
                    return true;
             }else{
                    return false;
             }
      }
}

package cn.com.javazysq.test2;
import java.lang.reflect.Method;
public class Test {
      public static void main(String[] args) throws Exception {
             String className='cn.com.bochy.test2.UserService';
             String methodName = 'login';
             /*获取运行时对象*/
             Class c = Class.forName(className);
             /*调用无参的构造方法实例化对象*/
             Object obj = c.newInstance();
             /*获取方法对象*/
             Method m = c.getMethod(methodName, String.class,String.class);
             //获取注解
             LoginAnnotation loginAnnotation = m.getAnnotation(LoginAnnotation.class);
             if(loginAnnotation==null){
                    System.out.println('没有找到注解');
                    return;
             }
             
             //获取注解里的值
             String name = loginAnnotation.name();
             String pwd = loginAnnotation.pwd();
             //调用方法
             boolean ret = (boolean) m.invoke(obj, name,pwd);
             System.out.println(ret);
      }
}
Java资源社区

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多