2017-06-06 73 views
2

我无法获取字段值。我试图做的是在运行时获取对象。请让我知道我出错的地方。使用反射获取字段值

的Test.class

import java.lang.reflect.Field; 

public class Test { 

public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException, 
     IllegalArgumentException, IllegalAccessException { 

    final Field field = Class.forName("com.logging.EX").getDeclaredField("value"); 
    field.setAccessible(true); 
    field.get(Class.forName("com.logging.EX")); 
} 

}

EX.class

public class EX { 

private String value; 


public EX(){ 
    value="data"; 
} 
/** 
* @return the value 
*/ 
public String getValue() { 
    return value; 
} 

/** 
* @param value 
*   the value to set 
*/ 
public void setValue(String value) { 
    this.value = value; 
} 

}

+2

'value'是一个实例字段。你的'EX'实例在哪里? – Radiodef

+0

我想在运行时获得EX的对象。 – rama

+1

那么,为了得到'value'字段,你需要一个'EX'的实例,因为'value'是一个实例字段。现在你的代码试图做一个相当于'com.logging.EX.class.value'的错误。 – Radiodef

回答

2

事情是这样的......

import java.lang.reflect.Field; 

public class Test { 
    public static void main(String... args) { 
     try { 
      Foobar foobar = new Foobar("Peter"); 
      System.out.println("Name: " + foobar.getName()); 
      Class<?> clazz = Class.forName("com.csa.mdm.Foobar"); 
      System.out.println("Class: " + clazz); 
      Field field = clazz.getDeclaredField("name"); 
      field.setAccessible(true); 
      String value = (String) field.get(foobar); 
      System.out.println("Value: " + value); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 
} 

class Foobar { 
    private final String name; 

    public Foobar(String name) { 
     this.name = name; 
    } 

    public String getName() { 
     return this.name; 
    } 
} 

或者,你可以使用类的newInstance方法在运行时让你的对象的实例。您仍然需要先设置该实例变量,否则它将没有任何值。

E.g.

Class<?> clazz = Class.forName("com.something.Foobar"); 
Object object = clazz.newInstance(); 

或者,如果它在它的构造,字符串两个参数和int例如...

Class<?> clazz = Class.forName("com.something.Foobar"); 
Constructor<?> constructor = clazz.getConstructor(String.class, int.class); 
Object obj = constructor.newInstance("Meaning Of Life", 42); 

或者你可以在运行时询问它的构造函数使用clazz.getConstructors()

NB我故意忽略了在这里创建的对象的铸造到期望的类型,因为那样会打败反射点,因为如果你这样做的话,你已经意识到了这个类,这将会否定第一个反射的需要地点。

+0

嗨MadoDestra,对不起我更新了我的问题。我试图做的是在运行时获取obejct。我不知道对象名是什么。 – rama

+0

您仍然必须知道对象类型才能实例化它。或者如果它是一个模糊的对象,那么你可以调用getClass()来确定它的类。或者你可以使用instanceof,但我不会推荐这种方法。 – ManoDestra

+0

上面详细介绍了如何在运行时获取对象的实例。通过使用构造函数或在类对象本身上调用newInstance(),但您首先需要知道其完全限定的路径名​​作为字符串。 – ManoDestra

0

你需要field.get的EX isntance()。

final Field field = Class.forName("com.logging.EX").getDeclaredField("value"); 
field.setAccessible(true); 
field.get(new EX()); 
0

您可以从类对象创建实例,并且可以在字段get值中使用该实例。

Class modelClass = Class.forName("com.gati.stackoverflow.EX"); 
    final Field field = modelClass.getDeclaredField("value"); 
    field.setAccessible(true); 
    Object modelInstance=modelClass.newInstance(); 
    field.get(modelInstance); 
0

所以,得到了下面的答案。目前它工作正常。不知道这是否是最好的。

您的测试类:

public class Test { 

    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException, 
      IllegalArgumentException, IllegalAccessException, InstantiationException { 

     Field[] fields = Class.forName("com.logging.EX").newInstance().getClass().getDeclaredFields(); 
     for (Field field : fields) { 
      field.setAccessible(true); 
      System.out.println(field.getName() + " : " + field.get(Class.forName("com.logging.EX").newInstance())); 
     } 

    } 
} 

我通过调用com.logging.EX实例提取到阵列中的所有字段,然后遍历所有字段提取的名称和值的字段成立。这里没有硬编码任何字段名称。

由于我访问变量private访问修饰符,但是它始终存在于反射中,所以我的安全警告很少。只是一个免责声明!

希望这会有所帮助!