Java find field by name

How to access class fields of a class that I only know it by its string name?

When I wrote my program I didn’t know there would be a class by this name, but at run time I found out a class by the name of «My_Class_X123.java» exists and I want to use its fields such as ABC and XYZ above, how to get those values ? OK, I got the answer, it’s something like this :

Wouldn’t it be nice to have some sample code like this in the java doc, to show user how to do it ! Frank

3 Answers 3

You need to use Reflection. A while back I wrote some JSTL tag utilities that does this sort of thing. One function checks to see if a class is an instance of a passed-in string ( instanceof basically). The other checks to see whether a class has a specified property ( hasProperty ). The following code snippet should help:

//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; > 

Pay particular attention to the Class.forName method in the first method (which loads and initializes a class) and getMethods() method in the second function, which returns all methods defined for a class.

What you probably want is Class.forName which also initializes the class. After that you can use newInstance to get a new instance of that class (if you need one). To access the fields, you need to use the Method objects that you got from getMethod() . Use the invoke method on those objects. If those methods are getter methods, then you now have access to the field you want.

Читайте также:  first-letter

After looking at the code in your question, I realized that you need getters and setters for those attributes. So assuming you have getABC and getXYZ defined, here is a somewhat contrived example:

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; > 

The above approach is more generic. If you only want the fields, then you can use the method James described:

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 >

Источник

get field value by its name in java

i need to read the field value given the field name. say i have class called product, it has fields: size, image, link.. and have methods as getSize(), getImage() and getLink() to read those values. now if i give ‘size’, i want to get size by calling getSize(), given ‘image’, get image by calling getImage(). right now i have a clumsy code call getField(String fieldName) to handler this:

public void String getField(String fieldName, Product p) < String value = ""; swtich(fieldName): case 'size': value = p.getSize(); break; case 'image': value = p.getImage(); break; . 

problem is i have too many fields in this class, the whole code looks ugly. also i try to avoid the reflection page because of the poor readability. is there any other idea to handle this nicely? thanks

Читайте также:  Javascript and dom objects

2 Answers 2

Other than reflection or an explicit switch (as you have), the only real alternative is to not have those fields at all. Instead of getSize() , getImage() , etc., you could just have a general-purpose getAttribute(Attribute a) . Attribute there would probably be an enum . Something like:

enum Attribute < SIZE, IMAGE, . >public class Product < Mapattributes = new EnumMap<>(Attribute.class); public String getAttribute(Attribute attribute) < return attributes.get(attribute); >public void setAttribute(Attribute attribute, String value) < attributes.put(attribute, value); >. > 

EnumMap s are very efficient, so this code will be speedy -- not quite as speedy as real fields, but probably not noticeably slower in your app.

The reason for making Attribute an enum (rather than just having String attribute keys, for instance) is that it gives you the same type safety as explicit getter functions. For instance, p.getAttribute(Attribute.NOT_A_REAL_ATTRIBUTE) will produce a compile-time error, same as p.getNotARealAttribute() would (assuming that enum value and method aren't defined, of course).

Источник

Java: How can I access a class's field by a name stored in a variable?

Although there are valid reasons for doing this, if you are trying to do this you are probably doing something very wrong.

2 Answers 2

You have to use reflection:

  • Use Class.getField() to get a Field reference. If it's not public you'll need to call Class.getDeclaredField() instead
  • Use AccessibleObject.setAccessible to gain access to the field if it's not public
  • Use Field.set() to set the value, or one of the similarly-named methods if it's a primitive

Here's an example which deals with the simple case of a public field. A nicer alternative would be to use properties, if possible.

import java.lang.reflect.Field; class DataObject < // I don't like public fields; this is *solely* // to make it easier to demonstrate public String foo; >public class Test < public static void main(String[] args) // Declaring that a method throws Exception is // likewise usually a bad idea; consider the // various failure cases carefully throws Exception < Field field = DataObject.class.getField("foo"); DataObject o = new DataObject(); field.set(o, "new value"); System.out.println(o.foo); >> 

set() asks me for two parameters, Object and value, why not just value? what's the first parameter ? - Field classField = this.getClass().getField(objField.getName()); classField.set(Object,Value)

Читайте также:  Rest request with javascript

@ufk: The first parameter is the object for which you want to set the field. Note that you got the Field instance by querying the class - there is nothing that links it to a particular instance of that class.

and if it is not a primitive ? In my case it's another class (an array of classes which I want to set/change/allocate)

Источник

How to access an object's fields/methods by their name as a string

I am an beginner java programmer trying to optimize a code written in swift (needless to say I am a novice in swift), which has a class with more than 50 members and setting/getting each of them in some other module gets very tedious. Just wondering if this is possible in either of the programming languages. In java I assume something like this might be possible using class reflection, but not very sure.

Do change java conventions and expect to assume private variables as public. I would suggest declaring public in the example.

Reflections has API to inspect classes at run time, which includes accessing class fields and its methods. Also, you can call these methods or populate the fields depending your requirements.

@AndyTurner the class is a mapper class to one of the database tables with more than 50 attributes, which I am populating using a dictionary in swift.

3 Answers 3

Well, you can use reflection, and do something like:

A a = new A(); Class cls = a.getClass(); //read a method value String methodName = "getAge"; Method method = cls.getDeclaredMethod(methodName); int methodReturnedResult = method.invoke(a, null); //read a field value String fieldName = "age"; Field field = cls.getDeclaredField(fieldName); int fieldValue = field.get(a); 

Though it is important to note that reflection wasn't meant for these cases and it isn't considered a good design to use reflection in these scenarios. What you need to do is to use IDE's abilities to generate setters and getters for you automatically.
Which IDE do you use? Most Java IDE's has the ability to generate getters and setters automatically according to the class fields.

Источник

Оцените статью