大家好。最近小弟在学习反射相关的知识。
本来想使用其实现动态实例的创建,但是用来用去发现,反射还不如直接使用数组呢??请给小弟讲解一下。谢谢!!
源码如下:
Class[] paramTypes = 
{Class.forName("java.lang.String"), Class.forName("java.lang.Object")};
Method method = dataClass.getMethod("setValue", paramTypes);for (int j = 1; j <= rsmd.getColumnCount(); j++) {
  Object[] values = {rsmd.getColumnName(j), rst.getString(j)}
  method.invoke(nsDataObj, values);
}
//下面是方法
public MAP setValue(String key  ,object obj){ return this.map.put (key,obj);}
//我可不可以直接使用HaspMap处理map.put(rsmd.getColumnName(j), rst.getString(j))??二者有什么区别??
不解。。

解决方案 »

  1.   

    你想想,如果你是写一个核心的共通函数,Class.forName("java.lang.String"), 里面的"java.lang.String"是通过接口传给你的,事先你并不知道要用什么类型,那你应该怎么办呢?
      

  2.   

    楼主 java的反射是非常有用的东西 一定要好好研究啊  哈哈
      

  3.   

    //这里为有值的Beanpackage fanshe;public class TestClass {
      private int id=2;
      private String name="3";
      public TestClass() {
      }
      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;
      }
    }//这里为要填充的Beanpackage fanshe;public class ClassTest {
      private int id;
      private String name;
      public ClassTest() {
      }
      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;
      }
    }//这里为操作的方法package fanshe;import java.lang.reflect.Field;public class TestFanShe {
      public TestFanShe() {
      }  /**
       * 填充Bean,将第一个Bean的信息放到第二个Bean中,但是我这里做的是两个Bean中有同样的信息
       * @param clas Class 有信息的Bean
       * @param cla Class 没有信息的Bean
       * @throws ClassNotFoundException
       * @throws IllegalAccessException
       * @throws InstantiationException
       * @return Object
       */
      public static Object tianChongBean(Class clas,Class cla) throws
          ClassNotFoundException, IllegalAccessException, InstantiationException {
        //获得第一个Bean中的所有属性
        Field[] fieldClas=clas.getDeclaredFields();
        //获得第二个Bean中的所有属性
        Field[] fieldCla=cla.getDeclaredFields();
        Object objClas=clas.newInstance();
        Object objCla=cla.newInstance();
        for (int i = 0; i < fieldClas.length; i++) {
          for (int j = 0; j < fieldCla.length; j++) {
            //设置属性可以访问,这里不设置为true,那么只能访问public类型
            fieldClas[i].setAccessible(true);
            fieldCla[j].setAccessible(true);
            //这里判断两个属性名是否相等
            if(fieldClas[i].getName().equals(fieldCla[j].getName()))
            {
              //这里将得到TestClass的属性植设置到ClassTest的属性中
              fieldCla[j].set(objCla,fieldClas[i].get(objClas));
              System.out.println(fieldCla[j].get(objCla));
            }
          }
        }
        return objCla;
      }
      public static void main(String[] args) {
        try {
          //这里为调用的方法
          ClassTest classTest=(ClassTest)tianChongBean(TestClass.class, ClassTest.class);
          System.out.println(classTest.getId());
          System.out.println(classTest.getName());
        }
        catch (InstantiationException ex) {
          System.out.println("InstantiationException"+ex.getMessage());
        }
        catch (IllegalAccessException ex) {
          System.out.println("IllegalAccessException"+ex.getMessage());
        }
        catch (ClassNotFoundException ex) {
          System.out.println("ClassNotFoundException"+ex.getMessage());
        }
      }
    }
      

  4.   

    两个MAP不同把,那个是封装过的
      

  5.   

    关于4楼所回复的情况,我基本上是明白的,就是使用反射改变变量的作用域的功能。
    但是,我想说,对于
    Method method = dataClass.getMethod("getValue", String.class);
    String s = method.invoke(null,args)
    而运行时method.invoke()也是返回个String,那为什么我不直接从数据库取出值放到Map里呀?
    反而还得运行一下public String getValue(){return s}方法???
    小弟真是不解呀。
      

  6.   

    如果你已经知道这个方法是public String getValue(){return s}当然没有问题但是如果你是一个容器,只是在配置文件中说有一个getValue的方法呢?你怎么在你的代码中调用,这个时候就必须靠反射机制了
      

  7.   

    还是有些不解。其实小弟是想这样的
    class Entity{
    String s;
    Integer sex;
    public void setSex(Integer sex){
      this.sex = sex;
    }public Integer getSex(){
      return this.sex;
    }
    public void setName(String s){
       this.s = s;
    }public String getName(){
       return this.s;
    }
    }class Factory{  
      getLists(){
        List list = new ArrayList();
        Entity e = new Entity();
        e.setName("Name");    list.add(e);
        return list;
    }
    }那如果我是知道结果集的情况如"setName"我在工厂包进来的时候,可以使用entity.setName()设置entity.getName()得到的,但是如果我不知道"Name"而只是"getX","setX"的时候,我怎么通过,entity.getX(这里面的"X"是我已知的),得到呢???我能想到用反射,可是处理来处理去,我不如用Map(Key,Value)处理呢??能不能像entity.getX那样得到X的值呢??
      

  8.   

    Method method = entity.getClass().getMethod("getX", new Class[]{});
    Object value = method.invoke(entity, new Object[]{});
      

  9.   

    To:ChDw(米)
    我倒。“X”是个指代~~~~并不是真正的方法。
    我是指反射是不是像是调用set,get方法一样进行调用。只不过就是将它再实例化??
      

  10.   

    不太明白你的意思
    String propName = 从某个配置文件中读取到这个属性名
    Method method = entity.getClass().getMethod("get" + propName, new Class[]{});
    Object value = method.invoke(entity, new Object[]{});
    这样就是动态去获取指定的方法啦,我不明白“我是指反射是不是像是调用set,get方法一样进行调用。只不过就是将它再实例化??”是指什么意思
      

  11.   

    最近问了一下相关人员,他说想要使用我所说的动态实例化技术,就相当于Hibernate技术,使用Xml文件做为中间层,里面是相关数据库的字段情况与数据库表进行映射,相互使用。
    他所说的~~我不是很明白~~
    To ChDw(米):
    对于我所说的:“我是指反射是不是像是调用set,get方法一样进行调用。只不过就是将它再实例化??”
    是指反射就是对已经实例化过的方法进行传值调用,反回的方法,如果对于没有在实例化中的方法想要进行实例化的意思。这也正是我一直感到迷惑的~~
    你看一个getName(){return this.name;}但是,如果我只知道有个get(){return this.str}但是我想像调用getName(){return this.name}一样,进行调用。第一次时进行实例化。第二次时我就可以使用getName()方法进行直接的调用。而不进行编码。
    还有一点,我不知道Java支不支持StringToClass的方法。将所有自动生成的字符串转换成类?而这个类是没有编译过的,是在运行时自动生成的。
    还有,谢谢大家对我的支持~
      

  12.   

    1、方法根本不存在实例化的概念,只有类可以实例化为一个对象
       getMethod返回的是一个方法对象,你可以将它看成是类的其中一个成员或者属性
       无论你obj1.getClass().getMethod() obj2.getClass().getMethod() 它们返回的Method对象没有任何的区别,与对象obj1,obj2本身是脱离的
       这个Method m 可以使用在不同的对象上,即
    m.invoke(obj1,new Object[]{});
    m.invoke(obj2,new Object[]{});
      这些都没有问题。  我不知道这样是否你的意思,你要清楚,方法没有实例化的概念,它是类的一个部分而已2、可以Class.forName("java.lang.String");返回一个类
       Class.forName("java.lang.String").newInstance()则使用空参数的构造函数实例化一个对象
      

  13.   

    非常感谢ChDw(米)的讲解但是。
    总结说来,Java中没有对方法可以实现实例化的方法。
    这样,对于我所说的反射的应用也就是可以不通过方法去调用了是吗。而是直接放到Map中不是更快??
    还要经过一系列的反射操作之后再返回来????我就不解这个地方为什么还要用反射做,我直接放到Map中进行操作行不行??那是肯定的“行”,但是为什么有些还要经过反射??如Hibernate似的???不解,不解~~
    顺顶~~谢罗~~^_^
      

  14.   

    我在配置文件里面写属性列表,然后在init方法中设置
    String clzName = readClassNameFromFile();
    ArrayList propNameList = readPropNameFromFile();private void init() {
      Class clz = Class.forName(clzName);
      Object obj = clz.newInstance();
      for(int i = 0; i < propNameList.size(); i++) {
        Method m = clz.getMethod("get" + propNameList.get(i), new Class[]{});
        System.out.println(m.invoke(obj, new Object[]{}));
      }
    }上面就是体现了如何从配置文件再通过反射
    在方法名都不知道的情况下面,你如何知道放什么东西进入Map中??所以这样是肯定不行的!
      

  15.   

    有些明白了?就是将数据库与java间做个第三方的映谢如使用XML进行。
    但是XML的编写则是所有数据库表的字段。。