java反射+注解

一、反射

  获取Class类对象

public class A01junit {
    @Before
    public void beforefun() {
//        System.out.println("测试之前");
    }

    @Test
    public void test01() throws ClassNotFoundException {
        //获取class类对象的3种方式
        Class<?> personclass1 = Class.forName("Person");//常用于配置文件
        Class<Person> personclass3 = Person.class;//常用于方法参数
        Class<? extends Person> personclass2 = new Person().getClass();

        //断言
        Assert.assertTrue(personclass1 == personclass2);
        Assert.assertTrue(personclass2 == personclass3);
    }

    @After
    public void afterfun() {
//        System.out.println("测试之后");
    }
}

   反射获取字段、构造器、方法

public class A02reflex {
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, InstantiationException {
        Class<Person> personClass = Person.class;

        //字段操作
//        Person person = new Person("孟美岐", 18);

//        Field field = personClass.getField("name");//获取public修饰的字段
//        Field[] fields = personClass.getFields();//获取所有public修饰的字段

//        Field field = personClass.getDeclaredField("name");//获取字段,不考虑修饰符
//        Field[] fields = personClass.getDeclaredFields();//获取所有字段,不考虑修饰符
//        field.setAccessible(true);//设置允许访问private修饰的属性
//        System.out.println(field.get(person));

        //构造器操作
//        Constructor<Person> constructor = personClass.getConstructor(String.class, Integer.class);
//        System.out.println(constructor.newInstance("孟美岐", 18));

//        Person person = personClass.newInstance();
//        person.setName("黄婷婷");
//        person.setAge(18);
//        System.out.println(person);

        //方法操作
//        Person person = new Person();
//        Method setName = personClass.getMethod("setName", String.class);
//        Method setAge = personClass.getMethod("setAge", Integer.class);
//        setName.invoke(person, "鞠婧祎");
//        setAge.invoke(person, 16);
//        System.out.println(person);

        //获取全限定类名
//        System.out.println(personClass.getName());
        //获取方法名
//        Method[] methods = personClass.getMethods();
//        for (Method method : methods) {
//            System.out.println(method.getName());
//        }
    }
}

   

二、反射案例

  类文件

    Teacher.java

public class Teacher {
    public void teach(){
        System.out.println("教师教书");
    }
}

    Student.java

public class Student {
    public void study(){
        System.out.println("学生学习");
    }
}

  配置文件

    application.properties

className=Student
methodName=study

  启动文件

public class A03reflexdemo {
    public static void main(String[] args) throws Exception {
//        获取加载器,将配置文件加载进内存
        ClassLoader classLoader = A03reflexdemo.class.getClassLoader();
        InputStream inputStream = classLoader.getResourceAsStream("application.properties");

//        读取配置文件
        Properties properties = new Properties();
        properties.load(inputStream);
        String className = properties.getProperty("className");
        String methodName = properties.getProperty("methodName");

//        获取类的class对象,创建对象
        Class objclass = Class.forName(className);
        Object obj = objclass.newInstance();

//        获取方法,执行方法
        Method objmethod = objclass.getMethod(methodName);
        objmethod.invoke(obj);
    }
}

三、注解

  1、注解分类

//        1、文档注解,可通过javadoc命令生成文档
//          注释中使用,@param(参数)、@return(返回值)、@version(版本)、@since(开始版本)、@author(作者)
//        2、预定义注解
//          方法、字段、类上使用,@Override(重写)、@Deprecated(过期)、@SuppressWarnings("all")(取消警告)
//        4、元注解
//          @Target(ElementType.METHOD)//描述注解能够作用的位置
//          @Retention(RetentionPolicy.RUNTIME)//描述注解被保留的阶段
//          @Documented//描述注解是否被抽取到api文档中
//          @Inherited//描述注解是否被子类继承
//        3、自定义注解

  2、自定义注解

    定义枚举类

public enum ColorEnum {
    red, green, yellow, blue
}

    定义注解

public @interface AnotherAnnotation {
}

    定义注解属性

@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    String name() default "孟美岐";

    int age() default 18;

    ColorEnum color() default ColorEnum.red;

    AnotherAnnotation anno() default @AnotherAnnotation;

    int[] arr() default {1, 2};
}

    使用

public class A04annotation {
    public static void main(String[] args) {
//        1、定义注解属性的返回值类型要求
//            *基本数据类型
//            *String
//            *枚举
//            *注解
//            *以上类型的数组
//        2、注解属性的赋值
//            *使用注解时,定义的属性必须赋值(使用default关键字给属性赋默认值,可以不用赋值)
//            *如果注解只有一个属性,且属性名为value,使用注解时value可以省略,括号中直接赋值
//            *属性为数组时,多个值使用,分隔{}包裹,单个值{}可以省略
    }

    @MyAnnotation(arr = 1)
    public void testAnnotation() {

    }
}

   3、解析注解

@MyAnnotation
public class A04annotation {
    public static void main(String[] args) throws NoSuchMethodException {
        Class<A04annotation> objclass = A04annotation.class;
//        获取在内存中生成的实现了该注解接口的子类对象
        MyAnnotation annotationclass = objclass.getAnnotation(MyAnnotation.class);

        Method method = objclass.getMethod("method");
        MyAnnotation annotationMethod = method.getAnnotation(MyAnnotation.class);

        int age = annotationclass.age();
        String name = annotationMethod.name();
        System.out.println(age);
        System.out.println(name);
    }

    @MyAnnotation
    public void method() {

    }
}
原文地址:https://www.cnblogs.com/linding/p/13535902.html