Java注解

 

目录

 

java1.5起默认的三个annotation类型

@Override:

@Deprecated:

@SuppressWarnings:

如何实现定义注解

注解的例子

自定义注解时需注意

实例

 

java1.5起默认的三个annotation类型

@Override:

一个是@Override:只能用在方法之上的,用来告诉别人这一个方法是改写父类的。

@Deprecated:

一个是@Deprecated:建议别人不要使用旧的API的时候用的,编译的时候会产生警告信息,可以设定在程序里的所有的元素上.

@SuppressWarnings:

一个是@SuppressWarnings:这一个类型可以用来暂时把一些警告信息消息关闭.

如何实现定义注解

首先在jdk自带的java.lang.annotation包里,打开如下几个源文件: 1、源文件Target.java

package java.lang.annotation;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.ANNOTATION_TYPE})
public @interface Target {
    ElementType[] value();
}

 

其中@interface是一个关键字,在设计annotations的时候必须把一个类型定义为@interface,而不能用class或interface关键字.

注解的关键字必须为@interface,即使写成interface接口类型亦或是继承Annotation类也不是自定义注解。

2、源文件Retention.java

@Documented
@Retention(RetentionPolicy.RUNsTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
    /**
     * Returns the retention policy.
     * @return the retention policy
     */
    RetentionPolicy value();
}

RetentionPolicy,ElementType这两个字段其实是两个Java文件。如下:

3、源文件RetentionPolicy.java

public enum RetentionPolicy {
/**
     * Annotations are to be discarded by the compiler.
     */
    SOURCE,
    /**
     * Annotations are to be recorded in the class file by the compiler
     * but need not be retained by the VM at run time.  This is the default
     * behavior.
     */
    CLASS,
    /**
     * Annotations are to be recorded in the class file by the compiler and
     * retained by the VM at run time, so they may be read reflectively.
     *
     * @see java.lang.reflect.AnnotatedElement
     */
    RUNTIME
}

这是一个enum类型,共有三个值,分别是SOURCE, CLASS 和 RUNTIME。

SOURCE代表的是这个Annotation类型的信息只会保留在程序源码里,源码如果经过了编译之后,Annotation的数据就会消失,并不会保留在编译好的.class文件里面。 ClASS的意思是这个Annotation类型的信息保留在程序源码里,同时也会保留在编译好的.class文件里面,在执行的时候,并不会把这一些信息加载到虚拟机(JVM)中去.注意一下,当你没有设定一个Annotation类型的Retention值时,系统默认值是CLASS. RUNTIME表示在源码编译好的.class文件中保留信息,在执行的时候会把这一些信息加载到JVM中去的. 举一个例子,如@Override里面的Retention设为SOURCE,编译成功了就不要这一些检查的信息;相反,@Deprecated里面的Retention设为RUNTIME,表示除了在编译时会警告我们使用了哪个被Deprecated的方法,在执行的时候也可以查出该方法是否被Deprecated。

4、源文件ElementType.java

public enum ElementType {
    /** Class, interface (including annotation type), or enum declaration */
    TYPE,
    /** Field declaration (includes enum constants) */
    FIELD,
    /** Method declaration */
    METHOD,
    /** Formal parameter declaration */
    PARAMETER,
    /** Constructor declaration */
    CONSTRUCTOR,
    /** Local variable declaration */
    LOCAL_VARIABLE,
    /** Annotation type declaration */
    ANNOTATION_TYPE,
    /** Package declaration */
    PACKAGE,
    /**
     * Type parameter declaration
     *
     * @since 1.8
     */
    TYPE_PARAMETER,
    /**
     * Use of a type
     *
     * @since 1.8
     */
    TYPE_USE
}

