The code below is a small example that easily reproduces the issue. So I have variable of type String, on which a default value is set. I have 3 methods:
The introspection does not return the getter as the readMethod and the setter as the writeMethod. Instead it returns the isTest() method as the readMethod. The setter is empty.
From the documentation I understand that if the type would be a boolean, the "is" method has higher precedence over get, but the type is String, so it does not make sense to even look for an "is-xxx" method?
public class Test {
public class Arguments {
private String test = Boolean.toString(true);
public boolean isTest() {
return Boolean.parseBoolean(test);
}
public String getTest() {
return test;
}
public void setTest(String test) {
this.test = test;
}
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) throws IntrospectionException {
BeanInfo info = Introspector.getBeanInfo(Arguments.class);
System.out.println("Getter: " + info.getPropertyDescriptors()[1].getReadMethod());
System.out.println("Setter: " + info.getPropertyDescriptors()[1].getWriteMethod());
PropertyDescriptor descr = new PropertyDescriptor("test", Arguments.class);
System.out.println("T");
}
}
Is there anyone who has some insight on this?
Additional information:
The result you are getting is actually the expected result, as per the JavaBeans specification.
Quoting paragraph 8.3.1 for simple properties:
If we discover a matching pair of
get<PropertyName>
andset<PropertyName>
methods that take and return the same type, then we regard these methods as defining a read-write property whose name will be<propertyName>
.
Then, quoting paragraph 8.3.2 for boolean properties:
This
is<PropertyName>
method may be provided instead of aget<PropertyName>
method, or it may be provided in addition to aget<PropertyName>
method.In either case, if the
is<PropertyName>
method is present for a boolean property then we will use theis<PropertyName>
method to read the property value.
From your example, the Introspector is detecting both the isTest
and getTest
method. Since isTest
has priority over getTest
, it uses isTest
to determine the type of the test
property as boolean
. But then, the Introspector expects the setter to have the signature void setTest(boolean test)
and it doesn't find it, so the setter method is null
.
What's important to note is that the Introspector does not read the fields. It uses the signature of the getter / setter methods to determine which fields are present and their corresponding types. isTest
method signature specifies for a property named test
of type boolean
, so, regardless of the actual type of test
, the Introspector will consider that your class has a property boolean test
.
In fact, for all the Introspecter is concerned, the property test
might not even exist! You can convince yourself of that with the following code:
class Test {
public class Arguments {
public boolean isTest() {
return true;
}
}
public static void main(String[] args) throws IntrospectionException {
BeanInfo info = Introspector.getBeanInfo(Arguments.class);
System.out.println("Getter: " + info.getPropertyDescriptors()[1].getReadMethod());
System.out.println("Name of property: " + info.getPropertyDescriptors()[1].getName());
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With