public class ReflectTester {
    public static void main (String[] s) throws Exception
    {
     ReflectTester rt=new ReflectTester();
        rt.copy(new Test());
    }
    
    public Object copy(Object obj) throws Exception{
     Class<?> classType=obj.getClass();
     Constructor cons=classType.getConstructor(int.class,String.class);
     Object ob=cons.newInstance(new Object[]{new Object[]{}});
     Field[] f=classType.getDeclaredFields();
    
     for(Field fi : f){
          
     String name=fi.getName();
          
     String firstLetter=name.substring(0,1).toUpperCase();
          
     String getMethodName="get"+firstLetter+name.substring(1);
     String setMethodName="set"+"get"+firstLetter+name.substring(1);
            
     Method getMethod=classType.getMethod(getMethodName, new Class[]{});
     Method setMethod=classType.getMethod(setMethodName,new Class[]{fi.getType()} );     Object value =getMethod.invoke(obj, new Object[]{});
            
     setMethod.invoke(ob, new Object[]{value});
          
          
      }
   
     return null;
    }
}class Test{
private int id;
private String name;
private int age;

Test(){

}
Test(int i,String n){
this.id=i;
this.name=n;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}

这段代码中Method getMethod=classType.getMethod(getMethodName, new Class[]{});为什么是getMethodName???

解决方案 »

  1.   

    getMethodName代表的就是 方法的名称,比如getAge getName,这是反射调用的形式参数,有什么问题?
      

  2.   


    我不明白为什么getMethodName能代表getAge getName。这只不过是一个字符串而已,这个引用指向了那个方法?
      

  3.   


    你不明白的地方就是JAVA虚拟机提供的实现,反射部分的代码就是能够利用Class类和对应的方法的名称获得Method对象,无法再进一步解释了
      

  4.   


    jvm可以根据字节码分析出有那些字段 哪些方法 你传一个方法名进去后,看源码public Method getMethod(String name, Class<?>... parameterTypes)
            throws NoSuchMethodException, SecurityException {
    // be very careful not to change the stack depth of this
    // checkMemberAccess call for security reasons 
    // see java.lang.SecurityManager.checkMemberAccess
            checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
            Method method = getMethod0(name, parameterTypes);
            if (method == null) {
                throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes));
            }
            return method;
        }
    是通过getMethod0(name, parameterTypes)方法得到的method,再看private Method getMethod0(String name, Class[] parameterTypes) {
            // Note: the intent is that the search algorithm this routine
            // uses be equivalent to the ordering imposed by
            // privateGetPublicMethods(). It fetches only the declared
            // public methods for each class, however, to reduce the
            // number of Method objects which have to be created for the
            // common case where the method being requested is declared in
            // the class which is being queried.
            Method res = null;
            // Search declared public methods
            if ((res = searchMethods(privateGetDeclaredMethods(true),
                                     name,
                                     parameterTypes)) != null) {
                return res;
            }
            // Search superclass's methods
            if (!isInterface()) {
                Class c = getSuperclass();
                if (c != null) {
                    if ((res = c.getMethod0(name, parameterTypes)) != null) {
                        return res;
                    }
                }
            }
            // Search superinterfaces' methods
            Class[] interfaces = getInterfaces();
            for (int i = 0; i < interfaces.length; i++) {
                Class c = interfaces[i];
                if ((res = c.getMethod0(name, parameterTypes)) != null) {
                    return res;
                }
            }
            // Not found
            return null;
        }
    在getMethod0(String name, Class[] parameterTypes)方法中,先会看自己这个类中有没有定义这个方法,如果有则调用searchMethods(privateGetDeclaredMethods(true),name,parameterTypes)方法去得到method,如果本类中没有 则会去父类或接口中找(此处就行递归),再看searchMethods(privateGetDeclaredMethods(true),name,parameterTypes)//这里会把所有的方法加载上来 放到数组中
    private Method[] privateGetDeclaredMethods(boolean publicOnly) {
            checkInitted();
            Method[] res = null;
            if (useCaches) {
                clearCachesOnClassRedefinition();
                if (publicOnly) {
                    if (declaredPublicMethods != null) {
                        res = (Method[]) declaredPublicMethods.get();
                    }
                } else {
                    if (declaredMethods != null) {
                        res = (Method[]) declaredMethods.get();
                    }
                }
                if (res != null) return res;
            }
            // No cached value available; request value from VM
            res = getDeclaredMethods0(publicOnly);
            if (useCaches) {
                if (publicOnly) {
                    declaredPublicMethods = new SoftReference(res);
                } else {
                    declaredMethods = new SoftReference(res);
                }
            }
            return res;
        }
    //这就是从数组中根据方法名后类来找到相应的方法了 
     private static Method searchMethods(Method[] methods,
                                            String name,
                                            Class[] parameterTypes)
        {
      Method res = null;
            String internedName = name.intern();
            for (int i = 0; i < methods.length; i++) {
        Method m = methods[i];
                if (m.getName() == internedName
    && arrayContentsEq(parameterTypes, m.getParameterTypes())
    && (res == null
        || res.getReturnType().isAssignableFrom(m.getReturnType())))
    res = m;
            } return (res == null ? res : getReflectionFactory().copyMethod(res));
        }
    上面就是整个过程了