识别 IType 的所有 IMethods 的访问器和修改器 (getters/setters)
Identifying accessors and mutators (getters/setters) of all IMethods of an IType
我可以使用方法 getMethods()
访问 IType
的所有方法。有没有一种有效的方法来确定这样的 IMethod
是访问器还是修改器 (getter/setter)?
检查 IMethod
的名称是否与方案 prefix + NameOfAttribute
和 prefix ∈ {"get", "set", "is"}
匹配将帮助我检测明显的方案,但是如果访问器或修改器 (getter/setter) 不是那样命名的,它不会工作。
有没有更好的方法?
编辑:我只想识别直接get/set IType
属性的getter/setter 方法,不做任何其他事情.
EDIT2:使用的技术术语:accessor & mutator
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
}
重要提示:此解决方案符合我的要求,但忽略了一些重要情况(请参阅 ) 。这仍然不检查该方法的功能,但它工作得很好。它检查我提出的方案的方法名称。但它还会检查参数计数以及 return 类型是否为 void
。如果有人想对此进行改进,他还可以检查 getter 的 return/parameter 类型是否与与方法名称匹配的字段类型相匹配。
我的方法是:
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 核心不支持识别 getters 和 setter。
JDT 中只有 public API 提供了 getter/setter 基于字段名称的名称生成。例如。 NamingConvention
Take a look at the suggestGetterName()
方法。
其他内部 class 类似 GetterSetterUtil
也没有提供您想要的方法。
最后我会自己创建一个 属性 访问器检测器。也许作为过滤器我可以应用于 Collection
s.
Checking if the name of an IMethod matches the scheme prefix + NameOfAttribute with prefix ∈ {"get", "set"}
如果是布尔值 属性,还要检查 is
前缀和方法的参数列表。 Getters 通常不带参数,而 setter 通常带一个参数。我说通常,因为 JavaBeans specification 也允许索引属性。例如
void setter(int index, PropertyType value); // indexed setter
PropertyType getter(int index); // indexed getter
void setter(PropertyType values[]); // array setter
PropertyType[] getter(); // array getter
编辑
I added my own solution based on your proposals to my post.
您的解决方案可能符合您的要求。请记住,属性 可能没有直接的 backing-field。 属性 的概念有点抽象。我的意思是,如果你有一个名为 visible
的 属性 和一个 getter isVisible()
,那么 class 可能没有字段 private boolean visible
.
为了清楚起见,您应该查看 JComponent
中的 属性 rootPane
。肯定是属性,因为Introspector
returns而已。
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;
}
}
会打印出来
Found property rootPane
但如果您看一下实现,它不会直接使用 backing-field。
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;
}
我只是想让这个更清楚。
我可以使用方法 getMethods()
访问 IType
的所有方法。有没有一种有效的方法来确定这样的 IMethod
是访问器还是修改器 (getter/setter)?
检查 IMethod
的名称是否与方案 prefix + NameOfAttribute
和 prefix ∈ {"get", "set", "is"}
匹配将帮助我检测明显的方案,但是如果访问器或修改器 (getter/setter) 不是那样命名的,它不会工作。
有没有更好的方法?
编辑:我只想识别直接get/set IType
属性的getter/setter 方法,不做任何其他事情.
EDIT2:使用的技术术语:accessor & mutator
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 的 return/parameter 类型是否与与方法名称匹配的字段类型相匹配。
我的方法是:
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 核心不支持识别 getters 和 setter。
JDT 中只有 public API 提供了 getter/setter 基于字段名称的名称生成。例如。 NamingConvention
Take a look at the suggestGetterName()
方法。
其他内部 class 类似 GetterSetterUtil
也没有提供您想要的方法。
最后我会自己创建一个 属性 访问器检测器。也许作为过滤器我可以应用于 Collection
s.
Checking if the name of an IMethod matches the scheme prefix + NameOfAttribute with prefix ∈ {"get", "set"}
如果是布尔值 属性,还要检查 is
前缀和方法的参数列表。 Getters 通常不带参数,而 setter 通常带一个参数。我说通常,因为 JavaBeans specification 也允许索引属性。例如
void setter(int index, PropertyType value); // indexed setter
PropertyType getter(int index); // indexed getter
void setter(PropertyType values[]); // array setter
PropertyType[] getter(); // array getter
编辑
I added my own solution based on your proposals to my post.
您的解决方案可能符合您的要求。请记住,属性 可能没有直接的 backing-field。 属性 的概念有点抽象。我的意思是,如果你有一个名为 visible
的 属性 和一个 getter isVisible()
,那么 class 可能没有字段 private boolean visible
.
为了清楚起见,您应该查看 JComponent
中的 属性 rootPane
。肯定是属性,因为Introspector
returns而已。
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;
}
}
会打印出来
Found property rootPane
但如果您看一下实现,它不会直接使用 backing-field。
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;
}
我只是想让这个更清楚。