有用的Java注解

java

好处:

能够读懂别人的代码,特别是框架相关的代码;

让编程更加简洁,代码更加清晰。

使用自定义注解解决问题!!

Java1.5版本引入。

Java中的常见注解

  • @Override:告诉使用者及编译器,该方法覆盖了父类或接口中的同名方法
  • @Deprecated:表示该方法已经过时了。
  • @Suppvisewarnings:忽略deprecated给出的警告。
  • 常见第三方注解:

    • Spring: @Autowired, @Service, @Repository
    • Mybatis: @InsertProvider, @UpdateProvider, @Options

注解分类

  • 按照运行机制分:

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

  • 按照来源分:

    • 来自JDK的注解
    • 来自第三方的注解
    • 自己定义的注解

  • 元注解:注解的注解

自定义注解

  • 语法要求

    • 成员类型是受限的,合法的类型包括原始类型及String,Class,Annotation,Enumeration;
    • 如果注解只有一个成员,则成员们必须取名为value(),在使用时可以忽略成员名和赋值号(=);
    • 注解类可以没有成员,没有成员的注解类成为标识注解;

  • 元注解(注解的注解)

    • @Target(……)
    • @Retention:生命周期(SOURCE:只在源码显示编译时丢弃;CLASS:编译时会记录到class中,运行时忽略;RUNTIME:运行时存在,可以通过反射读取)
    • @Inherited:允许子类继承,只能在类或者抽象类间继承,接口是不会继承的。而且继承时只是类的继承,类中的方法并不会继承。
    • @Documented:生成javadoc时会包含信息。

      • 到处一个Javadoc:在工程上点击Export->javadoc->设置路径,通过index.html即可查看你导出的Javadoc

  • 使用自定义注解

解析注解

  • 概念:通过反射获取类、函数或成员上的运行时注解信息,从而实现动态控制程序运行的逻辑。
  • //实例:拿到类名字的解释

    public class ParseAnn {

    public static void main(String[] args) {

    //1.使用类加载器加载类

    try {

    Class c = Class.forName("com.ann.test.Child");

    //2.找到类上面的注解

    boolean isExist = c.isAnnotationPresent(Description.class);

    if(isExist) {

    //3.拿到注解实例

    Description d = (Description) c.getAnnotation(Description.class);

    System.out.println(d.value());

    }

    //4.找到方法上的注解

    Method[] ms = c.getMethods();

    for(Method m : ms) {

    boolean isMExist = m.isAnnotationPresent(Description.class);

    if(isMExist) {

    Description d = (Description) m.getAnnotation(Description.class);

    System.out.println(d.value());

    }

    }

    //另外一种解析方法

    for(Method m : ms) {

    Annotation[] as = m.getAnnotations();

    for(Annotation a : as) {

    if(a instanceof Description) {

    Description d = (Description)a;

    System.out.println(d.value());

    }

    }

    }

    } catch (ClassNotFoundException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    }

    }

    }

    View Code 

  • //Child.java信息

    @Description("I am class annotation")

    public class Child implements Person {

    @Override

    @Description("I am method annotation")

    public String name() {

    // TODO Auto-generated method stub

    return null;

    }

    @Override

    public int age() {

    // TODO Auto-generated method stub

    return 0;

    }

    @Override

    public void sing() {

    // TODO Auto-generated method stub

    }

    }

    View Code

实践

  • 项目取自一个公司的持久层框架,用来代替Hibernate的解决方案,核心代码就是通过注解来实现的。
  • 需求:

    • 1.有一张用户表,字段包括用户ID、用户名、昵称、年龄、性别、所在城市、邮箱、手机号。
    • 2.方便的对每个子弹或字段的组合条件进行检索,并打印出SQL。
    • 使用方式要足够简单。 

  • private static String query(Object f) {

    StringBuilder sb = new StringBuilder();

    //1.获取到class

    Class c = f.getClass();

    //2.获取到table的名字

    boolean exist = c.isAnnotationPresent(Table.class);

    if(!exist)

    return null;

    Table t = (Table) c.getAnnotation(Table.class);

    String tableName = t.value();

    sb.append("select * from ").append(tableName).append(" where 1=1 ");

    //3.遍历所有的字段

    Field[] fArray = c.getDeclaredFields();

    for(Field field : fArray) {

    //4. 处理每个字段对应的SQL

    //4.1 拿到字段名

    boolean fe = field.isAnnotationPresent(Column.class);

    if(!fe)

    continue;

    // Column column = field.getAnnotation(Column.class);

    // String columnName = column.value();

    //4.2拿到字段值

    String fieldName = field.getName();

    String getMethodName = "get" + fieldName.substring(0, 1).toUpperCase() +

    fieldName.substring(1);

    Object fieldValue = null;

    try {

    Method getMethod = c.getMethod(getMethodName);

    fieldValue = getMethod.invoke(f);

    } catch (Exception e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    }

    //4.3拼装SQL

    if(fieldValue == null ||

    (fieldValue instanceof Integer && (Integer)fieldValue == 0))

    continue;

    if(fieldValue instanceof String) {

    if(((String) fieldValue).contains(",")) {

    String[] values = ((String) fieldValue).split(",");

    sb.append("and ").append(fieldName).append(" in(");

    for(String v : values) {

    sb.append("'").append(v).append("',");

    }

    sb.deleteCharAt(sb.length()-1);

    sb.append(")");

    }

    else

    sb.append("and ").append(fieldName).append("='")

    .append(fieldValue).append("'");

    }

    else

    sb.append("and ").append(fieldName).append("=").append(fieldValue);

    }

    return sb.toString();

    }

    View Code

     

总结

  • 注解的作用范围@Target和生命周期@Retention

    • 作用范围包括:包、类、字段、方法、方法的参数和局部变量
    • 生命周期:源文件SOURCE、编译CLASS、运行RUNTIME

  • 等读懂注解
  • 在实际项目中用注解解决问题,并能自定义注解

以上是 有用的Java注解 的全部内容, 来源链接: utcz.com/z/393848.html

回到顶部