//测试reflect的用法 import java.lang.reflect.Method;class Model{ public Model(){ System.out.println("this is a model."); }
public String getName(){ System.out.println("Model"); return "Model"; }
public void method(int i, String s){ System.out.println("int parameter " + i + ", the String is " + s); } public void toString(String s){ System.out.println("Model " + s); }
public int test(){ return 1; } }
public class TestReflect{ public static void main(String[] args){ Model model = null; Class c = null; try{ c = Class.forName("Model"); model = (Model)c.newInstance(); //获得Model类的对象 }catch(ClassNotFoundException e){ System.out.println("class not found."); e.printStackTrace(); }catch(Exception ex){ ex.printStackTrace(); }
param是什么类型?作什么用的,应该传什么值?
import java.lang.reflect.Method;class Model{
public Model(){
System.out.println("this is a model.");
}
public String getName(){
System.out.println("Model");
return "Model";
}
public void method(int i, String s){
System.out.println("int parameter " + i + ", the String is " + s);
} public void toString(String s){
System.out.println("Model " + s);
}
public int test(){
return 1;
}
}
public class TestReflect{
public static void main(String[] args){
Model model = null;
Class c = null;
try{
c = Class.forName("Model");
model = (Model)c.newInstance(); //获得Model类的对象
}catch(ClassNotFoundException e){
System.out.println("class not found.");
e.printStackTrace();
}catch(Exception ex){
ex.printStackTrace();
}
try{
Method m = c.getMethod("test", null);//获得Model.test();
m.invoke(model,null); //相当于语句:model.test();
}catch(Exception e){
e.printStackTrace();
}
Class[] classes = {String.class};
try{
Method m = c.getMethod("toString", classes);
Object[] arg = new Object[1];
arg[0] = new String("Test invoke ");
m.invoke(model,arg);
}catch(Exception e){
e.printStackTrace();
}
int i = 15;
try{
classes = {int.class, String.class};
Method m = c.getMethod("method",classes);
Object[] arg = new Object[2]; //arg数组的长度由将要调用的函数的参数个数决定
arg[0] = new Integer(i);
arg[1] = new String("this is a model");
m.invoke(model,arg); //model.method(arg[0], arg[1]);
}catch(Exception e){
e.printStackTrace();
} }
}
public class MyClass{
public MyClass(String str){
...
}
}而你要调用,构造函数是要传进参数"test"
则,可以
myClass = Class.forName(classname).getConstructor(new Class[]{String.class}).newInstance(new Object[] {"test"});
当然这个时候的myClass是Object的,你可以通过(MyClass)myClass强制转换
MyClass在程序中只是一个字符串,如何做强制转换中的类?
model = (Model)c.newInstance();
如果系统没找到这个类会抛出异常的
(MyClass)myClass
连编译都不会通过,怎么可能系统抛出异常呢。
其实一般来说就是plug-in的解决方案吧,MyClass可以定义成一个接口,具体实现可以动态加载,否则的化是没办法强制转换的
就是说用getMethod,getField等方法
主要是java里没有js中eval方法:)
其实我的目的是动态的加载不同属性方法的类,通过类对象进行数据的传递,在实际操作中,类对象存储的就是数据库中的一条记录,通过把对象存在集合中达到脱机数据集的目的,在取出数据的时候需要通过类名称将返回的类对象强制转换成该类的对象,才能取得数据,以达到通用性的目的,使用接口我还没试过。
希望大家再讨论讨论,然后我将对提出较好的解决方案的给分
/**
* 根据条件将查找到的数据以值对象集合的形式返回
* @param strsql 需要进行查询的sql语句
* @param voType值对象的类型
* @return
* @throws java.lang.Exception
*/
public Collection findDatas(strsql,
Class voType) throws Exception {
//查询数据的方法,返回数据集
RowSet rows = ExecuteQuery(strsql); Collection col = new ArrayList();
for (int i = 0; i < rows.length(); i++) {
rows.get(i).dump();
Object vo = toValueObject(rows.get(i), voType); //返回一个值对象,注意是voType类型的对象
col.add(vo);
}
return col;
} /**
* 将行对象转换成值对象
* @param row
* @param type值对象类型
* @return
* @throws java.lang.Exception 这里的异常一般在DAO中处理,因为DAO调用
* 这个方法进行Row和ValueObject的转换
*/
public static Object toValueObject(Row row, Class type) throws Exception {
Object vo = type.newInstance(); //创建一个值对象
Field[] fields = type.getDeclaredFields(); //得到值对象中所有字段
for (int i = 0; i < fields.length; i++) {
String name = fields[i].getName();
Object value = row.get(name); //得到从数据库中取出的与字段名对应的值
String methodName = "set" + Character.toUpperCase(name.charAt(0)) +
name.substring(1); //得到setXXXX方法名
Class argClass = null;
//用以得到类型
if (value instanceof Class) {
argClass = (Class) value;
value = null;
}
else {
argClass = value.getClass();
}
Method method = type.getMethod(methodName, new Class[] {argClass}); //得到set方法
method.invoke(vo, new Object[] {value}); //调用setXXXX方法
}
return vo;//返回值对象,是Object类型的
}
//下面是对该方法的测试,PolVO是为该查询准备的一个类,具有与查询结果对应的私有属性和get、set方法,现假设他只有两个属性:id,name,与表中的字段一一对应
//这里使用的是实际的单独的一个类,在应用中PolVO的位置应该传入一个需要的与查询相对应的类
public static void main(String[] a) throws Exception {
PolVO vo;
Collection col = dao.findDatas("select id,name from t_pol_main",PolVO.class);
for (Iterator iter = col.iterator(); iter.hasNext(); ) {
Object item = iter.next();
vo = (PolVO) item;//这里是出问题的地方,我不知道在只知道类名的情况下怎么进行强制类型转换
System.out.println(vo.getId);//这里将来是动态的
System.out.println(vo.getName);//这里将来是动态的
}
}还有一个地方,在测试函数中传值的地方,原来的类要求传进去的参数是累的全名,即我提出的类PolVO,需要传入PolVO.class,好像是为了在最后使用该类的时候省去了Class.forname这一步,
最重要的就是强制类型转换的地方
按你的方案,还是需要定义通用接口,在Collection里的对象都实现该接口就可以了
上面除了main函数之外是一个简易的DAO,该DAO还能实现添删改的功能
main函数是用来测试DAO的,我写得不太好,并没有体现出来如何动态调用,实际上使用的时候是把main函数改成一个普通函数,//下面的方法是调用DAO进行查询并打印的一个类方法
Public void PrintDBGrid(String strsql,Class VOClass){
Object vo = type.newInstance(); //创建一个值对象
Collection col = dao.findDatas("select id,name from t_pol_main",VOClass);
for (Iterator iter = col.iterator(); iter.hasNext(); ) {
Object item = iter.next();
//这里因改制通过类名称把vo强制转换,然后调用其方法
//然后就通过取得类方法来取得vo对象中的值并打印,此处略去
}
}//下面调用PrintDBGrid方法
Public void TestPrintDBGrid(){
PrintDBGrid("select * from t_pol_main",PolVO.class);
//这里调用打印方法,以实现方法的重用
}这样看行不行,各位帮我看看我提出强制类型转换的地方
Public void TestPrintDBGrid(){
PrintDBGrid("select id,name from t_pol_main",PolVO.class);
PrintDBGrid("select sellid,goodsname,price from t_sell_detail,SellVO.class);
}
PolVO.class 中有两个私有属性对应表t_pol_main中的两个字段:id,name
SellVO.class 中有三个私有属性对应表中t_sell_detail中的三个字段:sellid,goodsname,price
两个类其实是两个bean,具有对其私有属性操作的get、set方法