import java.io.PrintStream;
import java.lang.reflect.*;class Person {
public int age; public String hairColor; public Person(int age, String hairColor) {
this.age = age;
this.hairColor = hairColor;
}
}public class ReflectionTest { private static PrintStream out = System.out; /**
* This method is used to get public fields of an instanced object.
*/
public static Object getProperty(Object obj, String fieldName) throws Exception {
Class ownerClass = obj.getClass();
Field field = ownerClass.getField(fieldName);
Object property = field.get(obj); return property;
} /**
* This method is used to set public fields of an instanced object.
*/
public static void setProperty(Object obj, String fieldName, Object newValue) throws Exception {
Class objClass = obj.getClass();
Field field = objClass.getField(fieldName);
field.set(obj, newValue);
} /**
* This method is used to set public fields of an instanced object.
*/
public static Object newInstance(String className, Object parameter[]) throws Exception {
Class cls = Class.forName(className);
int pLength = parameter.length;
Class parameterTypes[] = new Class[pLength];
for (int i = 0; i < pLength; i++) {
parameterTypes[i] = parameter[i].getClass();
}
Constructor con = cls.getConstructor(parameterTypes);
Object argList[] = new Object[pLength];
for (int i = 0; i < pLength; i++) {
argList[i] = parameter[i];
} return con.newInstance(argList);
} public static void main(String[] args) {
Object parameter[] = {23, "Red"};
try {
Object a = newInstance("Person", parameter);
out.println("person age is " + getProperty(a, "age"));
setProperty(a, "age", 34);
out.println("person age is " + getProperty(a, "age"));
} catch (Exception e) {
e.printStackTrace();
}
}
}
这段代码不能运行,关键是这里
for (int i = 0; i < pLength; i++) {
parameterTypes[i] = parameter[i].getClass();
}如果改成
parameterTypes[0] = int.class;
parameterTypes[1] = String.class;就可以运行了,但这样是hard code的,有高手知道怎么获取类字面变量吗?
import java.lang.reflect.*;class Person {
public int age; public String hairColor; public Person(int age, String hairColor) {
this.age = age;
this.hairColor = hairColor;
}
}public class ReflectionTest { private static PrintStream out = System.out; /**
* This method is used to get public fields of an instanced object.
*/
public static Object getProperty(Object obj, String fieldName) throws Exception {
Class ownerClass = obj.getClass();
Field field = ownerClass.getField(fieldName);
Object property = field.get(obj); return property;
} /**
* This method is used to set public fields of an instanced object.
*/
public static void setProperty(Object obj, String fieldName, Object newValue) throws Exception {
Class objClass = obj.getClass();
Field field = objClass.getField(fieldName);
field.set(obj, newValue);
} /**
* This method is used to set public fields of an instanced object.
*/
public static Object newInstance(String className, Object parameter[]) throws Exception {
Class cls = Class.forName(className);
int pLength = parameter.length;
Class parameterTypes[] = new Class[pLength];
for (int i = 0; i < pLength; i++) {
parameterTypes[i] = parameter[i].getClass();
}
Constructor con = cls.getConstructor(parameterTypes);
Object argList[] = new Object[pLength];
for (int i = 0; i < pLength; i++) {
argList[i] = parameter[i];
} return con.newInstance(argList);
} public static void main(String[] args) {
Object parameter[] = {23, "Red"};
try {
Object a = newInstance("Person", parameter);
out.println("person age is " + getProperty(a, "age"));
setProperty(a, "age", 34);
out.println("person age is " + getProperty(a, "age"));
} catch (Exception e) {
e.printStackTrace();
}
}
}
这段代码不能运行,关键是这里
for (int i = 0; i < pLength; i++) {
parameterTypes[i] = parameter[i].getClass();
}如果改成
parameterTypes[0] = int.class;
parameterTypes[1] = String.class;就可以运行了,但这样是hard code的,有高手知道怎么获取类字面变量吗?
解决方案 »
- Java的switch语句支持byte、short、char、int、long、String和enum(枚举)吗?
- JTextPane setPage 加载html文件后 垂直滚动条不能停在最下端,求解决方法
- 负数的byte 转换成 short 问题
- Java文件操作
- 一个简单的JAVA算法问题
- windows下双击.jar文件
- 新手才学Java。。请教如何添加包呀?
- java 控件 汉字显示为方块 如何处理
- 一个程序运行有问题,大家帮帮忙!
- 那里可以下载hibernate?今天hibernate官网下不了.
- 有谁用过Jbuilder2007?编辑器里的字体能不能改?
- 有谁用过Jbuilder2007么?
关注,学习等答案帮推good luck
for (int i = 0; i < pLength; i++) {
parameterTypes[i] = parameter[i].getClass();
}
的方式返回的是Integer类对象,而parameterTypes[0] = int.class返回的是int对象,只要你在构造Person的时候用Integer别用int,使用代码中的方法就没问题了,即
for (int i = 0; i < pLength; i++) {
parameterTypes[i] = parameter[i].getClass();
}
所以获取的class是Integer.class而不是int.class,调用方法时肯定找不到(Integer,String)的签名.也就是那个方法找不到.
这里可以判断一下,如果Class为Integer.class,Short.class等,先try一下,找不到的话再将转换一下.
不过楼主传过去的就是一个Integer的23,(是object数组的关系,就自动编程Integer)
再还原到int的话,不知道java能不能,有什么办法能。int的class,有一个叫isPrimitive可以和Integer的class区分开。不过反过来我估计不行,
因为程序也不知道某个class,到底是Integer的还是int的
另外说一下,
楼主不想硬编码估计不行,
因为下面这两个方法是不一样的,
public Person(int age, String hairColor)
public Person(String hairColor, int age)
对于Person类是两个不同的构造函数,
所以,如果想要动态的调用某个构造函数,
应该取得所有的构造函数,然后再取得这些构造函数的ParameterTypes,
然后再一个一个的对比,
最后找到要调用的构造函数,再执行
有一点点跑题了!
继续等答案吧good luck
而你在 定义 Object parameter[] = {23, "Red"};的时候,jvm自动把23封装成了Integer,
所以在后面的:
for (int i = 0; i < pLength; i++) {
parameterTypes[i] = parameter[i].getClass();
}
里面parameter[0].getClass()获得的是Integer.class,所以jvm寻找的是Person(Integer age, String c)
这个构造方法,你声明的是(int i, String c),当然找不到了.
要注意的是Integer类型jvm可以自动解封装为int型,但是Integer.class是不会被jvm认为和int.class是相同的
所以造成 NoSuchMethodException,(java.lang.Integer, java.lang.String)
如果你能弄明白我上面说的话,相信这个问题你很容易就能解决了.
因为在实际调用的时候,参数由程序员控制传入的,所以它的类型也一样由程序员控制传入.其它任何地方转换都是不合理的.即你在调用 反映方法 ref时,既然你要传入new Object[]{23,"xxxx"};你就知道需要传new Class[]{int.class,String.class}而不是
从Object动态获取.其实这也是严谨的C的做法.JAVA把人教懒了.
不懂IOC,能介绍介绍吗?呵呵
Class cls = Class.forName(className);
int pLength = parameter.length;
Class parameterTypes[] = new Class[pLength];
Constructor ctorlist[] = cls.getDeclaredConstructors();
parameterTypes= ctorlist[0].getParameterTypes(); //这里还是硬编码,ctorlist[0]
Constructor con = cls.getConstructor(parameterTypes);
Object argList[] = new Object[pLength];
for (int i = 0; i < pLength; i++) {
argList[i] = parameter[i];
} return con.newInstance(argList);
}用这个方法倒可以,但还是硬编码的,见注释。
现在不是spring很流行,里面的newInstance方法最终目的是构造一个bean,与spring applicationcontext.getBean(id)是一样的啊
Object parameter[] = {23, "Red"};
try {
Object a = newInstance("Person", parameter); //这里的Person,类似于容器时的bean id
out.println("person age is " + getProperty(a, "age"));
setProperty(a, "age", 34);
out.println("person age is " + getProperty(a, "age"));
} catch (Exception e) {
e.printStackTrace();
}
Object parameter[] = {23, "Red"};相当于spring容器初始注入的值,后面自己要怎么搞就怎么搞
for (int i = 0; i < pLength; i++) {
parameterTypes[i] = parameter[i].getClass();
}
这有问题吧 界限