自定义注解初步学习

相信大家或多或少接触或者使用过java的注解


比如java.lang包中的注解:
@Override :表示该方法覆盖父类的方法,当方法拼写错误或者和父类的对应不上时,编译器会报错
@SuppressWarnings :关闭编译器的警告报错
比如用过Spring框架的朋友肯定会熟悉很多注解。等等


基本用法

元注解:元注解的作用就是负责注解其他注解。Java5.0定义了4个标准的meta-annotation类型,它们被用来提供对其它 annotation类型作说明。Java5.0定义的元注解:
    1.@Target
    2.@Retention,
    3.@Documented,
    4.@Inherited
  这些类型和它们所支持的类在java.lang.annotation包中可以找到。下面我们看一下每个元注解的作用和相应分参数的使用说明。
  
@Target:
   @Target说明了Annotation所修饰的对象范围:Annotation可被用于 packages、types(类、接口、枚举、Annotation类型)、类型成员(方法、构造方法、成员变量、枚举值)、方法参数和本地变量(如循环变量、catch参数)。在Annotation类型的声明中使用了target可更加明晰其修饰的目标。
  作用:用于描述注解的使用范围(即:被描述的注解可以用在什么地方)
  取值(ElementType)有:
    1.CONSTRUCTOR:用于描述构造器
    2.FIELD:用于描述域
    3.LOCAL_VARIABLE:用于描述局部变量
    4.METHOD:用于描述方法
    5.PACKAGE:用于描述包
    6.PARAMETER:用于描述参数
    7.TYPE:用于描述类、接口(包括注解类型) 或enum声明

@Retention:
  @Retention定义了该Annotation被保留的时间长短:某些Annotation仅出现在源代码中,而被编译器丢弃;而另一些却被编译在class文件中;编译在class文件中的Annotation可能会被虚拟机忽略,而另一些在class被装载时将被读取(请注意并不影响class的执行,因为Annotation与class在使用上是被分离的)。使用这个meta-Annotation可以对 Annotation的“生命周期”限制。
  作用:表示需要在什么级别保存该注释信息,用于描述注解的生命周期(即:被描述的注解在什么范围内有效)
  取值(RetentionPoicy)有:
    1.SOURCE:在源文件中有效(即源文件保留)
    2.CLASS:在class文件中有效(即class保留)
    3.RUNTIME:在运行时有效(即运行时保留)
以上参考:http://www.cnblogs.com/peida/archive/2013/04/24/3036689.html

自定义注解

注解的定义看起来和接口很像,只是在前面多了个@,并且在定义注解时,要用到我们上面介绍的元注解,来规定我们的注解使用的那个的地方。与java接口一样,注解会编译成class文件

下面是一个自定义注解,用来创建sql建表语句。

package zhujie;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
 * 自定义标签
 * @author lk
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface DBTable {
    public String name() default "";
}

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface Constraints{
    boolean primaryKey() default false;
    boolean allowNull() default true;
    boolean unique() default false;
}

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface SQLInteger{
    String name() default "";
    Constraints constraints() default @Constraints; 
}

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface SQLString{
    int value() default 0;
    String name() default "";
    Constraints constraints() default @Constraints; 
}

这样我们可以在类中使用我们的自定义注解

package zhujie;

@DBTable(name = "MEMBER")
public class Member {
    @SQLString(30)
    private String firstName;
    @SQLString(50)
    private String lastName;
    @SQLInteger
    private Integer age;
    @SQLString(value = 30, constraints = @Constraints(primaryKey = true))
    private String handle;

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getHandle() {
        return handle;
    }

    public void setHandle(String handle) {
        this.handle = handle;
    }

}

但是这样的注解和注释其实没有很大的区别,当注解和注解处理器一起使用时才能显示他的作用。

package zhujie;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

public class TableCreator {
    public static void main(String[] args) throws ClassNotFoundException {
        System.out.println(creator("zhujie.Member"));
    }

    private static String creator(String string) throws ClassNotFoundException {
        Class<?> cl = Class.forName(string);
        DBTable dbTable = cl.getAnnotation(DBTable.class);
        if (dbTable == null) {
            System.out.println("无效类名");
        }
        // 获取表名
        String tableName = dbTable.name();
        // 如果没有设置表名默认用类名大写
        if (tableName.length() < 1) {
            tableName = cl.getName().toUpperCase();
        }
        List<String> columnDefs = new ArrayList<>();
        //遍历属性
        for (Field field : cl.getDeclaredFields()) {
            // 获取属性注解
            Annotation[] anns = field.getAnnotations();
            String columnName = null;
            for (Annotation annotation : anns) {
                if (annotation instanceof SQLString) {
                    SQLString sString = (SQLString) annotation;
                    if (sString.name().length() < 1) {
                        columnName = field.getName().toUpperCase();
                    } else {
                        columnName = sString.name();
                    }
                    columnDefs.add(
                            columnName + " VARCHAR(" + sString.value() + ")" + getConstraints(sString.constraints()));
                    break;
                } else if (annotation instanceof SQLInteger) {
                    SQLInteger sInt = (SQLInteger) annotation;
                    if (sInt.name().length() < 1) {
                        columnName = field.getName().toUpperCase();
                    } else {
                        columnName = sInt.name();
                    }
                    columnDefs.add(columnName + " INT" + getConstraints(sInt.constraints()));
                    break;
                } else {
                    continue;
                }
            }
        }
        //创建语句
        StringBuilder createSql=new StringBuilder("CREATE TABLE "+tableName+"(");
        for(String columnDef:columnDefs){
            createSql.append("\r\n\t"+columnDef+",");
        }
        return createSql.substring(0,createSql.length()-1)+"\r\n);";
    }

    /*
     * 属性后面的约束(唯一,主键,是否为空)
     */
    private static String getConstraints(Constraints con) {
        String constraints = "";
        if (!con.allowNull()) {
            constraints += " NOT NULL";
        }
        if (con.primaryKey()) {
            constraints += " PRIMARY KEY";
        }
        if (con.unique()) {
            constraints += " UNIQUE";
        }
        return constraints;
    }
}

结果

CREATE TABLE MEMBER(
    FIRSTNAME VARCHAR(30),
    LASTNAME VARCHAR(50),
    AGE INT,
    HANDLE VARCHAR(30) PRIMARY KEY
);

通过上述的例子(来自java编程思想)我们大致可以了解到注解的作用和使用方法,当然这只是初步学习,我们用的例子对于真实的对象/关系映射而言(ORM数据库,比如hibernate),是很幼稚的。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值