Java: standard library to convert field name ("firstName") to accessor method name ("getFirstName")
Is there a standard library (such as org.apache.c开发者_StackOverflow中文版ommons.beanutils or java.beans) that will take a string field name and convert it to the standard method name? I'm looking all over and can't find a simple string conversion utility.
The JavaBean introspector is possibly the best choice. It handles "is" getters for boolean types and "getters" which take an argument and setters with none or two arguments and other edge cases. It is nice for getting a list of JavaBean fields for a class.
Here is an example,
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
public class SimpleBean
{
private final String name = "SimpleBean";
private int size;
public String getName()
{
return this.name;
}
public int getSize()
{
return this.size;
}
public void setSize( int size )
{
this.size = size;
}
public static void main( String[] args )
throws IntrospectionException
{
BeanInfo info = Introspector.getBeanInfo( SimpleBean.class );
for ( PropertyDescriptor pd : info.getPropertyDescriptors() )
System.out.println( pd.getName() );
}
}
This prints
class
name
size
class
comes from getClass()
inherited from Object
EDIT: to get the getter or setter and its name.
public static String findGetterName(Class clazz, String name) throws IntrospectionException, NoSuchFieldException, NoSuchMethodException {
Method getter = findGetter(clazz, name);
if (getter == null) throw new NoSuchMethodException(clazz+" has no "+name+" getter");
return getter.getName();
}
public static Method findGetter(Class clazz, String name) throws IntrospectionException, NoSuchFieldException {
BeanInfo info = Introspector.getBeanInfo(clazz);
for ( PropertyDescriptor pd : info.getPropertyDescriptors() )
if (name.equals(pd.getName())) return pd.getReadMethod();
throw new NoSuchFieldException(clazz+" has no field "+name);
}
public static String findSetterName(Class clazz, String name) throws IntrospectionException, NoSuchFieldException, NoSuchMethodException {
Method setter = findSetter(clazz, name);
if (setter == null) throw new NoSuchMethodException(clazz+" has no "+name+" setter");
return setter.getName();
}
public static Method findSetter(Class clazz, String name) throws IntrospectionException, NoSuchFieldException {
BeanInfo info = Introspector.getBeanInfo(clazz);
for ( PropertyDescriptor pd : info.getPropertyDescriptors() )
if (name.equals(pd.getName())) return pd.getWriteMethod();
throw new NoSuchFieldException(clazz+" has no field "+name);
}
A wild one-liner appeared!
String fieldToGetter(String name)
{
return "get" + name.substring(0, 1).toUpperCase() + name.substring(1);
}
You can use a PropertyDescriptor
without an Inspector
(which was suggested by Peter):
final PropertyDescriptor propertyDescriptor =
new PropertyDescriptor("name", MyBean.class);
System.out.println("getter: " + propertyDescriptor.getReadMethod().getName());
System.out.println("setter: " + propertyDescriptor.getWriteMethod().getName());
String fieldToSetter(String name)
{
return "set" + name.substring(0, 1).toUpperCase() + name.substring(1);
}
With copyright by Matt Ball
I modified the methods above, to remove the underscore character and capitalize the next character... for instance, if the field name is "validated_id", then the getter method name will be "getValidatedId"
private String fieldToGetter(String name) {
Matcher matcher = Pattern.compile("_(\\w)").matcher(name);
while (matcher.find()) {
name = name.replaceFirst(matcher.group(0), matcher.group(1).toUpperCase());
}
return "get" + name.substring(0, 1).toUpperCase() + name.substring(1);
}
private String fieldToSetter(String name) {
Matcher matcher = Pattern.compile("_(\\w)").matcher(name);
while (matcher.find()) {
name = name.replaceFirst(matcher.group(0), matcher.group(1).toUpperCase());
}
return "set" + name.substring(0, 1).toUpperCase() + name.substring(1);
}
Guava CaseFormat will do it for you.
For example from lower_underscore -> LowerUnderscore
CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, str)
In the following example two fields named example
and eXample
have the getters
getExample
and geteExample
IF generated by eclipse. BUT this is not compatible with PropertyDescriptor("eXample",...).getReadMethod().getName()
which expects getEXample
as a valid getter name.
public class XX {
private Integer example;
private Integer eXample;
public Integer getExample() {
return example;
}
public Integer geteXample() {
return eXample;
}
public void setExample(Integer example) {
this.example = example;
}
public void seteXample(Integer eXample) {
this.eXample = eXample;
}
public static void main(String[] args) {
try {
System.out.println("Getter: " + new PropertyDescriptor("example", ReflTools.class).getReadMethod().getName());
System.out.println("Getter: " + new PropertyDescriptor("eXample", ReflTools.class).getReadMethod().getName());
} catch (IntrospectionException e) {
e.printStackTrace();
}
}
}
String fieldToGetter(Field field) {
final String name = field.getName();
final boolean isBoolean = (field.getType() == Boolean.class || field.getType() == boolean.class);
return (isBoolean ? "is" : "get") + name.substring(0, 1).toUpperCase() + name.substring(1);
}
String fieldToGetter(boolean isBoolean, String name) {
return (isBoolean ? "is" : "get") + name.substring(0, 1).toUpperCase() + name.substring(1);
}
精彩评论