注解

注解

优势

有注解,配置文件可以不用。

概述

注解就是对程序的标注和解释。

public class Zi extends Fu {
    @Override   // 告诉我们的编译器这个方法是重写了父类中的show方法
    // 那么我们在进行方法定义的时候,就需要按照重写方法的要求进行方法定义
    public void show() {
        System.out.println("子类的方法");
    }

    @Deprecated //表示这是一个过时的方法
    public void method() {
        System.out.println("method......");
    }

    @SuppressWarnings(value = "all")    //压制本方法中所有的警告
    public void function() {
        int a = 10;
        int b = 20;
//        System.out.println(a);
//        System.out.println(b);
    }
}

注释和注解的区别

注释:是给程序员看

注解:是给编译器看的(让虚拟机看到程序中的注解,注解代表程序的一些特殊功能)

自定义注解

格式:

public @interface 注解名称{
public 属性类型 属性名 () default 默认值;
}

//例如
public @interface Test{
public int a() default 23;
}

public 可以省略。

public @interface Anno1 {
    // 定义一个基本类型的属性
    int a() default 23;

    // 定义一个String类型的属性
    public String name();

    // 定义一个Class类型的属性
    public Class clazz() default Anno2.class;

    // 定义一个注解类型的属性
    public Anno2 anno() default @Anno2;

    // 定义一个枚举类型的属性
    public Season season() default Season.SPRING;

    // 以上类型的一维数组
    // int数组
    public int[] arr() default {1, 2, 3, 4, 5};

    // 枚举数组
    public Season[] seasons() default {Season.SPRING, Season.AUTOMN};
     // value, 后期我们在使用注解的使用,我们只需要给注解的value属性赋值
    // 那么value就可以省略
    public String value();
}

// 注解的使用
// 在使用注解的时候,如果注解里面的属性没有指定默认值
// 那么我们就需要手动给出注解属性的设置值
// @Anno1(name = "charley")
@Anno1("abc")   //如果只有value没有指定默认值,那么可以把value简化,直接赋值
public class AnnoDemo {
}

注解练习

// Annotation
// 表示Test这个注解的存活时间
@Retention(value = RetentionPolicy.RUNTIME)
public @interface Test {
}

//UseTest.java
public class UseTest {
    // 没有使用Test注解
    public void show(){
        System.out.println("UseTest....show....");
    }

    // 使用Test注解
    @Test
    public void method(){
        System.out.println("UseTest....method....");
    }

    // 没有使用Test注解
    @Test
    public void function(){
        System.out.println("UseTest...function...");
    }
}

//AnnotationDemo.java
public class AnnoDemo {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException {
        // 1.通过反射获取到UseTest的字节码文件对象
        Class clazz = Class.forName("com.charley.myanno3.UseTest");

        // 创建对象
        UseTest useTest = (UseTest) clazz.newInstance();

        //2.通过反射获取这个类里面所有的方法对象
        Method[] methods = clazz.getDeclaredMethods();

        // 3. 遍历数组,得到每一个方法对象
        for (Method method : methods) {
            // method依次表示每一个方法对象
            // isAnnotationPresent(Class<? extends Annotation> annotationClass)
            // 判断当前方法上是否有指定的注解
            // 参数:注解的字节码文件对象
            //返回值:布尔结果,true存在,false不存在
            if (method.isAnnotationPresent(Test.class)){
                method.invoke(useTest);
            }
        }
    }
}