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));
}