一、反射
获取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() { } }