全面解析Java注解--慕课网笔记

本文从Java注解的基础概念入手,详细介绍了注解的作用、分类及其应用场景。不仅涵盖了JDK自带的注解,还深入探讨了如何自定义注解以及如何在实际项目中运用这些注解来简化开发流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第1章 概述
1-1 Java注解概述

为什么要学习注解?学习注解有什么好处?学完能做什么?

  1. 能够读懂别人的代码,特别是框架相关的代码
  2. 让编程更加简洁,代码更加清晰
  3. 让别人高看我们一眼

注解在Java1.5引入
Java提供了一种原程序中元素关联任何信息和任何元素的途径和方法

  • Java中的常见注解
  • 注解分类
  • 自定义注解
  • 注解应用实战
第2章 Java中的常见注解
2-1 JDK中的注解

JDK自带注解
- @Override
- @Deprecated
- @Suppvisewarnings

public interface Person {


    public String name();

    public String age();

    @Deprecated
    public void sing();

}
public class Child implements Person{

    @Override
    public String name() {
        return null;
    }

    @Override
    public String age() {
        return null;
    }

    @Override
    public void sing() {

    }

}
public class Test {


    @SuppressWarnings("deprecation")
    public void sing() {
        Person p = new Child();
        p.sing();
    }

}
2-2 Java第三方注解
  • Spring
    • @Autowired
    • @Service
    • @Repository
  • Mybatis
    • @InsertProvider
    • @UpdateProvider
    • @Options
第3章 注解的分类
3-1 Java注解的分类
  • 按照运行机制分
    • 源码注解
      注解只在源码中存在,编译成.class文件就不存在了。
    • 编译时注解
      注解在源码和.class文件中都存在,如@Override、@Deprecated、@Suppvisewarnings
    • 运行时注解
      在运行阶段还起作用,甚至会影响运行逻辑的注解,如@Autowired
  • 按照来源分类
    • 来自JDK的注解
    • 来自第三方的注解
    • 我们自定义的注解

元注解:注解的注解

第4章 自定义注解
4-1 Java自定义注解
  • 自定义注解的语法要求
  • 注解的注解(元注解)
  • 使用自定义注解
  • 解析注解
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Description{

    String desc();

    String author();

    int age() default 18;
}
  • 使用@interface关键字定义注解
  • 成员以无参无异常方式声明
  • 可以用default为成员指定一个默认值
  • 成员类型是受限的,合法的类型包括基本类型以及String、Class、Annotation、Enumeration
  • 如果注解只有一个成员,则成员名必须取名为value(),在使用时可以忽略成员名和赋值号(=)
  • 注解类可以没有成员,没有成员的注解称为标识注解

ElementType中有:
- CONSTRUCTOR
- FIELD
- LOCAL_VARIABLE
- METHOD
- PACKAGE
- PARAMETER
- TYPE

RetentionPolicy中有:
- SOURCE
- CLASS
- RUNTIME

@Inherited:允许子类继承
@Doucument:生成javadoc时会包含注解

4-2 使用自定义注解

使用注解的语法:
@<注解名>(<成员名1>=<成员值1>,<成员名2>=<成员值2>,…)

@Description(desc="I am eyeColor",author="Mooc boy",age=18)
public String eyeColor(){
    return "red";
}
4-3 关于自定义注解的代码演示说明
4-4 解析注解

通过反射获取类、函数或成员上的运行时注解信息,
从而实现动态控制程序运行的逻辑。

public class ParseAnn {


