Java 识别一个IType的所有IMethods的访问器和变异器(getter/setter)

Java 识别一个IType的所有IMethods的访问器和变异器(getter/setter),java,eclipse,parsing,abstract-syntax-tree,eclipse-jdt,Java,Eclipse,Parsing,Abstract Syntax Tree,Eclipse Jdt,我可以使用方法getMethods()访问IType的所有方法。有没有一种有效的方法来确定这样的i方法是存取器还是变异器(getter/setter) 检查i方法的名称是否与带有前缀的scheme前缀+NameOfAttribute匹配∈ {“get”、“set”、“is”}将帮助我检测明显的错误,但是如果访问器或变异器(getter/setter)没有这样命名,它将无法工作 有更好的办法吗 EDIT:我只想识别直接获取/设置IType属性的getter/setter方法,而不做任何其他事情 E

我可以使用方法
getMethods()
访问
IType
的所有方法。有没有一种有效的方法来确定这样的
i方法是存取器还是变异器(getter/setter)

检查
i方法的名称是否与带有
前缀的scheme
前缀+NameOfAttribute
匹配∈ {“get”、“set”、“is”}
将帮助我检测明显的错误,但是如果访问器或变异器(getter/setter)没有这样命名,它将无法工作

有更好的办法吗

EDIT:我只想识别直接获取/设置
IType
属性的getter/setter方法,而不做任何其他事情

EDIT2:使用的技术术语:存取器和变异器

EDIT3:阅读所有答案后,这里是我的解决方案:

    private boolean isAccessor(IMethod method) throws JavaModelException {
        if (isAccessMethod("get", method) || isAccessMethod("is", method)) { // if name fits
            return method.getNumberOfParameters() == 0 && !Signature.SIG_VOID.equals(method.getReturnType());
        }
        return false;
    }

    private boolean isMutator(IMethod method) throws JavaModelException {
        if (isAccessMethod("set", method)) { // if name fits
            return method.getNumberOfParameters() == 1 && Signature.SIG_VOID.equals(method.getReturnType());
        }
        return false;
    }

    private boolean isAccessMethod(String prefix, IMethod method) throws JavaModelException {
        IType type = method.getDeclaringType();
        for (IField field : type.getFields()) { // for ever field of IType:
            if (method.getElementName().equalsIgnoreCase(prefix + field.getElementName())) {
                return true; // is access method if name scheme fits for one field
            }
        }
        return false; // is not an access method if no field fits
    }
重要提示:此解决方案符合我的要求,但忽略了一些重要情况(请参见)。这仍然无法检查该方法的功能,但效果相当不错。它检查我提出的方案的方法名。但它还检查参数计数以及返回类型是否为
void
。如果有人想改进这一点,他还可以检查getter的返回/参数类型是否与方法名匹配的字段类型匹配。

我的方法是:

for (IMethod m : iType.getMethods()) {
    if (m.getElementName().substring(0,3).equals("get")) {
        //do something
    } else if (m.getElementName().substring(0,3).equals("set")) {
        //do something else
    }
}

您可以对
IType
使用
getFields()
,然后对每个字段使用
getElementName()

我猜JDT核心中不支持识别getter和setter

JDT中只有一个公共API提供基于字段名的getter/setter名称生成。看看这个方法

其他内部类,如
GetterSetterUtil
也不提供所需的方法

最后,我将自己创建一个属性访问器检测器。也许作为一个过滤器,我可以应用于
Collection
s

检查IMethod的名称是否与scheme prefix+NameOfAttribute with prefix匹配∈ {“获取”、“设置”}

对于布尔属性和方法的参数列表,还要检查
is
前缀。getter通常不接受参数,而setter通常只接受一个参数。我通常说,因为也允许索引属性。例如

 void setter(int index, PropertyType value); // indexed setter
 PropertyType getter(int index); // indexed getter
 void setter(PropertyType values[]); // array setter
 PropertyType[] getter(); // array getter
编辑


我根据你的建议在我的帖子中添加了我自己的解决方案

您的解决方案可能符合您的要求。请记住,属性可能没有直接支持字段。属性的概念有点抽象。我的意思是,如果您有一个名为
visible
的属性和一个getter
isVisible()
类可能没有一个字段
private boolean visible

为了清楚起见,您应该查看
JComponent
中的属性
rootPane
。它肯定是一个属性,因为用户返回它

BeanInfo jcomponentBeanInfo = Introspector.getBeanInfo(JComponent.class);

PropertyDescriptor[] propertyDescriptors = jcomponentBeanInfo.getPropertyDescriptors();
for (int i = 0; i < propertyDescriptors.length; i++) {
  PropertyDescriptor propertyDescriptor = propertyDescriptors[i];
  if("rootPane".equals(propertyDescriptor.getName())){
    System.out.println("Found property rootPane");
    break;
  }
}
但是,如果您查看实现,它不会使用直接支持字段

public JRootPane getRootPane() {
    return SwingUtilities.getRootPane(this);
}
SwingUtilities.getRootPane

public static JRootPane getRootPane(Component c) {
    if (c instanceof RootPaneContainer) {
        return ((RootPaneContainer)c).getRootPane();
    }
    for( ; c != null; c = c.getParent()) {
        if (c instanceof JRootPane) {
            return (JRootPane)c;
        }
    }
    return null;
}

我只想说得更清楚。

这与我在问题中提出的建议非常相似。问题是,如果该方法不是getter,而是名为
getXYZ()
,它将被错误地声明为getter。您可以通过调用
getFields()
来获取已声明字段的数组。然后为每个循环使用一个
for(Field:iType.getFields())
。是的,但这仍然只检查方法的名称。这将是一个不错的解决方案,但也许有一种方法可以用JDTAPI检查方法的功能。感谢关于is前缀的提示,我会忘记的!另外,参数计数也是一个好主意。我根据你的建议在我的帖子中添加了我自己的解决方案。谢谢你的更新。这是一个有趣的例子,这使得准确识别访问器和变异器变得更加困难。我的解决方案可能符合我的要求,但并不是这个问题的通用解决方案。我将在我的帖子中添加这一点作为免责声明。
public static JRootPane getRootPane(Component c) {
    if (c instanceof RootPaneContainer) {
        return ((RootPaneContainer)c).getRootPane();
    }
    for( ; c != null; c = c.getParent()) {
        if (c instanceof JRootPane) {
            return (JRootPane)c;
        }
    }
    return null;
}