zoukankan      html  css  js  c++  java
  • java注解

    注解含义注解是JDK1.5之后才有的新特性,它相当于一种标记,在程序中加入注解就等于为程序打上某种标记,之后又通过类的反射机制来解析注解。

    一、JDK自带注解

    JDK1.5之后内部提供的三个注解

     @Deprecated       #废弃,过时。
     @Override         #重写、覆盖。
     @SuppressWarnings #压缩警告。

    示例

    @SuppressWarnings("deprecation")
    public class AnnotationTest {
        //4、这里称为压缩警告注解,可以在类上也可以放在方法上,因为该方法用了个已经过期的方法.getYear(),所以会发出警告
        //加上这个注解表明取消对deprecation的警告,那么该方法里有过时方法也不会发出预警。同时getYear()的那条横线也消失了。
        @SuppressWarnings("deprecation")
        public static void main(String[] args) {
    
       //1、这里的.getYear()方法画了一条横线表示此方法已经过时了,里面方法加上了@Deprecated注解
            new Date().getYear();
        }
    
        //2、这里我通过@Deprecated注解自定义一个已经过时不建议使用的方法。
        @Deprecated
        public String   getName() {
            return "小小";
    
        }
        //3、重写(覆盖)父类Object的toString()方法
        @Override
        public String toString() {
            return "小小";
        }
    }

    注解示意图

    二、自定义注解

    示例

    @Target(ElementType.FIELD)
    @Retention(RetentionPolicy.RUNTIME)
    @Inherited
    @Documented
    public @interface AnCode {//使用@interface关键字定义注解
    
        //如果只有一个属性 强烈建议取名为value
        String value() default "";
    }                                       

    在自定义注解上面有四个注解,我们称为元注解,下面一个一个解释。

    1、@Target 用于描述注解的使用范围

    取值(ElementType)有:
        1、CONSTRUCTOR:   用于描述构造器
        2、FIELD:         用于描述域(字段申明)
        3、LOCAL_VARIABLE:用于描述局部变量
        4、METHOD:        用于描述方法
        5、PACKAGE:       用于描述包
        6、PARAMETER:     用于描述参数
        7、TYPE:          用于描述类、接口(包括注解类型) 或enum声明
        8、TYPE_PARAMETER:输入参数申明(JDK1.8)
        9、TYPE_USE:      使用类型(JDK1.8)

    2、@Retention 定义了该注解生命周期

    取值(RetentionPoicy)有:
        1、SOURCE:  在源文件中有效(即源文件保留)
        2、CLASS:   在class文件中有效(即class保留)
        3、RUNTIME: 注解永久保留,可以被VM加载时加载到内存中

    一般框架注解和我们自定义注解采用的几乎都是RUNTIME,因为只有这个才能运行时通过反射来获取注解中的数据。

    3、@Inherited

    概念: @Inherited阐述了某个被标注的类型是被继承的。如果一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类。

    注意:@Inherited annotation类型是被标注过的class的子类所继承。类并不从它所实现的接口继承annotation,方法并不从它所重载的方法继承annotation
    解释: 比如A继承B,B类的上面有一个注解@A带有元注解@Inherited 那么A也可以拥有B父类的这个注解@A,但接口实现是不可以的。同时需要指出@A注解是需要元注解@Retention(RetentionPolicy.RUNTIME)。

    参考文章:java @Inherited注解的作用

    4、@Documented

    概念:描述其它类型的annotation应该被作为被标注的程序成员的公共API,因此可以被例如javadoc此类的工具文档化。

    5、自定义注解参数

      1、只能用public或默认(default)这两个访问权修饰.例如,String value();这里把方法设为defaul默认类型;  
          2、参数成员只能用基本类型byte,short,char,int,long,float,double,boolean八种基本数据类型和
               String,Enum,Class,annotations等数据类型,以及这一些类型的数组;
       3、如果只有一个参数成员,最好把参数名称设为"value",后加小括号(也可以不加小括号)

    三、自定义注解案例

    目标 实现一个简单的通过注解生成SQL查询语句。

    先创建两个注解

    @Table表名注解

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Table {
    
        //数据库表名属性
        String value() default "";
    }

    @Column字段名注解

    @Target(ElementType.FIELD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Column {
        //数据库表字段名称和实体属性映射
        String value() default "";
    }

    User实体

    @Table("t_user")
    public class User {
        /**
         * 用户Id
         */
        @Column("user_id")
        private Integer userId;
        /**
         * 用户年龄
         */
        @Column("age")
        private Integer age;
        
        public User(Integer userId, Integer age) {
            this.userId = userId;
            this.age = age;
        }
        //添加get和set方法
        }

    解析注解类

    public class Query {
        public static String query(Object object) throws Exception{
            StringBuilder sql = new StringBuilder();
            //1.利用反射获取Class
            Class c = object.getClass();
            //2.获取Table的名字
            boolean isExist = c.isAnnotationPresent(Table.class);
            if (!isExist) {
                return null;
            }
            Table t = (Table) c.getAnnotation(Table.class);
            //3、获取注解上的value值
            String tableName = t.value();
            sql.append("select * form ").append(tableName).append(" where 1 = 1 ");
            //4.遍历所有的属性字段
            Field[] fArray = c.getDeclaredFields();
            for (Field field : fArray) {
                //处理每个字段对应的sql
                boolean fExist = field.isAnnotationPresent(Column.class);
                if (!fExist) {
                    continue;
                }
                Column column = field.getAnnotation(Column.class);
                //数据库字段名
                String columnName = column.value();
                //5、将user_id 变成 userId
                String[] columns = columnName.split("_");
                StringBuilder columnBuilder = new StringBuilder();
                for (int i = 0; i < columns.length; i++) {
                    String s = columns[i];
                    columnBuilder.append(s.substring(0, 1).toUpperCase()).append(s.substring(1));
                }
                //6、活动属性值
                String getMethodName = "get" + columnBuilder.toString(); //get方法名
                Method getMethod = c.getMethod(getMethodName);
                Object  fieldValue = getMethod.invoke(object);//类字段值
                //7、拼装sql
                sql.append(" and ").append(columnName).append(" = ").append(fieldValue);
            }
            return sql.toString();
        }
    }

    测试类

    public static void main(String[] args) throws Exception {
            User user = new User(001, 4);
            String query = Query.query(user);
            System.out.println("query = " + query);
        }

    运行结果

    通过这个小案例实现了通过注解的方式,生成sql语句。

  • 相关阅读:
    scrum立会报告+燃尽图(第三周第一次)
    scrum立会报告+燃尽图(第二周第七次)
    scrum立会报告+燃尽图(第二周第六次)
    scrum立会报告+燃尽图(第二周第五次)
    scrum立会报告+燃尽图(第二周第四次)
    006_for
    005_while
    003_if_else
    002_how to use getpass
    图像旋转
  • 原文地址:https://www.cnblogs.com/smallfa/p/12372362.html
Copyright © 2011-2022 走看看