Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Confusing behavior of java.beans.PropertyDescriptor(String, Class)

Tags:

java

javabeans

I'm trying to create a PropertyDescriptor for a bean class I have. I am calling

new PropertyDescriptor(myProperty, myClass)

and am seeing an exception that the method "isMyProperty" does not exist. Peeking into the code a bit --

/**
 * Constructs a PropertyDescriptor for a property that follows
 * the standard Java convention by having getFoo and setFoo
 * accessor methods.  Thus if the argument name is "fred", it will
 * assume that the writer method is "setFred" and the reader method
 * is "getFred" (or "isFred" for a boolean property).  Note that the
 * property name should start with a lower case character, which will
 * be capitalized in the method names.
 *
 * @param propertyName The programmatic name of the property.
 * @param beanClass The Class object for the target bean.  For
 *      example sun.beans.OurButton.class.
 * @exception IntrospectionException if an exception occurs during
 *              introspection.
 */
public PropertyDescriptor(String propertyName, Class<?> beanClass)
    throws IntrospectionException {
this(propertyName, beanClass, 
     "is" + capitalize(propertyName), 
     "set" + capitalize(propertyName));
}

The documentation says that it will look for "getFred" but it always uses "is" + capitalize(property)! This is in java version "1.6.0_31"

Thoughts?

like image 751
Steven Schlansker Avatar asked Apr 24 '12 17:04

Steven Schlansker


People also ask

What is PropertyDescriptor in Java?

A PropertyDescriptor describes one property that a Java Bean exports via a pair of accessor methods. Constructor Summary. PropertyDescriptor ( String propertyName, Class beanClass) Constructs a PropertyDescriptor for a property that follows the standard Java convention by having getFoo and setFoo accessor methods.

What are the features of JavaBeans?

Here are a few unique characteristics that make JavaBeans different from other classes in Java: JavaBeans provide default constructor without any conditions or arguments. JavaBeans are serializable and are capable of implementing the Serializable interface. JavaBeans usually have several 'getter' and 'setter' methods.

What are JavaBeans explain?

In computing based on the Java Platform, JavaBeans is a technology developed by Sun Microsystems and released in 1996, as part of JDK 1.1. The 'beans' of JavaBeans are classes that encapsulate one or more objects into a single standardized object (the bean).

Can JavaBeans have methods?

A bean's methods are the things it can do. Any public method that is not part of a property definition is a bean method. When you use a bean in the context of a builder tool like NetBeans, you can use a bean's methods as part of your application.


2 Answers

Edit: I think I know what your problem is. If the property doesn't exist in your class, then you will get the "isProperty" method error. See my example:

    {
        PropertyDescriptor desc = new PropertyDescriptor("uuid", Company.class);
        Method m = desc.getReadMethod();
        System.out.println(m.getName()); /* prints getUuid */
    }
    {
        PropertyDescriptor desc = new PropertyDescriptor("uuid11", Company.class);
        Method m = desc.getReadMethod();
        System.out.println(m.getName()); /* throws Method not found: isUuid11 */
    }

Original:

It looks like it just defaults to isProperty as the read method, and if it doesn't exists, it uses getProperty. Take a look at the getReadMethod method, the bit where it goes:

if (readMethod == null) {
    readMethodName = "get" + getBaseName();

So it's trying the isProperty method first, and if it doesn't have that method, looks for getProperty.

Here's the full method:

public synchronized Method getReadMethod() {
Method readMethod = getReadMethod0();
if (readMethod == null) {
    Class cls = getClass0();
    if (cls == null || (readMethodName == null && readMethodRef == null)) {
        // The read method was explicitly set to null.
        return null;
    }
    if (readMethodName == null) {
        Class type = getPropertyType0();
        if (type == boolean.class || type == null) {
            readMethodName = "is" + getBaseName();
        } else {
            readMethodName = "get" + getBaseName();
        }
    }

    // Since there can be multiple write methods but only one getter
    // method, find the getter method first so that you know what the
    // property type is.  For booleans, there can be "is" and "get"
    // methods.  If an "is" method exists, this is the official
    // reader method so look for this one first.
    readMethod = Introspector.findMethod(cls, readMethodName, 0);
    if (readMethod == null) {
        readMethodName = "get" + getBaseName();
        readMethod = Introspector.findMethod(cls, readMethodName, 0);
    }
    try {
        setReadMethod(readMethod);
    } catch (IntrospectionException ex) {
    // fall
    }
}
return readMethod;
}
like image 133
John Farrelly Avatar answered Oct 01 '22 12:10

John Farrelly


If your property is primitive boolean then PropertyDescriptor looking for "isProperty" method. If your property is boxed Boolean then PropertyDescriptor looking for "getProperty" method.

like image 20
Peter Avatar answered Oct 01 '22 13:10

Peter