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???
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???
解决方案 »
- Hibernate 怎么报这样的错?
- eclipse开发struts登陆界面报错java.lang.UnsupportedClassVersionError: Bad version nu望高手解决
- 正则如何删除 "> <"中间的空格
- hibernate中如何判断数据库是否断开?
- 发现JAVA两个问题,SPLIT和REPLACEALL,希望有高手可以解答
- 半年没来了,提个hibernate的问题,大家帮看看吧
- Struts的<logic:iterate>只能显示formBean中的数据,不能把数据提交到formBean中?
- 高分求救,在axis 中如何调用 EJB
- 那位有基于struts框架的jsp程序拿来参考一下学习学习。尤其是struts框架的配置
- Collection出现的问题(在线等待)
- spring与webwork整合需要的jar包?
- extjs panel如何实现最大化?
我不明白为什么getMethodName能代表getAge getName。这只不过是一个字符串而已,这个引用指向了那个方法?
你不明白的地方就是JAVA虚拟机提供的实现,反射部分的代码就是能够利用Class类和对应的方法的名称获得Method对象,无法再进一步解释了
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));
}
上面就是整个过程了