例如,我有一个名为“My_Class_X123.java”的类,如下所示:
public class My_Class_X123 // This file was generated by a java program
{
static String ABC[]={"1","2",...};
int XYZ=0;
}
当我编写程序时,我不知道会有这个名称的类,但是在运行时我发现了一个名为“My_Class_X123.java”的类存在,我想使用它的字段如ABC和XYZ上面,如何获得这些值?
好的,我得到了答案,就是这样:
try
{
Class myClass=Class.forName("My_Class_X123");
Field fields[]=myClass.getDeclaredFields();
String New_ABC[]=String[].class.cast(fields[0].get(String[].class));
}
catch (Exception e) { e.printStackTrace(); }
在java doc中有一些像这样的示例代码,向用户展示如何做到这一点不是很好!
谢
答案 0 :(得分:3)
您需要使用Reflection。前段时间我wrote一些JSTL标签实用程序执行此类操作。一个函数检查一个类是否是传入字符串的实例(基本上是instanceof
)。另一个检查以查看类是否具有指定的属性(hasProperty
)。以下代码段应该有所帮助:
//Checks to see if Object 'o' is an instance of the class in the string "className"
public static boolean instanceOf(Object o, String className) {
boolean returnValue;
try {
returnValue = Class.forName(className).isInstance(o);
}
catch(ClassNotFoundException e) {
returnValue = false;
}
return returnValue;
}
//Checks to see if Object 'o' has a property specified in "propertyName"
public static boolean hasProperty(Object o, String propertyName) {
boolean methodFound = false;
int i = 0;
Class myClass = o.getClass();
String methodName = "get" + propertyName.toUpperCase().charAt(0) + propertyName.substring(1);
Method[] methods = myClass.getMethods();
while(i < methods.length && !methodFound) {
methodFound = methods[i].getName().compareTo(methodName) == 0;
i++;
}
return methodFound;
}
特别注意第一个方法中的Class.forName
方法(加载并初始化一个类)和第二个函数中的getMethods()
方法,该方法返回为类定义的所有方法。
你可能想要的是Class.forName
,它也初始化了这个类。之后,您可以使用newInstance
获取该类的新实例(如果需要)。要访问这些字段,您需要使用从Method
获得的getMethod()
个对象。对这些对象使用invoke
方法。如果这些方法是getter方法,那么您现在可以访问所需的字段。
修改强>
在查看问题中的代码后,我意识到您需要获取这些属性的getter和setter。因此,假设您定义了getABC
和getXYZ
,这是一个有点人为的例子:
public Object reflectionDemo(String className, String getter) throws ClassNotFoundException, NoSuchMethodException {
Object fieldValue;
Class myClass = Class.forName(className);
Object myClassInstance = myClass.newInstance(); //to get an instance of the class
if(myClassInstance instanceof My_Class_X123) {
//null because we are not specifying the kind of arguments that class takes
Method getterMethod = myClass.getMethod(getter, null);
//null because the method takes no arguments
//Also in the scenario that the method is static one, it is not necessary to pass in an instance, so in that case, the first parameter can be null.
fieldValue = getterMethod.invoke(myClassInstance, null);
}
return fieldValue;
}
上述方法更通用。如果您只想要字段,那么您可以使用James描述的方法:
myClass = null;
try {
myClass = Class.forName(className);
Field[] fields = myClass.getDeclaredFields();
for(Field field : fields) {
//do whatever with the field. Look at the API reference at http://java.sun.com/javase/6/docs/api/java/lang/reflect/Field.html
}
}
catch(Exception e) {
//handle exception
}
答案 1 :(得分:0)
使用java.lang.reflect。首先使用ClassLoader获取类的Class,然后可以调用newInstance来获取对象,然后可以使用反射接口来获取字段。
现场综合教程here。
答案 2 :(得分:0)
如果您只需要类字段,甚至不需要创建实例,只要您使用反射来获取类,您可以使用getDeclaredFields()
方法获取字段的名称及其价值观,例如
Class myClass = null;
try {
myClass = Class.forName("package.ClassName");
Field[] fields = myClass.getDeclaredFields();
for (Field field : fields) {
System.out.println("Field type is: " + field.getType());
System.out.println("Field name is: " + field.getName());
}
} catch (Exception e) {
}