1.类的 类类型(ClassType)
类的类类型可以用来做很多事,我们可以通过它获取到类的名称,类的路径,类的成员变量,类的方法等等,还可以通过它获得类的实例化对象。
我们可以通过 类名.class 来得到类的类类型,如下面的 c1
Class c1 = ReflectDemo.class;
我们可以通过类的实例对象得到类的类类型
ReflectDemo demo1 = new ReflectDemo(); Class c2 = demo1.getClass();
还可以通过类的包路径加类名获得类的类类型
Class c3 = Class.forName("reflectdemo.ReflectDemo");
值得注意的是,每个类只有一个类类型,也就是说上面的 c1, c2 , c3 指向的是同一个对象。
在开头也说了,类的类类型同样可以得到类的实例,所以两者可以相互得到。
类自身,类的类类型 和 类的实例对象 的关系如下图:
2.通过类的类类型获取类的成员变量以及方法
自己写了一个方法,通过传入某个类的实例对象,就能得到该类的方法。
其中 getMethod() 方法是获取类中所有public方法,包括父类的 public 方法;getDeclareMethod()方法可以获取本类中声明的所有方法,不论权限
public static void getClassMethods(Object obj){ Class c = obj.getClass(); //获取类类型 Method []ms = c.getMethods(); //获取类中所有的public方法,包括父类中的方法 Method []ms2 = c.getDeclaredMethods(); ////获取该类自己声明的所有方法,不论权限 Field []fields = c.getFields(); //获取类中public级成员变量 for(Field f:fields){ String fieldType = f.getType().getSimpleName(); //获得成员变量类型 String fieldName = f.getName(); //获得成员变量名 System.out.println(fieldType+" "+fieldName); } for(Method m:ms){ String type = m.getReturnType().getName(); //方法的返回值类型 System.out.print(type+" "); String methodName=m.getName(); //方法名 System.out.print(methodName+"("); Class []params = m.getParameterTypes(); //方法中 参数的类类型 元组 for(Class param:params){ String parName = param.getName(); //从参数类类型中得到参数名 System.out.print(parName+" "); } System.out.println(");"); } }
3.通过反射来操作方法
除了上面通过getMethods()和getDeclaredMethods()获取方法数组之外,还可以通过getMethod()和getDeclaredMethod()来对单个方法进行查找。
这时就要注意,想要定位一个方法,必须要传入正确的方法名以及参数类类型才行。如下:
public class ReflectDemo2 { public void print(){ System.out.println("a+b"); } public String add(String a,String b){ return a+b; } public int add(int a,int b){ return a+b; } }
我们想要获取对应的方法就要进行如下操作:
ReflectDemo2 demo=new ReflectDemo2(); Class c=ReflectDemo2.class; try { //通过传入的方法名称和参数类类型来获得某一确定方法的类类型 // Method m1=c.getMethod("add", new Class[]{int.class,int.class}); //第一个参数为方法名,后面既可以传入一个类类型数组,也可以单独地传入类类型 Method m1=c.getMethod("add",int.class,int.class); Object obj = m1.invoke(demo, 10,20); //通过invoke()来执行方法,要传入类的实例对象以及对应参数的值 System.out.println(obj); Method m2=c.getMethod("print"); //如果没有参数要传入,直接输入方法名即可 m2.invoke(demo); //如果方法没有返回值,可以不用获取 } catch (Exception e) { e.printStackTrace(); } }
结果和平常使用类的实例对象调用方法的结果是一样的。
待编辑。。
时间: 2024-10-28 15:24:24