这个demo在使用反射机制操作属性之前,主要原因是因为在.class文件字节码中,方法排在属性的前面。
1,获得一个类中的方法
先看一下方法和运行结果。获取所有的方法使用Class类中getMethos()方法。
待获取的类:
12345678910111213141516171819202122232425262728293031323334353637383940414243444546 | package com.aaron.reflect; public class Heros { private String name; //名字 private String type; //类型 private int camp; //0,近卫;1,天灾 public Heros(){} public Heros(String name, String type, int camp) { super (); this .name = name; this .type = type; this .camp = camp; } public String getName() { return name; } public void setName(String name) { this .name = name; } public String getType() { return type; } public void setType(String type) { this .type = type; } public int getCamp() { return camp; } public void setCamp( int camp) { this .camp = camp; } @Override public String toString() { return "Heros [\n name=" + name + ", \n type=" + type + ", \n camp=" + camp + "\n]" ; } } |
Hero类中包含了三个属性,和对应的getter和setter方法。另外还有一个toString方法。这是一个非常常见的pojo。
测试类:
12345678910111213 | package com.aaron.reflect; import java.lang.reflect.Method; public class Demo5 { public static void main(String[] args) { Class<?> herosClass = Heros. class ; Method[] methods = herosClass.getMethods(); for (Method method : methods) { System.out.println(method); } } } |
理论上,我们会获得所有的getter和setter,然后还有toString方法
运行结果:
123456789101112131415 | public void com.aaron.reflect.Heros.setType(java.lang.String) public int com.aaron.reflect.Heros.getCamp() public void com.aaron.reflect.Heros.setCamp( int ) public java.lang.String com.aaron.reflect.Heros.toString() public java.lang.String com.aaron.reflect.Heros.getName() public void com.aaron.reflect.Heros.setName(java.lang.String) public java.lang.String com.aaron.reflect.Heros.getType() public final void java.lang.Object.wait( long , int ) throws java.lang.InterruptedException public final native void java.lang.Object.wait( long ) throws java.lang.InterruptedException public final void java.lang.Object.wait() throws java.lang.InterruptedException public boolean java.lang.Object.equals(java.lang.Object) public native int java.lang.Object.hashCode() public final native java.lang.Class java.lang.Object.getClass() public final native void java.lang.Object.notify() public final native void java.lang.Object.notifyAll() |
然而却列出了这么一大堆。
仔细看一下返回的方法,原来把Object类所拥有的方法也返回了。因为我们这个POJO类默认继承的是java.lang.Object类。,例如getClass(),equals()这些。
使用getMethods()这个方法,返回了一个包含某些Method对象的数组,Method对象已经介绍过,用来表示一个方法的对象,是对类中方法进行抽象的结果。
这些对象反映了Class对象所表示的类或者接口,当然,包括那些由该类或者接口声明的以及从超类和超接口继承的那些类或接口。举个例子来解释一下:
例如使用getMethods()获得Integer类的方法,会把Integer的父类,Number的所有方法,以及Number的父类Object的方法都获取出来。
这个返回数组,包括了从Object类继承的所有(公共)member方法。返回数组中的元素没有排序。如果这个Class对象表示没有公共成员方法的类或者接口,或者表示了一个基本类型或者表示void,则返回长度为0的数组。
2,调用类中的方法
直接给出一个Demo,注意参数。
1234567891011121314151617181920 | package com.aaron.reflect; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class Demo5 { public static void main(String[] args) { Class<?> herosClass = Heros. class ; try { Method m1 = herosClass.getMethod( "setName" ,String. class ); Method m2 = herosClass.getMethod( "getName" ); Object userInfo = herosClass.newInstance(); m1.invoke(userInfo, "影魔" ); System.out.println( "调用set方法:" +userInfo); System.out.println( "调用get方法:" +m2.invoke(userInfo)); } catch (Exception e) { e.printStackTrace(); } } } |
运行结果:
12345678 | 调用set方法: Heros [ name=影魔, type= null , camp= 0 ] 调用get方法: 影魔 |