    public static void main(String[] args) {


        try {
            //1.使用类加载器加载类
            Class c = Class.forName("com.ann.test.Child");
            //2.找到类上面的注解
            boolean isExist = c.isAnnotationPresent(Description.class);
            if(isExist) {
                //3.拿到注解实例
                Description d = (Description)c.getAnnotation(Description.class);
                System.out.println(d.value());
            }


            //4.找到方法上的注解
            Method[] ms = c.getMethods();
            for (Method m : ms) {
                boolean isMExist = m.isAnnotationPresent(Description.class);
                if(isMExist){
                    Description d = (Description)m.getAnnotation(Description.class);
                    System.out.println(d.value());
                }
            }

            //另一种解析方法
            for(Method m:ms) {
                Annotation[] as = m.getAnnotations();
                for (Annotation a : as) {
                    if(a instanceof Description) {
                        Description d = (Description)a;
                        System.out.println(d.value());
                    }
                }


            }


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

}
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Description{

    String value();

//  String author();

//  int age() default 18;
}
@Description("I am interface")
public class Person {

    @Description("I am interface method")
    public String name() {
        return null;
    };

    public String age() {
        return null;
    };

    @Deprecated
    public void sing() {};

}
public class Child extends Person{

    @Override
    public String name() {
        return null;
    }

    @Override
    public String age() {
        return null;
    }

    @Override
    public void sing() {

    }

}
第5章 项目实战
5-1 项目需求

项目说明:项目取自一个公司的持久层框架,用来代替Hibernate的
解决方案,核心代码就是通过注解来实现的。

需求:
1. 有一张用户表,字段包括用户ID,用户名,昵称,年龄,
性别,所在城市,邮箱,手机号。
2. 方便的对每个字段或字段的组合条件进行检索,并打印SQL。
3. 使用方式要足够简单,见代码示例。

5-2 项目实现(上)
5-3 项目实现(下)
public class Test {

    public static void main(String[] args) {

        Filter f1 = new Filter();
        f1.setId(10);//查询id为10的用户

        Filter f2 = new Filter();
        f2.setUserName("lucy");//查询用户为lucy的用户
        f2.setAge(18);

        Filter f3 = new Filter();
        f3.setEmail("liu@sina.com,zh@163.com,77777@qq.com");


        String sql1 = query(f1);
        String sql2 = query(f2);
        String sql3 = query(f3);

        System.out.println(sql1);
        System.out.println(sql2);
        System.out.println(sql3);


        Filter2 filter2 = new Filter2();
        filter2.setAmount(10);
        filter2.setName("技术部");
        System.out.println(query(filter2));
    }

    private static String query(Object f) {
        StringBuilder sb = new StringBuilder();
        //1.获取到class
        Class c = f.getClass();
        //2.获取到table的名字
        boolean exists = c.isAnnotationPresent(Table.class);
        if(!exists) {
            return null;
        }
        Table t = (Table)c.getAnnotation(Table.class);
        String tableName = t.value();
        sb.append("select * from ").append(tableName).append(" where 1=1");
        //3.遍历所有字段
        Field[] fArray = c.getDeclaredFields();
        for (Field field : fArray) {
            //4.处理每个字段对应的sql
            //4.1拿到字段名
            boolean fExists = field.isAnnotationPresent(Column.class);
            if(!fExists) {
                continue;
            }
            Column column = field.getAnnotation(Column.class);
            String columnName = column.value();
            //4.2拿到字段的值
            String filedName = field.getName();
            String getMethodName = "get"+ filedName.substring(0,1).toUpperCase() + 
                    filedName.substring(1);
            Object fieldValue = null;
            try {
                Method getMethod = c.getMethod(getMethodName);
                fieldValue =getMethod.invoke(f, null);
            } catch (Exception e) {
                e.printStackTrace();
            }
            //4.3拼装sql
            if(fieldValue == null ||
                    (fieldValue instanceof Integer && (Integer)fieldValue == 0)) {
                continue;
            }
            sb.append(" and ").append(filedName);
            if(fieldValue instanceof String) {
                if(((String)fieldValue).contains(",")) {
                    String[] values = ((String)fieldValue).split(",");
                    sb.append(" in(");
                    for (String v : values) {
                        sb.append("'").append(v).append("'").append(",");
                    }
                    sb.deleteCharAt(sb.length()-1);
                    sb.append(")");
                }else {
                    sb.append("=").append("'").append(filedName).append("'");
                }
            }else if(fieldValue instanceof Integer) {
                sb.append("=").append(fieldValue);
            }
        }
        return sb.toString();
    }

}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Table {

    String value();
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {

    String value();
}
@Table("user")
public class Filter {

        @Column("id")
        private int id;

        @Column("user_name")
        private String userName;

        @Column("nick_name")
        private String nickName;

        @Column("age")
        private int age;

        @Column("city")
        private String city;

        @Column("email")
        private String email;

        @Column("mobile")
        private String mobile;

        public int getId() {
            return id;
        }

        public void setId(int id) {
            this.id = id;
        }

        public String getUserName() {
            return userName;
        }

        public void setUserName(String userName) {
            this.userName = userName;
        }

        public String getNickName() {
            return nickName;
        }

        public void setNickName(String nickName) {
            this.nickName = nickName;
        }

        public int getAge() {
            return age;
        }

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

        public String getCity() {
            return city;
        }

        public void setCity(String city) {
            this.city = city;
        }

        public String getEmail() {
            return email;
        }

        public void setEmail(String email) {
            this.email = email;
        }

        public String getMobile() {
            return mobile;
        }

        public void setMobile(String mobile) {
            this.mobile = mobile;
        }



}
@Table("department")
public class Filter2 {

        @Column("id")
        private int id;

        @Column("name")
        private String name;

        @Column("leader")
        private String leader;

        @Column("amount")
        private int amount;

        public int getId() {
            return id;
        }

        public void setId(int id) {
            this.id = id;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getLeader() {
            return leader;
        }

        public void setLeader(String leader) {
            this.leader = leader;
        }

        public int getAmount() {
            return amount;
        }

        public void setAmount(int amount) {
            this.amount = amount;
        }


}
第6章 课程总结
6-1 课程总结
  1. 认识注解
  2. 注解作用范围@Target和生命周期@Retention
    • 作用范围:包、类、字段、方法的参数、局部变量
    • 生命周期:源文件SOURCE、编译CLASS、运行RUNTIME
  3. 能读懂注解

《全面解析java注解》视频地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值