2016-04-25 124 views
1

我试图自己实现类似枚举的东西。当我试图迭代我的​​常量对象时,我遇到了使用反射,我偶然发现了java.lang.reflect.Field。所以这是我的场景。我有拿着一双字符串的实体类常量通过接口中的对象常量进行迭代的迭代

public class ConstantEntity { 

    private String constantName; 
    private String constantDesc; 

    ConstantEntity(String name, String desc) { 
     this.constantName = name; 
     this.constantDesc = desc; 
    } 

    public String constantName() { 
     return this.constantName; 
    } 

    public String constantDesc() { 
     return this.constantDesc; 
    } 

} 

而且我有一个界面,我创建使用实体

public interface MyConstantsPool { 

    public static final ConstantEntity CONSTANT_ONE = new ConstantEntity("bla1", "11"); 
    public static final ConstantEntity CONSTANT_TWO = new ConstantEntity("bla2", "12"); 
    public static final ConstantEntity CONSTANT_THREE = new ConstantEntity("bla3", "13"); 


} 

常量和我试图消耗,并通过这些常量迭代使用

import java.lang.reflect.Field; 

public class ConsumeConstants { 

    public static void main(String args[]) { 

     Field[] fields = MyConstantsPool.class.getDeclaredFields(); 
     for (int i = 0; i < fields.length; i++) { 

      Object myConstant = fields[i]; 
      ConstantEntity typeSafeEnum = (ConstantEntity) myConstant ; 
      System.out.println(" The name: " 
        + ((ConstantEntity) typeSafeEnum).constantName()); 
      System.out.println(" The description: " 
        + ((ConstantEntity) typeSafeEnum).constantDesc()); 

     } 
    } 
} 

我经历了文档,但我无法把握Field背后的想法。我对使用反思的理解完全错误吗?我们什么时候使用Field?在接口中迭代所有Object常量的正确方法是什么?

NOTE:我正在使用java 1.4;所以我必须使用基本的Java功能来实现这一点。

回答

0

Field是一个访问,它可以让你设置和获取操作,并做检查,发现一样在运行时的类型或领域的改性剂。

什么是正确的方式来遍历界面中的所有对象常量?

如果你想要遍历所有static ConstantEntity领域,你可以使用这样的事情:

Field[] fields = MyConstantsPool.class.getFields(); 
for (int i = 0; i < fields.length; i++) { 
    Field f = fields[i]; 
    if (ConstantEntity.class.isAssignableFrom(f.getType()) 
      && Modifier.isStatic(f.getModifiers())) { 
     ConstantEntity constant = 
      (ConstantEntity) f.get(null); 
    } 
} 

我是在使用反射的理解完全错误的?

从代码中的错误,试图将myConstant直接投射到ConstantEntity,至少部分。您必须致电get实际检索该字段中保存的值。对象本身只是一个访问器。

您还可以看到"What is reflection and why is it useful?"


此外,Java 1.4中,真的???这已经过了10年以上。

+2

为什么选择倒票? – Pshemo

+1

接口不能有非静态字段,所以'Modifier.isStatic(f.getModifiers()')可能是多余的(除非我误解了你的想法) – Pshemo

+0

@Pshemo是的,你说得对,在这里检查修饰符更多我的代码示例只是打算更具普遍性。 – Radiodef

0

使用Java反射,您可以检查类的字段(成员变量)并在运行时获取/设置它们。

给定一个类的实例,可以使用反射来设置该类中字段的值。这通常只在 特殊情况下才能以通常方式设置值时不是 。 因为此类访问通常违反了该类的设计意图 ,所以应该尽可能使用它。

因此一个类对象可以用来获得Field对象的声明为public,声明为受保护或声明私有字段。

但是,在你的情况下,它可能对你的界面的'设计意图'有用。

+0

@Radiodef“我通过文档去,但是我无法理解Field背后的想法,我对使用反射的理解完全错误吗?我们什么时候使用Field?“ 我将问题解释为:“为什么使用反射?何时有用?目标是什么?” 我错了吗? – granmirupa

0

为什么你不能使用数组而不是反射?

public static final ConstantEntity CONSTANT_ONE = new ConstantEntity("bla1", "11"); 
public static final ConstantEntity CONSTANT_TWO = new ConstantEntity("bla2", "12"); 
public static final ConstantEntity CONSTANT_THREE = new ConstantEntity("bla3", "13"); 

public static final ConstantEntity[] CONSTANTS = { 
    CONSTANT_ONE, 
    CONSTANT_TWO, 
    CONSTANT_THREE 
}; 
1

你只是做简单的错误, 你抢Field,并试图将其投放到您的ConstantEntity类,

你需要从外地获取价值:

Object myConstant = fields[i].get(null);