Java反射
1、Class类
1)在面向对象的世界里,万事万物都是对象。(Java语言中,静态的成员、普通数据类型不是对象)
package com.learn.reflect; import java.lang.reflect.Method; public class MethodDemo { public static void main(String[] args) { //要获取print(int, int)方法 1.要获取一个方法就是获取类的信息,获取类的信息首先要获取类的类类型 A a1 = new A(); Class c = a1.getClass(); /** * 2.获取方法 名称和参数列表来决定 * getMethod获取的是public的方法 * getDelcaredMethod获取自己声明的方法 */ try { //Method m = c.getMethod("print", new Class[] {int.class, int.class}); Method m = c.getMethod("print", int.class, int.class); //方法的反射操作 //a1.print(10,20);方法的反射操作是用m对象进行方法的调用 效果与a1.print(10,20)一致 //方法如果没有返回值返回null,有返回值返回对应的返回值 //Object o = m.invoke(a1, new Object[] {10,20}); Object o = m.invoke(a1, 10, 20); System.out.println("--------------------"); //获取方法print(String, String) Method m1 = c.getMethod("print", String.class, String.class); //用方法进行反射操作 //a1.print("hello", "world"); o = m1.invoke(a1, "hello", "world"); System.out.println("--------------------"); //Method m2 = c.getMethod("print", new Class[] {}); Method m2 = c.getMethod("print"); //o = m2.invoke(a1, new Class[] {}); o = m2.invoke(a1); } catch (Exception e) { e.printStackTrace(); } } } class A{ public void print() { System.out.println("hello word"); } public void print(int a, int b) { System.out.println(a+b); } public void print(String a, String b) { System.out.println(a.toUpperCase()+" "+b.toLowerCase()); } }
类是对象,类是java.lang.Class类的实例对象,任何一个类都是Class类的实例对象。
2、三种获取方式
第一种获取方式——任何一个类都有一个隐含的静态成员变量(class)
Class c1 = Foo.class;
第二种获取方式——已知该类的对象,通过getClass方法获取
Class c2 = foo.getClass();
c1,c2表示了Foo类的类类型
第三种获取方式
Class c3 = null;
try{
c3 = Class.forName("com.xxx.xxx.Foo");//包含包名
}catch(ClassNotFoundException e){
e.printStackTrace();
}
3、通过类类型获取该类的实例对象
前提-->该类必须具备无参构造函数
Foo foo = (Foo)c1.newInstance();
4、应用场景——动态加载类,在线升级等
5、getName()获取类名;getSimpleName()获取不带包名的类名;getReturnType()得到方法返回值类型的类类型;
getParameterTypes() 获取参数类型----》得到参数列表的类型的类类型
例:
package com.learn.reflect; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; //打印类的一些信息 public class ClassUtil { /** * 打印成员方法信息 */ public static void printMethodMessage(Object obj) { Class c = obj.getClass(); //获取类的名称 System.out.println("类名是:"+c.getName()); /** * getMethods方法获取的是所有的public的方法,包括父类继承而来的 * getDeclaredMethods()获取自己声明的所有方法 */ Method[] ms = c.getMethods(); for(int i=0; i<ms.length; i++) { //得到方法返回值类型的类类型 Class returnType = ms[i].getReturnType(); System.out.print(returnType.getName()+" "); //得到方法的名称 System.out.print(ms[i].getName()+"("); // 获取参数类型----》得到参数列表的类型的类类型 Class[] paramTypes = ms[i].getParameterTypes(); for(Class pc:paramTypes) { System.out.print(pc.getName()+","); } System.out.println(")"); } } /** *打印成员变量信息 */ public static void printFieldMessage(Object obj) { Class c = obj.getClass(); /* * 成员变量也是对象 * java.lang.reflect.Field * Field类封装了关于成员变量的操作 * getFields()方法获取的是所有的public的成员变量的信息 * getDeclaredFields获取的是该类自己声明的成员变量的信息 */ //Field[] fs = c.getFields(); Field[] fs = c.getDeclaredFields(); for(Field field:fs) { //得到成员变量的类型的类类型 Class fieldType = field.getType(); String typeName = fieldType.getName(); //得到成员变量的名称 String fieldName = field.getName(); System.out.println(typeName+" "+fieldName); } } public static void printConMessage(Object obj) { Class c = obj.getClass(); /** * 构造函数也是对象 * java.lang.Constructor中封装了构造函数的信息 * getConstructors获取所有的public的构造函数 * getDeclaredConstructors得到所有的构造函数 */ // Constructor[] cs = c.getConstructors(); Constructor[] cs = c.getDeclaredConstructors(); for(Constructor con:cs) { System.out.print(con.getName()+"("); //获取构造函数的参数列表--》得到参数列表的类类型 Class[] paramTypes = con.getParameterTypes(); for(Class pc:paramTypes) { System.out.print(pc.getName()+","); } System.out.print(")"); } } }
6、方法的反射 invoke method.invoke(对象,参数列表)
package com.learn.reflect; import java.lang.reflect.Method; public class MethodDemo { public static void main(String[] args) { //要获取print(int, int)方法 1.要获取一个方法就是获取类的信息,获取类的信息首先要获取类的类类型 A a1 = new A(); Class c = a1.getClass(); /** * 2.获取方法 名称和参数列表来决定 * getMethod获取的是public的方法 * getDelcaredMethod获取自己声明的方法 */ try { //Method m = c.getMethod("print", new Class[] {int.class, int.class}); Method m = c.getMethod("print", int.class, int.class); //方法的反射操作 //a1.print(10,20);方法的反射操作是用m对象进行方法的调用 效果与a1.print(10,20)一致 //方法如果没有返回值返回null,有返回值返回对应的返回值 //Object o = m.invoke(a1, new Object[] {10,20}); Object o = m.invoke(a1, 10, 20); System.out.println("--------------------"); //获取方法print(String, String) Method m1 = c.getMethod("print", String.class, String.class); //用方法进行反射操作 //a1.print("hello", "world"); o = m1.invoke(a1, "hello", "world"); System.out.println("--------------------"); //Method m2 = c.getMethod("print", new Class[] {}); Method m2 = c.getMethod("print"); //o = m2.invoke(a1, new Class[] {}); o = m2.invoke(a1); } catch (Exception e) { e.printStackTrace(); } } } class A{ public void print() { System.out.println("hello word"); } public void print(int a, int b) { System.out.println(a+b); } public void print(String a, String b) { System.out.println(a.toUpperCase()+" "+b.toLowerCase()); } }