Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
251 views
in Technique[技术] by (71.8m points)

java - Confused about naming of JavaBean properties, with respect to getters and setters

I am making an application that uses Drools planner.

The @ValueRangeFromSolutionProperty is supposed to refer to a property from another class (NQueens in this case). From the JavaDocs for @ValueRangeFromSolutionProperty:

propertyName

    The property name of which exists a getter on the Solution that returns a Collection. 

But I noticed an inconsistency: the annotator uses the property rowList from NQueens. But rowList (as opposed to RowList) is a private variable (see snippets below). If it were supposed to infer a property by introspection (from it's getter and setter methods), shouldnt it be spelled RowList as in getRowList()?

Question: How does Java infer (introspect) the property name (case and all) from the getter methods?

Or does the @ValueRangeFromSolutionProperty access the private variables directly?


Background details: From Queen.java, a class that represents a queen on a chessboard:

public class Queen extends AbstractPersistable {
....
@ValueRangeFromSolutionProperty(propertyName = "rowList")
public Row getRow() {
    return row;
....

From NQueens.java, the class from which the @ValueRangeFromSolutionProperty gets it's property from:

public class NQueens extends AbstractPersistable implements Solution<SimpleScore> {
...
private List<Column> columnList;
private List<Row> rowList;
....
public List<Row> getRowList() {
    return rowList;
...
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The JavaBeans Specification says that for a property propertyName there should be a getter method getPropertyName() and/or a setter method setPropertyName().

A property is defined by the only presence of the getter and setter methods and can also be a computed value. A instance variable on the object is not required.

The specification defines the capitalization rules for properties and getter/setter methods:

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


The method is in fact implemented as:

/*
Utility method to take a string and convert it to normal Java variable name 
capitalization. This normally means converting the first character from upper case to  
lower case, but in the (unusual) special case when there is more than one character  
and both the first and second characters are upper case, we leave it alone.

Thus "FooBah" becomes "fooBah" and "X" becomes "x", but "URL" stays as "URL".

 Parameters:
     name The string to be decapitalized.
 Returns:
 The decapitalized version of the string.
 */
 public static String  decapitalize(String name) {
 if (name == null || name.length() == 0) {
 return name;
 }
 if (name.length() > 1 && Character.isUpperCase(name.charAt(1)) &&
                     Character.isUpperCase(name.charAt(0))){
        return name;
     }

     char chars[] = name.toCharArray();
     chars[0] = Character.toLowerCase(chars[0]);
     return new String(chars);
 }

So:

  1. if the name is null, return it as such
  2. if the name has first two characters in caps, return it as such
  3. all other strings, decapitalize first character

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...