主要记录一下枚举类和注解的使用场景

一.枚举类

特点

  • Java 枚举是一个特殊的类,一般用来生成有限个实例供外界调用,Java 枚举类使用 enum 关键字来定义,各个实例间使用逗号 , 来分割.
  • 所有的实例变量定义在第一行,默认使用 public static final 修饰.
  • 枚举类的构造器默认都是 private 修饰的,所以不能创建新的实例对象.
  • 枚举类提供 values() 方法,可以获取到所有的实例对象.
  • 使用enum定义的枚举类默认继承了java.lang.Enum类,而不是默认继承Object类,因此枚举类不能显示继承其他父类。

优势

  • 枚举类相比较于静态常量,可以很方便的打印出每个数字对应的含义
  • 可以在枚举类的静态代码块中,对所有的实例对象进行一些操作,比如生成目录.

使用场景

  • 替代静态常量
  • 自动生成目录

自动生成目录代码

package com.example.springboot01.util;

import java.io.File;

public enum FileCatalog {
    UPS(1),FEDEX(2);

    // 创建目录
    static {
        FileCatalog[] fileCatalogs = FileCatalog.values();
        for (FileCatalog fileCatalog: fileCatalogs) {
            String path = "D:\\workspace" + File.separator + fileCatalog.toString();
            File file = new File(path);
            if (!file.exists()) {
                file.mkdirs();
            }
        }
    }

    private final int a;

    FileCatalog(int a) {
        this.a = a;
    }

    public int getValue() {
        return this.a;
    }
}

上述代码中可以通过 FileCatallog.UPS.toString() 来获取 “UPS” 字符串.

二.注解

特点

  • 注解是一种特殊的接口, 使用 @interface 关键字定义
  • 注解里面的变量定义和类里面有些不同,在变量后面需要增加圆括号 (), 并且可以设置默认值.
  • 注解有4个元注解,分别是 @Retention 表示在什么级别保存该注解信息, @Target 表示该注解用于什么地方, @Documented 将此注解包含在 javadoc 中, @Inherited 允许子类继承父类中的注解.
  • 注解对标注的代码不会产生任何影响,想要发挥注解的作用,可以通过反射来完成.

优势

  • 通过注解可以很方便的区分出哪些代码需要进行特殊操作
  • 使用方便,只要在代码前加上注解就能实现特定功能

使用场景

  • 可以配合面向切面编程,实现日志记录,安全校验等功能.
  • 可以实例化对象.

实例化对象代码
网上找的一个例子

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FruitProvider {
    /*供应商编号*/
    public int id() default -1;
    /*供应商名称*/
    public String name() default "";
    /*供应商地址*/
    public String address() default "";
}

@FruitProvider(id = 1728, name = "why", address = "shenzhen")
public class Apple {
    private int appleID;
    private String appleProvidername;
    private String appleprovideraddress;
}

public class FruitInfoUtil {
    public static Apple getAApple(Class<?> clazz) throws Exception{
        FruitProvider fb = clazz.getAnnotation(FruitProvider.class);//通过反射获取处理注释
        //通过newInstance()生成Apple实例,利用反射的结果进行设置
        Apple ap = (Apple)clazz.newInstance();
        ap.setAppleID(fb.id());
        ap.setAppleProvidername(fb.name());
        ap.setAppleprovideraddress(fb.address());
        return ap;
    }
}

public class Main {
    public static void main(String[] args) throws  Exception{
        Apple a = FruitInfoUtil.getAApple(Apple.class);
        System.out.println("苹果商的ID为:"+a.getAppleID());
        System.out.println("苹果商的名字为:"+a.getAppleProvidername());
        System.out.println("苹果商的地址为:"+a.getAppleprovideraddress());
    }
}

日志记录

// 注解类
package com.example.springboot01.util;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface TestAnnotation {
    boolean printInstance() default false;
}

// 切面类
package com.example.springboot01.util;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;

@Aspect
@Component
public class TestAspect {
	@Pointcut("@annotation(com.example.springboot01.util.TestAnnotation)")
    public void pointcut() {

    }

    @Before("pointcut()")
    public void before(JoinPoint joinPoint) {
        try {
            String methodName = joinPoint.getSignature().getName();
            //Class clazz = joinPoint.getThis().getClass();
            Class clazz = Class.forName("com.example.springboot01.HomeController");
            Method m = clazz.getMethod(methodName);
            if (m.isAnnotationPresent(TestAnnotation.class)) {
                if (m.getAnnotation(TestAnnotation.class).printInstance()) {
                    System.out.println(clazz.getName());
                }
            }
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

	// 测试方法
    @TestAnnotation(printInstance = true)
    public Set<String> getKeys() throws InterruptedException {
        Set<String> set = redisTemplate.keys("*");
        Iterator<String> iterator = set.iterator();
        while(iterator.hasNext()) {
            if(iterator.next().matches("spring:session.*")) {
                iterator.remove();
            }
        }
        return set;
    }
  • 注解想起作用,一般都是通过反射来完成的.
  • 先是获取类对象,再获取这个类的指定方法,判断这个方法是否标注了指定的注解,获取到注解里面的值,根据不同的值来执行不同的处理逻辑.