Annotation

  1. 注解
    1. 创建一个注解
      1. 在注解中声明属性
        1. 注解运用范围
      2. JDK内置注解
      3. 元注解
    2. 如何通过反射机制获取注解:
      1. 根据注解自动生成SQL查询语句

注解

什么是注解?

元数据(Annotation) ,是一种对代码进行说明的数据,JDK1.5引入的新规范,是与类、接口、枚举等引用类型处于同一个层次,可以用在包、类、属性、方法、方法的参数和局部变量等的前边,不影响代码的语义,可以对其进行解析

注解Annotation: 是一种引用数据类型(在类加载的时候会生成字节码文件)

注解在以后的用途:

​ 注解的作用:

​ 注解只能起到一个标识的作用

spring框架:基于注解的开发模式

​ 学习了反射可以不使用new关键字去创建一个类的实例

​ spring是一个容器里面会存放很多类的实例

我怎么知道有哪些类需要去创建实例,那些类不需要创建实例?

​ 用注解去标识一下,需要创建实例的类,用注解去做一个标识

​ 在spring框架检测到该类有注解时,就会通过反射机制去创建该类的实例

beans: User、Student、Person、Animal

创建一个注解

public @interface MyAnnotation {
    
}

注解中可以拥有属性,但是不能拥有方法

如果你给一个注解声明了属性,那么在注解修饰元素的时候,就必须要给属性赋值,除非你在声明属性的时候,给了属性默认值

在注解中声明属性

public @interface MyAnnotation {

    //在注解中如何去声明属性
    String name() default "";

    int i();

    String[] strings() default {"1","2"};

    //枚举类型
    Math math() default Math.Max;
    
    Math[] maths() default {Math.Max,Math.Count,Math.Sum};
    
}

在注解中定义属性只能时八大基本数据类型、字符串类型String、枚举类型、以及主要类型所对应的数组类型

在定义属性时,如果属性名称是value,那在注解修饰元素,并且给属性赋值的时候,属性名称可以省略不写

@MyAnnotation(name = "123",i = 100)

注解运用范围

注解使用时的语法格式是:

​ @注解类型名

注解可以出现在类上、属性上、方法上、变量上等

注解可以出现在注解类型上

JDK内置注解

Deprecated@Deprecated 注释的程序元素,不鼓励程序员使用这样的元素,通过是因为它很危险或存在更好的选择

Override表示一个方法声明打算重写超类中的另一个方法声明

SuppressWarnings 指示应该在注释元素(以及包含在该注释元素中的所有程序元素)中取消显示指定的编译器警告

元注解

什么是元注解?

用来标注“注解类型”的“注解”,称为元注解

修饰注解的注解

在定义注解时需要通过元注解指定例如注解的使用场合、是否生成文档、是否可以继承、注解保持的策略(是否能被反射机制所获取到)

元注解

@Target({ElementType.METHOD,ElementType.TYPE}) 表示注解的作用域

参数只能是枚举类型数组

//使得注解能标识在类和属性前
@Target({ElementType.TYPE,ElementType.FIELD})
public @interface MyAnnotation {

}
  • @Retention(RetentionPolicy.RUNTIME)

    注解的生命周期

  • RetentionPolicy(设置注解的生命周期以及保持性策略):

    SOURCE

    ​ 当前注解只保留在源码这个层面上,在类加载的时候不会去生成字节码文件,而且不可以被反射机制所获取!

    CLASS

    ​ 在类加载的时候会生成字节码文件,但是不可以被发射机制获取

    RUNTIME

    ​ 在类加载的时候可以生成字节码文件,而且可以被反射机制获取工

  • @Inherited

    标识允许子注解来继承这个注解(注意这里只能是继承不能是接口上使用,而且只能继承类上的注解,不能继承方法上的注解)

  • @Documented

    生成JAVADOC时会包含注解

如何通过反射机制获取注解:

​ 1、创建类对应的字节码对象

​ 2、通过字节码对象获取注解字节码对象

public class Annotation01 {

    public static void main(String[] args) {


        try {

            //创建字节码对象
            Class aClass = Class.forName("com.os467.pojo.User");

            //获取类上的注解
            MyAnnotation annotation = (MyAnnotation)aClass.getAnnotation(MyAnnotation.class);

            if (annotation != null){

                //获取注解上的属性
                System.out.println(annotation.name());

                //获取属性字节码对象
                Field[] declaredFields = aClass.getDeclaredFields();

                for (Field declaredField : declaredFields) {

                    MyAnnotation annotation1 = declaredField.getAnnotation(MyAnnotation.class);

                    if (annotation1 != null){

                        System.out.println(declaredField.getName()+" 这个属性上有注解");

                    }

                }

            }

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }


    }

}

根据注解自动生成SQL查询语句

package com.os467;

import com.os467.Annotion.Table;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;


public class ORM {

    private ORM(){

    }

    public static String getSql(Object obj){

        StringBuilder stringBuilder = new StringBuilder();

        //获取obj字节码对象
        Class aClass = obj.getClass();

        Table annotation = (Table)aClass.getAnnotation(Table.class);

        //表的名称
        String table = null;

        if (annotation != null){

            //获取表的名称
            table = annotation.value();

            stringBuilder.append("select * from "+ table +" where ");

        }

        //获取属性字节码对象
        Field[] declaredFields = aClass.getDeclaredFields();

        for (Field declaredField : declaredFields) {

            //打破封装
            declaredField.setAccessible(true);

            com.os467.Annotion.Field annotation1 = declaredField.getAnnotation(com.os467.Annotion.Field.class);

            //注解不为空的情况下拼接
            if (annotation1 != null){

                try {

                    //获取属性值
                    Object o = declaredField.get(obj);

                    //检查email属性是否有多个","隔开
                    if (o != null && o.toString().contains(",")){

                        stringBuilder.append(annotation1.value() + " in(" + o + ") and");

                    }else if (o != null && !o.toString().equals("0")){

                        stringBuilder.append(annotation1.value() + " = ");

                        if (o instanceof String){

                            stringBuilder.append("'" + o + "'" + " and ");

                        }

                        if (o instanceof Integer){

                            stringBuilder.append(o + " and ");

                        }

                    }


                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }

            }

        }

        String s = stringBuilder.toString();

        //替换掉最后的and 
        s = s.substring(0,s.length() - 4);

        if (s.contains("=")){

            return s;

        }

        return null;
    }

}

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以邮件至 1300452403@qq.com

文章标题:Annotation

字数:1.5k

本文作者:Os467

发布时间:2022-07-14, 19:36:02

最后更新:2022-09-05, 00:07:16

原始链接:https://os467.github.io/2022/07/14/Annotation/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

×

喜欢就点赞,疼爱就打赏