2016-04-26 72 views
0

我有这样的两个阶级,我想,第二个(DocumentiDiIdentitaList)创建一个基于在第一类中声明的变量的所有值的列表(DocumentiDiIdentita反思级Java

其实我得到这个代码

public class DocumentiDiIdentita { 

    public static final String CARTA_IDENTITA = "CI"; 
    public static final String CARTA_IDENTITA_AFTER_25_06_2003 = "CI_NEW"; 
    public static final String PASSAPORTO_CONSOLATO = "PC"; 
    public static final String PASSAPORTO_QUESTURA = "PQ"; 
    public static final String PASSAPORTO_ESTERO = "PE"; 
    public static final String PATENTE_MORIZZAZIONE = "PZ"; 
    public static final String PATENTE_PREFETTURA = "PT"; 
    public static final String PORTOARMI = "PM"; 
    public static final String PASSAPORTO="PA"; 

} 

public static class DocumentiDiIdentitaList { 
    private static Field[] fields = DocumentiDiIdentita.class.getFields(); 
    public static List documentTypes = Arrays.asList(fields); 

} 

但实际上列表documentTypes cointains变量的名称,而不是它们的值,所以实际上是:

CARTA_IDENTITA 
CARTA_IDENTITA_AFTER_25_06_2003 
PASSAPORTO_CONSOLATO 
etc. 

,但我想:

CI 
CI_NEW 
PC 
etc. 

我怎么能做到这一点? (我必须在Java 1.4上运行)

+2

Field.get(Object)呢? http://docs.oracle.com/javase/8/docs/api/java/lang/reflect/Field.html#get-java.lang.Object- – JEY

+0

@JEY使这个答案;) – 2016-04-26 07:56:37

+0

我不能得到如何使用这个“Field.get(Object)”,对不起 – RudiDudi

回答

2

Java Reflections API允许您在元模型(即类,方法,字段等)上以编程方式操作哪些是您的代码的结构信息,这意味着当您获得对Field实例,它指的是由类声明的字段,而不是类实例(又名对象)字段的实例。

为了使用反射来获取字段的值,您必须使用field.get(instance)来读取给定实例的值。在静态字段和方法的情况下,实例就是类本身。但是你不能传递类,因为.class是一个拥有自己的字段和方法的对象,所以field.get(DocumentiDiIdentita.class)将不起作用。相反,对于访问静态值,您通过null作为参数。

在Java 1.4及以上,你可以做

Field[] fields = DocumentiDiIdentita.class.getFields(); 
List documentTypes = new ArrayList(); 
for(int i = 0; i < fields.length; i++){ 
    Field f = fields[i]; 
    documentTypes.add(f.get(null)); 
} 

由于Java 5,你可以使用泛型和for-each循环:

Field[] fields = DocumentiDiIdentita.class.getFields(); 
List<String> documentTypes = new ArrayList<String>(); 
for(Field f : fields){ 
    documentTypes.add(f.get(null)); 
} 

在Java8你可以使用流

List docTypes = Stream.of(DocumentiDiIdentita.class.getFields()).map(this::uncheckedGet).collect(Collectors.toList()); 

private Object uncheckedGet(Field f) { 
    try { 
     return f.get(null); 
    } catch (IllegalAccessException e) { 
     throw new RuntimeException(e); 
    } 
} 

为了便于阅读,我省略了上述java 1.4和1.5例子的异常处理。您可以使用java 8示例的uncheckedGet方法替换field.get调用,或重新使用异常处理。

+0

不幸的是我不得不使用1.4 – RudiDudi

+0

@RudiDudi - 可悲的是,我也想提出一个类似的代码。你能说出为什么这不适用于JDK 1.4吗?我无法安装JDK 1.4,尽管我拥有它。 – soufrk

+0

“令牌上的语法错误”;“,”列表documentTypes = new ArrayList();和“无法在字段f = fields.get(i);”上的数组类型Field []上调用get(int) – RudiDudi

-1

到达静态字段值有点棘手。你需要传递null获得方法是这样的:

public class DocumentiDiIdentitaList { 

    public static void main(String[] args) { 

     Field[] fields = DocumentiDiIdentita.class.getDeclaredFields(); 

      Arrays.stream(fields).forEach(f -> { 

       try { 

        System.out.println(f.get(null)); 

       } 
       catch (IllegalAccessException e) {} 

      }); 
    } 
} 

希望我帮助:)

- 编辑

对不起java8版本:(你可以检查是否得到法空值工作?

+0

不,是强制性的。8 java兼容级别 “lambda表达式只允许在源级1.8或更高”, 也Arrays.stream是1.8方法 – RudiDudi

+0

我相信op提及的问题,他使用Java 1.4,它不包含lambda。 – user902383