Fetching getters and setters

Mainly, there are several solutions for obtaining the getters and setters of a class via reflection. Let's assume that we want to fetch the getters and setters of the following Melon class:

public class Melon {

private String type;
private int weight;
private boolean ripe;
...

public String getType() {
return type;
}

public void setType(String type) {
this.type = type;
}

public int getWeight() {
return weight;
}

public void setWeight(int weight) {
this.weight = weight;
}

public boolean isRipe() {
return ripe;
}

public void setRipe(boolean ripe) {
this.ripe = ripe;
}
...
}

Let's start with a solution that gets all the declared methods of a class via reflection (for example, via Class.getDeclaredMethods()). Now, loop Method[] and filter it by constraints that are specific to getters and setters (for example, start with the get/set prefix, return void or a certain type, and so on).

Another solution is getting all the declared fields of a class via reflection (for example, via Class.getDeclaredFields()). Now, loop Field[] and try to obtain the getters and setters via Class.getDeclaredMethod() by passing the name of the field (prefixed with get/set/is and the first letter capitalized) and the type of the field (in the case of setters) to it.

Finally, a more elegant solution will rely on the PropertyDescriptor and Introspector APIs. These APIs are available in the java.beans.* package and are dedicated to working with JavaBeans.

Many of the features that are exposed by these two classes rely on reflection behind the scene.

The PropertyDescriptor class can return the method that's used for reading a JavaBean property via getReadMethod(). Moreover, it can return the method that's used for writing a JavaBean property via getWriteMethod(). Relying on these two methods, we can fetch the getters and setters of the Melon class, as follows:

for (PropertyDescriptor pd:
Introspector.getBeanInfo(Melon.class).getPropertyDescriptors()) {

if (pd.getReadMethod() != null && !"class".equals(pd.getName())) {
System.out.println(pd.getReadMethod());
}

if (pd.getWriteMethod() != null && !"class".equals(pd.getName())) {
System.out.println(pd.getWriteMethod());
}
}

The output is as follows:

public boolean modern.challenge.Melon.isRipe()
public void modern.challenge.Melon.setRipe(boolean)
public java.lang.String modern.challenge.Melon.getType()
public void modern.challenge.Melon.setType(java.lang.String)
public int modern.challenge.Melon.getWeight()
public void modern.challenge.Melon.setWeight(int)

Now, let's assume that we have the following Melon instance:

Melon melon = new Melon("Gac", 1000);

Here, we want to call the getType() getter:

// the returned type is Gac
Object type = new PropertyDescriptor("type",
Melon.class).getReadMethod().invoke(melon);

Now, let's call the setWeight() setter:

// set weight of Gac to 2000
new PropertyDescriptor("weight", Melon.class)
.getWriteMethod().invoke(melon, 2000);

Calling for an inexistent property will cause IntrospectionException:

try {
Object shape = new PropertyDescriptor("shape",
Melon.class).getReadMethod().invoke(melon);
System.out.println("Melon shape: " + shape);
} catch (IntrospectionException e) {
System.out.println("Property not found: " + e);
}
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset