1.基本语法
1.1 注解的分类
按运行机制分
源码注解
注解只存在于源码中,编译成.class文件就不存在了编译时注解
注解在源码和.class文件中都存在运行时注解
在运行阶段还能起作用,甚至会影响运行逻辑的注解
按来源分
- 来自JDK的注解
- 来自第三方的注解
- 我们自定义的注解
源注解
元注解类型 :
@Target 与 @Retention 取值类型 :
1.2 如何自定义注解
所有的Annotation自动实现java.lang.annotation.Annotation接口
注解支持类型:
八种基本数据类型和String、Enum、Class、annotation以及以上类型的数组)
// 注解的作用域
@Target({ElementType.METHOD, ElementType.TYPE, ElementType.FIELD})
// 注解的生命周期
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface Description {
String desc();
String author();
int age() default 18;
}
public class Person {
@Description(desc="帅哥", author = "wxf")
public void introduce() {
System.out.println("大家好, 我是王晓峰");
}
}
1.3 解析
通过反射获取类,方法,属性上的注解
class Person {
@Description(desc = "属性上的注解", author = "wxf2")
private String name;
@Description(desc = "方法上的注解", author = "wxf3")
public void introduce() {
System.out.println("大家好, 我是王晓峰");
}
public static void main(String[] args) throws NoSuchMethodException {
// 1.获取Person类的Class对象
Class<?> cls = Person.class;
// 2.通过反射获取到 introduce() 方法对象
Method method = cls.getMethod("introduce", new Class[]{});
// 3.判断该方法上是否存在指定类型的注解
if (method.isAnnotationPresent(Description.class)) {
Description annotation = method.getAnnotation(Description.class);
String desc = annotation.desc();
String author = annotation.author();
int age = annotation.age();
System.out.println(desc + ", " + author + ", " + age);
}
}
}
声明注解的属性 :
如果注解中有一个名称value的属性,那么使用注解时可以省略value=部分
特殊属性value, String[] value;
2.动态代理
2.1 动态代理的代码实现
// 接口
public interface ArithmeticInter {
int sum(int num1, int num2);
int minus(int num1, int num2);
int multiply(int num1, int num2);
int divide(int num1, int num2);
}
// 实现类
public class ArithmeticImpl1 implements ArithmeticInter {
@Override
public int sum(int num1, int num2) {
int result = num1 + num2;
return result;
}
@Override
public int minus(int num1, int num2) {
int result = num1 - num2;
return result;
}
@Override
public int multiply(int num1, int num2) {
int result = num1 * num2;
return result;
}
@Override
public int divide(int num1, int num2) {
int result = num1 / num2;
return result;
}
}
public static void main(String[] args) {
// 1.创建一个实现类对象
final ArithmeticInter arithmetic = new ArithmeticImpl1();
// 2.使用动态代理实现方法的调用
// 参数1: 类加载器
ClassLoader loader = ArithmeticImpl1.class.getClassLoader();
// 参数2: 被代理的类实现的所有接口
Class<?>[] interfaces = ArithmeticImpl1.class.getInterfaces();
// 参数3: InvocationHandler 接口, 动态代理具体处理的实现代码, 一般都使用匿名内部类实现
ArithmeticInter proxy = (ArithmeticInter) Proxy.newProxyInstance(loader, interfaces, new InvocationHandler() {
@Override
public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
if (method.getName().endsWith("sum")) {
System.out.println("相加开始");
Object obj = method.invoke(arithmetic, objects);
System.out.println("相加结束");
return obj;
}
return method.invoke(arithmetic, objects);
}
});
System.out.println(proxy.sum(10, 20));
System.out.println(proxy.minus(20, 8));
System.out.println(proxy.multiply(5, 5));
System.out.println(proxy.divide(20, 5));
}