Java-高级-注解详解

注解(代码标记)

概念

可以通过反射机制获取代码标记中的元数据。

在编译器生成类文件时,标记可以被嵌入到字节码中。Java 虚拟机可以保留标记内容,在运行时可以获取到标记内容

元注解(Java提供的)

由Java提供的元注解,所谓元注解就是标记其他注解的注解

@Target(约束自定义注解)

用来约束注解可以应用的地方(如方法、类或字段),其中ElementType是枚举类型,也代表可能的取值范围

public enum ElementType {
    /**标明该注解可以用于类、接口(包括注解类型)或enum声明*/
    TYPE,

    /** 标明该注解可以用于字段(域)声明,包括enum实例 */
    FIELD,

    /** 标明该注解可以用于方法声明 */
    METHOD,

    /** 标明该注解可以用于参数声明 */
    PARAMETER,

    /** 标明注解可以用于构造函数声明 */
    CONSTRUCTOR,

    /** 标明注解可以用于局部变量声明 */
    LOCAL_VARIABLE,

    /** 标明注解可以用于注解声明(应用于另一个注解上)*/
    ANNOTATION_TYPE,

    /** 标明注解可以用于包声明 */
    PACKAGE,

    /**
     * 标明注解可以用于类型参数声明(1.8新加入)
     * @since 1.8
     */
    TYPE_PARAMETER,

    /**
     * 类型使用声明 类型检查(1.8新加入)
     * @since 1.8
     */
    TYPE_USE
    
    /**
    * 标注在类型参数上(1.8后加入)
    **/
    TYPE_PARAMETER
}	
当注解未指定Target值时,则此注解可以用于任何元素之上,多个值使用{}包含并用逗号隔开
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})

@Retention(约束注解的生命周期)

分别有三个值,源码级别(source),类文件级别(class)或者运行时级别(runtime),其含有如下:

  • SOURCE:注解将被编译器丢弃(该类型的注解信息只会保留在源码里,源码经过编译后,注解信息会被丢弃,不会保留在编译好的class文件里)
  • CLASS:注解在class文件中可用,但会被JVM丢弃(该类型的注解信息会保留在源码里和class文件里,在执行的时候,不会加载到虚拟机中),请注意,当注解未定义Retention值时,默认值是CLASS,如Java内置注解,@Override、@Deprecated、@SuppressWarnning等
  • RUNTIME:注解信息将在运行期(JVM)也保留,因此可以通过反射机制读取注解的信息(源码、class文件和执行的时候都有注解的信息),如SpringMvc中的@Controller、@Autowired、@RequestMapping等

@Override(声明覆盖了父类方法)

用于标明此方法覆盖了父类的方法

@Deprecated(标明已经过时的方法或类)

@SuppressWarnnings(关闭编译器警告)

用于有选择的关闭编译器对类、方法、成员变量、变量初始化的警告

@Documented(被修饰的注解会生成到javadoc中)

使用javadoc命令生成文档

@Inherited(让子类继承父类的注解)

@Repeatable(可以在同个位置上标注重复注解)

元注解@Repeatable是JDK1.8新加入的,它表示在同一个位置重复相同的注解。在没有该注解前,一般是无法在同一个类型上使用相同的注解的

自定义注解

创建SQL建表语句

1、创建默认属性注解

@Target(value = ElementType.FIELD)
@Retention(value = RetentionPolicy.RUNTIME)
public @interface Constraints {
    //是否为主键
    boolean primaryKey() default false;

    //是否为空
    boolean allowNull() default false;

    //是否唯一
    boolean unique() default false;
}
//默认表名
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface DBTable {
    String name() default "";
}
//Int类型列名
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SQLInteger {
    String name() default "";

    Constraints constraints() default @Constraints;
}
//String类型列名
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SQLString {
    String name() default "";

    int value() default 0;

    Constraints constraints() default @Constraints;
}

2、通过反射调用注解,获得其默认值

public class createTable {

    public  static String createTableSql(String className) throws ClassNotFoundException {

        //通过反射获取该类
        Class<?> cl = Class.forName(className);
        //获取该类的@DBTable注解
        DBTable dbTable = cl.getAnnotation(DBTable.class);

        if(dbTable ==null){
            System.out.println("当前"+className+"不存在");
            return  null;
        }

        String tableName = dbTable.name().toUpperCase();

        List<String> columnList = new ArrayList<String>();

        for(Field field : cl.getDeclaredFields()){
            String columnName = null;

           Annotation[] annotations = field.getDeclaredAnnotations();

           if(annotations[0] instanceof  SQLInteger){
               SQLInteger sqlInteger = (SQLInteger) annotations[0];
              if(sqlInteger.name().length()<1){
                  columnName = field.getName();
              }else {
                  columnName = sqlInteger.name();
              }
               columnList.add(columnName+" INT "+getConstraints(sqlInteger.constraints()));
           }

           if(annotations[0] instanceof  SQLString){
               SQLString sqlString = (SQLString) annotations[0];
               if(sqlString.name().length()<1){
                   columnName = field.getName();
               }else{
                   columnName = sqlString.name();
               }
               columnList.add(columnName+" VARCHAR("+sqlString.value()+") "+getConstraints(sqlString.constraints()));
           }



        }

        StringBuilder stringBuilder = new StringBuilder(
                "CREATE TABLE " +tableName +"("
        );
        for(String column : columnList){
            stringBuilder.append("\n"+column+",");
        }
        String createSQL = stringBuilder.substring(0,stringBuilder.length()-1)+");";

        return  createSQL;
    }

    public  static  String getConstraints(Constraints constraints){
        String con = "";
        if(!constraints.allowNull()){
            con += " NOT NULL ";
        }
        if(constraints.primaryKey()){
            con +=" PRIMARY KEY ";
        }
        if(constraints.unique()){
            con +=" UNIQUE ";
        }
        return  con;
    }
}

3、调用运行时的类,获得建表语句

public class Application {
    public static void main(String[] args) throws ClassNotFoundException {

        String[] arg={"annotation.User"};
        for(String className : arg){
            System.out.println(createTable.createTableSql(className));
        }

    }
}

在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值