Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does PropertyDescriptor return a property name with uppercase as first character?

Tags:

java

javabeans

I'm obtaining an information about a class via

Introspector.getBeanInfo(this.getClass()).getPropertyDescriptors()

then getting the property's name by invoking propery[i].getName().

Everything is fine if a property has no one-letter-part. For example, if a property has a name personAddress (meanwhile its getter/setter -> getPersonAddress(), setPersonAddress(String personAddress)), is's OK, getName() returns personAddress.

But if the property has a name rPersonId (getRPersonId(), setRPersonId(Long rPersonId)) then getName() returns "RPersonId", i.e. first letter has been capitalized! Why?

According to this: https://docs.oracle.com/javase/7/docs/api/java/beans/FeatureDescriptor.html:

public String getName()-> Gets the programmatic name of this feature.

So why does it return a name somehow related to its getter's or setter's name instead of the real name of the property?

like image 693
Yuriy Tsarkov Avatar asked Nov 26 '16 19:11

Yuriy Tsarkov


1 Answers

This is actually the documented behaviour.

First of all, property names are entirely located by discovering their getter and setter, and not by looking at the fields of the class. This is specified in paragraph 8.3 of the Java Beans specification:

If we discover a matching pair of get<PropertyName> and set<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>.

So when you have the introspection of a class that contains Long getRPersonId() and setRPersonId(Long), a property can be extracted from it. The name of the property generally follows from lower-casing the first letter, and keeping the rest unchanged. But this is not always the case, the exact rule is in paragraph 8.8:

Thus when we extract a property or event name from the middle of an existing Java name, we normally convert the first character to lower case. However to support the occasional use of all upper-case names, we check if the first two characters of the name are both upper case and if so leave it alone. So for example:

  • FooBah becomes fooBah
  • Z becomes z
  • URL becomes URL

We provide a method Introspector.decapitalize which implements this conversion rule.

In the example above, the getter and setter would provide the String RPersonId to turn into a property name. Since the first two characters are upper-case, the first character will not be lower-cased. As such, the property name that will be derived is RPersonId, and this explains your output.

You can also call the method decapitalize to see which property name would be located from a pair of getter / setter:

System.out.println(Introspector.decapitalize("RPersonId"));     // prints RPersonId
System.out.println(Introspector.decapitalize("PersonAddress")); // prints personAddress
like image 50
Tunaki Avatar answered Nov 01 '22 20:11

Tunaki