1

Is it possible to get the name of the attributes of an apex class? I have a class below, is it possible to get the name of its fields at runtime?

public class MyObjectApex { 

    public String name {get;set;}
    public String Id {get;set;}
    public String attr1 {get;set;}
    public String attr2 {get;set;}

}

In Java it would look like:

MyObjectApex my = new MyObjectApex(); 
for(Field f : someObject.getClass().getDeclaredFields()) {
    field.setAccessible(true); // You might want to set modifier to public first.
    Object value = field.get(someObject); 
    if (value != null) {
        System.out.println(field.getName());
    }
}

1 Answer 1

1

I think this question is a duplicate, but I can't find any previous such questions at the moment, so here we go.

Apex has very limited reflection capabilities. What you want isn't possible generically.

However, for any type which has a 0-argument constructor, you can monkey around with serialization:

public class MyClass
{
    public String attr1 { get; set; }
    public String attr2 { get; set; }
}

Set<String> keys = ((Map<String, Object>)JSON.deserializeUntyped(
    JSON.serialize(new MyClass())
)).keySet();
system.debug(keys);

You can even write a method that will give you the attribute names for such types:

public static Set<String> getAttributeNames(Type toReflect)
{
    return ((Map<String, Object>)JSON.deserializeUntyped(
        JSON.serialize(toReflect.newInstance())
    )).keySet();
}
system.debug(getAttributeNames(MyClass.class));

If you don't want to run the constructor, don't have a 0-argument constructor, or want to avoid instantiation for some other reason, you're pretty much out of luck. You could hack something together with the Tooling API, I suppose. Even if you get these keys, however, you can't do much with them. That is, unless you want to convert your object to a Map in the same fashion.

One other route besides the Tooling API that might be viable is to roll your own describes. It's probably going to hurt performance, and it's a lot more verbose. But it's hard to say if it would be worth it without knowing what you're trying to accomplish.

public interface Describable
{
    Set<String> getAttributeNames();
    // OR
    Map<String, Type> getAttributeTypes();
}
public class MyClass implements Describable
{
    public String attr1 { get; set; }
    public String attr2 { get; set; }

    public Map<String, Type> getAttributeTypes()
    {
        return new Map<String, Type>
        {
            'attr1' => String.class,
            'attr2' => String.class
        };
    }
}
1

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .