我刚刚从C#转到JAVA,所以要把以前写的一些C#程序用JAVA改写。其中有个程序是通过接口,利用反射获取实体类的属性。大致代码如下:public bool insert(IEntity entity)
{
   PropertyInfo[] pis = entity.GetType.GetProperties();
   String a = pis[0].GetValue(entity, null);
}以上代码中,IEntity entity是一个接口,里面没有任何方法,纯粹作为一个连接通道,然后用下面的语句就能获取接口另外一端的实体类的属性(实体类里已经写上了属性的set和get方法)。于是我就想用同样的方法改用JAVA实现,代码如下:测试实体类,用于提供属性给测试类反射获取:public class Test implements IEntity{    private String s = "反射成功!";    public String getS(){
        return s;
    }
}
接口:public interface IEntity{}
测试类,通过反射获取测试实体类的属性:public class DataBaseOperations{    public void test(IEntity ie)
    {
        //PropertyInfo[] pis  = ie.      
    }
}就在我注释的那一句我被卡住了。在C#里面,接口ie会有一个GetType()方法,然后紧接着还有一个GetProperties()方法,这样就能把接口另外一端的实体类属性反射到PropertyInfo[]数组,再通过pis[0].GetValue(entity, null)就能获取属性的值。
但是JAVA里接口没有GetType()方法,那我该怎么办?

解决方案 »

  1.   

    java一般传入个Object,通过getClass()方法获得Class对象,再用getFields()/getDeclaredFields()获得Field[],一个是只能获得public的属性,一个是全部都获得. 还可以通过getMethod(String methodName)获得方法等等,自己去看看API吧
      

  2.   

    与c#类似,你也要写这个属性的set和get方法。(其实不写也行。把变量定义成pulbic就行了。但set和get是java bean的标准)
    然后这样:
    //forName的参数就是你的实体类,比如你要用User
    Class cls = Class.forName("xx.xx.xx.User");
    //假设你的变量叫name,那方法名就是getName
    Method mtd = cls.getMethod("getName",new Class[]{String.class});
    Object obj = (Object)cls.newInstance();
    String name = (String)mtd.invoke(obj,null);
      

  3.   

    刚刚看了一下资料,貌似C#里面在通过反射获取私有属性的时候,编译器是通过调用set/get方法来取得属性,所以在C#中使用反射来获取实体类私有属性的时候,实体类里面必须要有set/get方法。而好像JAVA没有这样的机制,所以我想改成反射调用实体类set/get方法,请问,JAVA里怎么通过反射调用方法?
      

  4.   

    ⊙﹏⊙b汗 传入Object,通过getClass就可以动态获取类了,前面不是说了,获取了类,就能getField getMethod...要执行方法invoke一下...
      

  5.   

    直接取字段值就行了package test;import java.lang.reflect.Field;interface IEntity{}class Entity implements IEntity{
        private String s1 = "字符串1";    private String s2 = "字符串2";
    }public class Test {
        
        public static void reflect(IEntity e) throws Exception{
            Class cls = e.getClass();
            Field[] fields = cls.getDeclaredFields();
            for(int i=0; i<fields.length; i++){
                Field f = fields[i];
                f.setAccessible(true);
                System.out.println("属性名:" + f.getName() + " 属性值:" + f.get(e));
            } 
        }
        
        public static void main(String[] args) throws Exception{
            IEntity e = new Entity();
            reflect(e);
        }
    }运行结果:
    属性名:s1 属性值:字符串1
    属性名:s2 属性值:字符串2
      

  6.   

    Class.getFields和Class.getDeclaredFields好像可以返回该类的属性吧,Field类里有获取名字的方法。
      

  7.   

    我给你一个方法吧.但是每个成员属性你都要有get,set方法
    Class<? extends Object> targetType = target.getClass(); PropertyDescriptor[] targetPds = BeanUtils
    .getPropertyDescriptors(targetType); for (int i = 0; i < targetPds.length; i++) { PropertyDescriptor targetPd = targetPds[i];
                            //这里获取get方法
    Method srcReadMethod = sourcePd.getReadMethod();
    Object sourceValue = srcReadMethod.invoke(source,null);
                            //这里获取到的值可以写一个方法进行转换
    }
      

  8.   

    原理和java.io.Serializable接口一样,没看楼上的我还不知道原来序列化是这样做的
      

  9.   


    这里应该直接用getFields吧
    我记得getDeclaredFields能取到父类但是却不能得到private
      

  10.   

    拥有 set/get 方法的称为属性(即便是不存在该成员变量),否则称之为成员变量,不知道楼主想要哪一种?* 属性是需要通过 JavaBeans 规范的类通过 BeanInfo 来获得的
    * 成员变量需要通过类的 Class 对象来获得的
      

  11.   

    f.setAccessible(true); 不安全,如果用这样的方法,那还需要private干吗,我试一下invoke方法看看,调用get方法。
      

  12.   

    Test test = new Test();
    PropertyDescriptor[] pds = Introspector.getBeanInfo(Test.class).getPropertyDescriptors();
    for(PropertyDescriptor pd : pds){
    if("s".equals(pd.getName())){
    Method getter = pd.getReadMethod();
    Object value = getter.invoke(test);
    System.out.println(value);
    }
    }