zoukankan      html  css  js  c++  java
  • 《疯狂Java讲义》(三十)---- Annotation

    • 限定重写父类方法:@Override

    作用是告诉编译器检查这个方法,保证父类要包含一个被该方法重写的方法,否则就会编译出错。

    • 标记已过时:@Deprecated

    用于表示某个程序元素(类或方法)已过时,当其他程序使用已过时的类或方法时,编译器会给出警告。

    • 抑制编译器警告:@SuppressWarnings

    指示被该Annotation修饰的程序元素取消显示指定的编译器警告。@SuppressWarnings会一直作用于该程序元素的所有子元素。

    通常情况下,如果程序中使用没有泛型限制的集合将会引起编译器警告,为了避免这种编译器警告,可以使用@SuppressWarnings修饰。@SuppressWarnings(value="unchecked")

    用于修饰Annotation的Annotation

    • @Retention

    只能用于修饰一个Annotation定义,用于指定被修饰的Annotation可以保留多长时间。

    @Retention(value = RetentionPolicy.RUNTIME)
    public @interface Testable()

    或者也可以省略value

    @Retention(RetentionPolicy.SOURCE)
    public @interface Testable()

    表示Testable这个Annotation只保留在源码中,编译器会直接丢弃Retention为SOURCE的Annotation

    • @Target

    指定被修饰的Annotation能用于修饰哪些程序单元,如constructor,field,method,怕人阿meter,package等。

    @Target(ElementType.Field)
    public @interface ActionListenerFor()
    • @Documented

    用于指定Annotation类将被javadoc工具提取成文档,如果定义Annotation类时使用了@Documented修饰,则所有使用该Annotation修饰的程序元素的API文档中将会包含该Annotation说明。

    • @Inherited

    指定被它修饰的Annotation将具有继承性----如果某个类使用了@A Annotation(A annotation使用了@Inherited修饰)修饰,则其子类将自动被@A 修饰。

    • 自定义Annotation

    定义新的Annotation类型使用@interface关键字,默认情况下,Annotation可用于修饰任何程序元素,包括类,接口,方法等。

    public @interface Test {
    }

    自定义Annotation也可以带成员变量,成员声明和接口方法声明类似,成员的声明有以下几点限制:

    1. 成员以无入参无抛出异常的方式声明,如boolean value(String str)/boolean value() throws Exception等都是非法的。
    2. 可以通过default为成员指定一个默认值,当然也可以不指定。
    3. 成员类型是受限的,合法的类型包括基本类型及其包装类型,String,Class,enums和注解类型以及上述类型的数组类型。自定义类型是不允许的。

    如果注解只有一个成员,则成员名必须取名为value(),在使用时可以忽略成员名和赋值号(=),如@NeedTest(true).注解类拥有多个成员时,如果仅对value成员进行赋值则也可以不使用赋值号,如果同时对多个成员进行赋值,则必须使用赋值号。注解类可以没有成员,没有成员的注解成为标识注解。

    public @interface MyTag {
        String name() default "ivy";
        int age() default 18;
    }
    public class Test {
        @MyTag(name="xx", age=6)
        public void info() {
        }
    }

    当开发者使用Annotation修饰了类,方法,Field等成员后,这些Annotation不会自己生效,必须有开发者提供相应的工具来提取并处理Annotation信息。

    Annotation[] aArray = Calss.forName("Test").getMethod("info").getAnnotations();
    for(Annotation an : aArray) {
        if (an instanceof MyTag1) {
        System.out.println("tag.name():" + ((MyTag1)tag).method1());
      }
      if (an instanceof MyTag2) {
        System.out.println("tag.name():" + ((MyTag2)tag).method1());
      }
    }

    Example:

    package com.ivy.annotation;
    
    import java.lang.annotation.Retention;
    import java.lang.annotation.Target;
    import static java.lang.annotation.ElementType.*;
    import java.lang.annotation.RetentionPolicy;
    
    @Retention(RetentionPolicy.RUNTIME)
    @Target(value={METHOD})
    public @interface Testable {
    
    }
    package com.ivy.annotation;
    
    public class MyTest{
    
        @Testable
        public static void m1(){
            
        }
        
        public static void m2(){
                
        }
        @Testable
        public static void m3(){
            throw new RuntimeException("Boom");
        }
        
        public static void m4(){
            
        }
        
        @Testable
        public static void m5(){
            
        }
        
        public static void m6(){
            
        }
        @Testable
        public static void m7(){
            throw new RuntimeException("Crash");
        }
        
        public static void m8(){
            
        }
        
    
    }
    package com.ivy.annotation;
    
    import java.lang.reflect.Method;
    
    public class ProcessTest {
        public static void process(String clazz) throws SecurityException, ClassNotFoundException {
            int passed = 0;
            int failed = 0;
            
            for(Method m : Class.forName(clazz).getMethods()) {
                if (m.isAnnotationPresent(Testable.class)) {
                    try {
                        m.invoke(null);
                        passed++;
                    } catch (Exception ex) {
                        System.out.println("method" + m + "failed :" + ex.getCause());
                        failed++;
                    }
                }
            }
            System.out.println("All run methods :" + (passed+failed) + "passed :" + passed + "failed: " + failed);
        }
    }
    package com.ivy.annotation;
    
    public class RunTest {
    
        public static void main(String[] args) throws SecurityException, ClassNotFoundException {
            // TODO Auto-generated method stub
            ProcessTest.process("com.ivy.annotation.MyTest");
        }
    
    }

    注意:Class.forName(String className) 此处className必须是class全称,包含包名。

  • 相关阅读:
    mysql GROUP_CONCAT 查询某个字段(查询结果默认逗号拼接)
    mysql中find_in_set的使用
    Libev源码分析07:Linux下的eventfd简介
    Libev源码分析06:异步信号同步化--sigwait、sigwaitinfo、sigtimedwait和signalfd
    Nova中的Hook机制
    Python深入:stevedore简介
    Libev源码分析05:Libev中的绝对时间定时器
    Python深入:setuptools简介
    Libev源码分析04:Libev中的相对时间定时器
    Libev源码分析02:Libev中的IO监视器
  • 原文地址:https://www.cnblogs.com/IvySue/p/6396236.html
Copyright © 2011-2022 走看看