1、自定义的MyAnnotation注解
package com.ydlclass.reflect;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.FIELD,ElementType.METHOD,ElementType.TYPE,ElementType.CONSTRUCTOR})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
String name() default "铁蛋";
}
2、Dog类
package com.ydlclass.reflect;
import java.lang.annotation.Documented;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@MyAnnotation
public class Dog {
private String name;
public int age;
public Dog() {
}
@MyAnnotation(name = "有参构造")
public Dog(String name, int age) {
this.name = name;
this.age = age;
}
public Dog(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@MyAnnotation(name = "吃方法")
public void eat(){
eat(null);
}
public void eat(String foodName){
System.out.println(this.getName() + "正在吃:" + foodName);
}
}
3、反射的常见获取构造器创建对象,获取字段设置字段,获取不同的重载方法,获取特定的注解
package com.ydlclass.reflect;
import org.junit.Test;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class ReflectTest {
Class<Dog> aClass = Dog.class;
@Test
public void classTest(){
ClassLoader classLoader = aClass.getClassLoader();//可以从classPAth中加载对应的类,out目录下加载
boolean annotation = aClass.isAnnotation();//判断class对象是否是一个注释
Dog dog = null;
try {
dog = aClass.newInstance();//jdk9之后,此种方式过时了
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
dog.setName("123");
System.out.println(dog.getName());
System.out.println(annotation);
}
@Test
public void testField() throws NoSuchFieldException, IllegalAccessException {
Field[] fields = aClass.getFields();
for (Field field : fields) {
System.out.println(field.getName());//直接使用此方法无法获取成员变量的名字,只能拿到public的成员变量
}
System.out.println("-----------");
//可以使用这个方法获得所有的字段,自然的也就可以为所有的字段赋值
Field[] declaredFields = aClass.getDeclaredFields();
for (Field declaredField : declaredFields) {
System.out.println(declaredField.getName());
}
//赋值操作需要给指定的对象赋值
Dog dog = new Dog("吴签",33);
//获取这个对象的name字段
Field name = aClass.getDeclaredField("name");
//修改这个字段
//暴力注入
name.setAccessible(true);
name.set(dog,"jerry");
System.out.println(name.get(dog));
//由于name为private修饰,所以上面的设置不能为private的值
}
@Test
public void testMethod() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
//Method[] methods = aClass.getMethods();//获取public修饰的方法
//for (Method method : methods) {
// System.out.println(method.getName());
//}
Method[] declaredMethods = aClass.getDeclaredMethods();//获取所有的方法(不包括继承父类的方法)
//for (Method declaredMethod : declaredMethods) {
// System.out.println(declaredMethod.getName());
//}
//获取一个方法
Method eat = aClass.getDeclaredMethod("eat");//可以只填方法名
Method eat1 = aClass.getDeclaredMethod("eat", String.cla***这种方式获取重载的方法,
// 由于重载方法相同;
//对于方法而言,就是调用方法;invoke方法中需要传入两个参数,分别为需要调用的对象,已经这个方法对应的需要的参数
Dog dog2 = new Dog("zhangsan",123);
eat.invoke(dog2);//重载方法直接的调用形式,eat对象是无参数的方法,所以使用时不需要传入参数
eat1.invoke(dog2,"骨头");//eat1是有参数的方法,使用invoke对象调用这个对象的方法,需要传入这个方法需要的参数;
/***
* 输出为:
* zhangsan正在吃:null
* zhangsan正在吃:骨头
*/
}
@Test
public void testConstruct() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
Constructor<Dog> constructor = aClass.getConstructor();
//获取无参构造器器,并且构造对象
Constructor<Dog> declaredConstructor = aClass.getDeclaredConstructor();
Dog dog = declaredConstructor.newInstance();//构造了一个对象
//获取有参构造器,实例化对象
Constructor<Dog> declaredConstructor1 = aClass.getDeclaredConstructor(String.class, int.class);
Dog dog1 = declaredConstructor1.newInstance("反射狗", 666);
System.out.println(dog1.getName());
}
@Test
public void testAnnotation() throws NoSuchFieldException, NoSuchMethodException {
//1.通过类对象获取指定的注解,获取的是注解在Dog类对象上的注解
MyAnnotation annotation = aClass.getAnnotation(MyAnnotation.class);
System.out.println(annotation.name());
//2.通过制定的方法获取注解在方法上的注解
Method eat = aClass.getDeclaredMethod("eat");
MyAnnotation annotation1 = eat.getAnnotation(MyAnnotation.class);
System.out.println(annotation1.name());
//3.通过构造器的方式获取注解在构造器上面的注解
Constructor<Dog> constructor = aClass.getConstructor(String.class, int.class);
MyAnnotation declaredAnnotation = constructor.getDeclaredAnnotation(MyAnnotation.class);
System.out.println(declaredAnnotation.name());
}
}