首先定义一些类和接口
package reflection1; public interface MtInterface { void info(); }
package reflection1; import java.io.Serializable; public class Creature<T> implements Serializable { private char gender; public double weight; public Creature() { super(); } private void breath() { System.out.println("呼吸"); } public void eat() { System.out.println("吃饭"); } }
package reflection1; public class Person extends Creature<String> implements Comparable<String>,MtInterface { private String name; int age; public int id; public Person() { super(); } private Person(String name) { super(); this.name = name; } Person(String name, int age) { super(); this.name = name; this.age = age; } public Person(String name, int age, int id) { super(); this.name = name; this.age = age; this.id = id; } private String show(String nation) throws Exception{ System.out.println("nation="+nation); return nation; } public String display(String interests) { return interests; } @Override public void info() { System.out.println("我是人"); } @Override public int compareTo(String o) { return 0; } private static void showDesc() { System.out.println("static method"); } @Override public String toString() { return "Person [name=" + name + ", age=" + age + ", id=" + id + "]"; } }
反射获取运行时类的属性
package reflection2; import java.lang.reflect.Field; import org.junit.jupiter.api.Test; import reflection1.*; /* * 获取当前运行时类的属性结构 * */ public class FieldTest { @Test public void test1() { Class clazz = reflection1.Person.class; Field [] fields = null; //获取属性结构 //getFields():获取当前运行时类及其父类中所有public的属性 fields = clazz.getFields(); for(Field f:fields) System.out.println(f); System.out.println(""); //getDeclaredFields():获得当前运行时类的所有属性,不包含父类的属性,不考虑权限 fields = clazz.getDeclaredFields(); for(Field f:fields) System.out.println(f); System.out.println(""); } //权限修饰符:数据类型 变量名 @Test public void test2() { Class clazz = reflection1.Person.class; Field [] fields = clazz.getDeclaredFields(); for(Field f:fields) { System.out.println(f); /* * * 1.权限修饰符 * PUBLIC: 1 PRIVATE: 2 PROTECTED: 4 STATIC: 8 FINAL: 16 SYNCHRONIZED: 32 VOLATILE: 64 TRANSIENT: 128 NATIVE: 256 INTERFACE: 512 ABSTRACT: 1024 STRICT: 2048 * */ int modifiers = f.getModifiers(); System.out.println(modifiers); //2.数据类型 Class type = f.getType(); System.out.println(type); //3.变量名 String name = f.getName(); System.out.println(name); System.out.println(""); } } }
反射获得运行时类的方法
package reflection2; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import org.junit.jupiter.api.Test; import reflection1.Person; /* * 获取运行时类的方法结构 * * */ public class MethodTest { @Test public void test1() { Class clazz = Person.class; //getMethods():获取当前类及其父类所有public方法 Method[] methods = clazz.getMethods(); for(Method m:methods) { System.out.println(m); } System.out.print(' '); //获取当前运行时类中的所有方法 methods = clazz.getDeclaredMethods(); for(Method m:methods) { System.out.println(m); } } /* * 权限修饰符,返回值类型,方法名(参数类型1 参数1,参数类型2 参数2,参数类型3 参数3...) * */ @Test public void test2() { //1.获取方法声明的注解 Class clazz = Person.class; Method[]methods = clazz.getDeclaredMethods(); for(Method m:methods) { System.out.println(m); //1.获得方法声明的注解 Annotation[] annos = m.getAnnotations(); for(Annotation a:annos) { System.out.println("注解:"+a); } //2.获取权限修饰符 int modifier = m.getModifiers(); System.out.println("权限:"+modifier); //3.返回值类型 System.out.println("返回值类型:"+m.getReturnType().getName()); //4.方法名 System.out.println("方法名字:"+m.getName()); //5.形参列表 Class [] parameterTypes = m.getParameterTypes(); if(!(parameterTypes == null && parameterTypes.length==0)) { System.out.println("形参列表:"); for(int i=0;i<parameterTypes.length;i++) { Class p = parameterTypes[i]; System.out.println(p.getName()+" args_"+i); } } //6.抛出的异常 Class [] exceptionTypes = m.getExceptionTypes(); for(Class e:exceptionTypes) System.out.println("异常:"+e.getName()); System.out.println(""); } } }
反射获得运行时类的构造器,父类,泛型信息,接口,包等信息
package reflection2; import java.lang.reflect.Constructor; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import reflection1.Person; public class OtherTest { /* * 获取构造器结构 * */ @Test public void test1() { Class clazz = Person.class; //获得public的构造器(无父类) Constructor[] constructors = clazz.getConstructors(); for(Constructor c:constructors) System.out.println(c); System.out.println(); //获得所有构造器 constructors = clazz.getDeclaredConstructors(); for(Constructor c:constructors) System.out.println(c); } /* * 获取运行时类的父类 * */ @Test public void test2() { Class clazz = Person.class; Class superClass = clazz.getSuperclass(); System.out.println(superClass); } /* * 获取运行时带泛型的父类 * */ @Test public void test3() { Class clazz = Person.class; Type superClass = clazz.getGenericSuperclass(); System.out.println(superClass); } /* * 获取运行时带泛型的父类的泛型 * 关于ParameterizedType的理解 * https://www.jianshu.com/p/da21b3a59b47 定义 * https://www.jianshu.com/p/cfa74c980b25 理解 * */ @Test public void test4() { Class clazz = Person.class; Type superClass = clazz.getGenericSuperclass(); ParameterizedType paramType = (ParameterizedType)superClass; //getActualTypeArguments()可以去掉最外面一层<>获得里面的Type数组 Type[] types = paramType.getActualTypeArguments(); System.out.println(types[0].getTypeName()); } /* * 获取运行时类的接口 * */ @Test public void test5() { Class clazz = Person.class; Class[] interfaces = clazz.getInterfaces(); for(Class c:interfaces) System.out.println(c); System.out.println(); Class[] interfaces1 = clazz.getSuperclass().getInterfaces(); for(Class c:interfaces1) System.out.println(c); } /* * 获取类运行时所在包 * */ @Test public void test6() { Class clazz = Person.class; Package package1 = clazz.getPackage(); System.out.println(package1); } }
反射调用运行时类的属性,方法,构造器(反射打破封装性)
package reflection2; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import org.junit.jupiter.api.Test; import reflection1.Person; /* * 调用运行时类中指定的结构:属性,方法,构造器 * */ public class ReflectionTest { /* * 反射调类属性 * * */ @Test public void test1() throws NoSuchFieldException, SecurityException, InstantiationException, IllegalAccessException { Class clazz = Person.class; //创建运行时类对象 Person person = (Person)clazz.newInstance(); //获取指定变量名的属性 Field name = clazz.getDeclaredField("name"); //将该属性权限修改为可获得 name.setAccessible(true); //设置当前对象的属性值:set()方法:参数1:指明设置哪个对象的属性,参数2:将属性设置为多少 name.set(person, "Tom"); /* * 获取当前属性值get():参数1:获取哪个对象的属性值 * */ Field age = clazz.getDeclaredField("age"); age.setAccessible(true); int pAge = (int)age.get(person); System.out.println(pAge); name.setAccessible(false);//还要再改回去 } /* * 操作运行时类中指定的方法 * */ @Test public void test2() throws InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException { Class clazz = Person.class; //创建运行时类对象 Person person = (Person)clazz.newInstance(); //获取指定的某个方法 //参数1:指明获取方法的名称,参数2:指明获取方法的形参列表 Method show = clazz.getDeclaredMethod("show", String.class); //将权限改为可访问 show.setAccessible(true); //invoke():参数1:方法调用者 参数2:给方法形参赋值的实参 //返回值 为调用的方法的返回值 String nation = (String)show.invoke(person,"CHN"); System.out.println(nation); System.out.println("*********************调用静态方法**********************"); //得到这个方法的步骤是一样的 Method showDesc = clazz.getDeclaredMethod("showDesc"); showDesc.setAccessible(true); //由于是静态,直接用这个类去调用就行 showDesc.invoke(Person.class); } /* * 调用运行时类的指定的构造器 * */ @Test public void test3() throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { Class clazz = Person.class; //获取指定的构造器:参数:指明构造器的参数列表 Constructor constructor = clazz.getDeclaredConstructor(String.class); //将权限改为可访问 constructor.setAccessible(true); Person person = (Person)constructor.newInstance("Tom"); System.out.println(person); } }