@Target里面的ElementType是用来指定Annotation类型可以用在哪一些元素上的.说明一下:TYPE(类型), FIELD(属性),METHOD(方法), PARAMETER(参数), CONSTRUCTOR(构造函数),LOCAL_VARIABLE(局部量),ANNOTATION_TYPE,PACKAGE(包),其中的TYPE(类型)是指可以用在Class,Interface,Enum和Annotation类型上.如果一个Annotation类型没有指明@Target使用在哪些元素上,那么它可以使用在任何元素之上.

即@Target如果指明了枚举类型,那么就只可以作用在指定的元素之上,如果未指明指定元素,那么就可以作用在任何元素之上。

注解的例子

自定义注解时需注意

访问修饰符限制

1.只能用public默认(default)这两个访问权修饰.例如,String value();这里把方法设为defaul默认类型.

数据类型

2.参数成员只能用基本类型byte,short,char,int,long,float,double,boolean八种基本数据类型和String,Enum,Class,annotations等数据类型,以及这一些类型的数组.例如,String value();这里的参数成员就为String.

一个参数必用value

3.如果只有一个参数成员,最好把参数名称设为"value",后加小括号

实例

自定义注解类并获取注解

import java.lang.annotation.*;
@Documented
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Description {
    String value();
}
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Name {
    String originate();
    String brand();
}
@Description("java,做最棒的编程语言")
public class Java {

        @Name(originate = "创始人:高斯林", brand= "java")
        public String getName() {
            return null;
        }

        @Name(originate = "创始人:菲利普·莫里斯", brand= "Marlboro")
        public String getName2() {
            return "男人只因浪漫铭记爱情";
        }
}
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Set;
public class TestAnnotation {
    public static void main(String[] args) throws Exception {
        String CLASS_NAME = "com.uplooking.demo.Java";
        Class test = Class.forName(CLASS_NAME);
        Method[] methods = test.getMethods();
        //判断此类是否是一个注解类
        boolean flag = test.isAnnotationPresent(Description.class);
        if (flag) {
            Description des = (Description) test
                    .getAnnotation(Description.class);
            System.out.println("描述:" + des.value());
            System.out.println("-----------------");
        }
        for (Method m: methods) {
            boolean otherFlag = m.isAnnotationPresent(Name.class);
            if (otherFlag) {
                Name name = m.getAnnotation(Name.class);
                System.out.println(name.originate());
                System.out.println("创建的品牌:" + name.brand());
            }
        }
    }
}

class对象.isAnnotationPresent(Description.class):判断当前类上是否有注解类

class对象..getAnnotation(Description.class)       括号内表示判断当前类中是否有该注解类。

注解+反射,写简单的ORM(对象关系映射)

通过注解+反射,写一个简单的ORM(对象关系映射(Object Relational Mapping))框架,效果是通过注解的方式快速生成SQL语句 首先先定义注解类:Table,Column(分别代表:表和列)

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Table {
    String value();
}
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
    String value();
}
@Table(value = "person")
public class Person {
    @Column("id")
    private String id;
    @Column("user_name")
    private String userName;
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
}
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Test {
    public static void main(String[] args) {
        Person person = new Person();
        person.setId("12");
        person.setUserName("张三");
        System.out.println(query(person));
    }
    public static String query(Person person) {
        StringBuffer sb = new StringBuffer();
        Class p = person.getClass();
        boolean exist = p.isAnnotationPresent(Table.class);
        if (!exist) {
            return null;
        }
        //如果是,强制类型转换成Table
        Table table = (Table) p.getAnnotation(Table.class);
        String tableName = table.value();
        sb.append("select * from ").append(tableName);
        Field[] fields = p.getDeclaredFields();
        for (Field f : fields) {
            boolean fExit = f.isAnnotationPresent(Column.class);
            if (!fExit) {
                return null;
            }
            Column column = f.getAnnotation(Column.class);
            String columValue = column.value();
            String fieldName = f.getName();
            String methodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
            try {
                Method m = p.getMethod(methodName);
                Object fieldValue = m.invoke(person);
                sb.append(" and ").append(columValue).append(" =
					").append("\'").append(fieldValue).append("\'");
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        }
        return sb.toString();
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值