gpt4 book ai didi

JavaBeans 和内省(introspection) - 搞砸了 boolean 值和索引属性?

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:50:57 24 4
gpt4 key购买 nike

我的一位前同事半小时前开始讨论 JavaBeans,以及为什么它们在 JSF 中不能按照他想要的方式工作。特殊情况是关于 boolean 属性。

1。对于名为 isUrl 的 boolean 属性,Eclipse 生成此

private boolean isUrl;
public boolean isUrl() {..}
public boolean setUrl(boolean url) {..}

但这在 JSF 中不起作用。他通过添加 public boolean getIsUrl() 使其工作。实现可能有问题,所以让我们通过使用内省(introspection) API 来确定谁是对的。

BeanInfo info = Introspector.getBeanInfo(ClassTest.class);
for (PropertyDescriptor pd : info.getPropertyDescriptors()) {
System.out.println(pd.getName() + ": " + pd.getReadMethod() +
" : " + pd.getWriteMethod());
}

对于上面的代码,这会打印两种方法 - 即 Eclipse 是正确的,JSF 是错误的。但这对我来说听起来很可疑,因为the specification没有提到任何关于双"is"的事情。

但是在查看规范时,我看到了一些我从未使用过的东西——所谓的索引属性。您可以使用 private String[] bar,然后使用 public String getBar(int idx)。所以:

2。我用 Introspector 尝试过,但没有找到 bar 的读取方法。上述代码的结果是:bar: null : null。所以我开始思考 - 现在内省(introspection)者不遵循规范。也许它在之前的案例中没有遵循它,最终,JSF 是正确的。事实上,索引属性可以使给定属性有两种读取方法。这对于内省(introspection) API 的 PropertyDescriptor 类是不可能的。

这将我们引向何方 - 我们有一个不符合规范的可能已损坏的 API。这导致规范的其他实现(JSF 显然使用自定义实现)。这导致了进一步的误解和困惑。

关于困扰我的事情的旁注 - 在 JavaBeans 规范中,他们将方法的命名约定称为“设计模式”。这对我来说听起来不对。

那么,现在进入问题:

  1. JavaBeans 规范是否清晰
  2. 内省(introspection) API 是否正确
  3. 是否需要新的 JavaBeans 规范,至少要阐明 boolean 值的行为(这在一定程度上是主观的)

更新。看起来 JSF 用法是 bean.isUrl 而不是 bean.url。不使用 isUrl() 访问器是完全合理的。

附言JDK 1.6.0_20、JSF 1.2、MyFaces

最佳答案

Java Bean 属性由方法而不是字段定义。出于这个原因 PropertyDescriptor类有getReadMethod()getWriteMethod()方法,但没有 getField() 方法。

就我个人而言,我认为您的同事使用了一种不好的做法。

a) is 是一个动词。字段不应以动词命名。
b) 虽然这不是必需的,但好的做法是像属性一样命名字段,这样您就可以编写如下代码:

PropertyDescriptor pd; // let's assume this is set
Method referenceMethod = pd.getReadMethod() == null
// at least one of these is not null
? pd.getWriteMethod() : pd.getReadMethod();
Field underLyingField = referenceMethod
.getDeclaringClass()
.getDeclaredField(pd.getName());

虽然此代码未标准化,但它遵循约定并且可以派上用场。如果您不遵循这样的约定,您将无法将字段与属性相关联(我知道这是故意的)。

例如我使用上面的代码来检查该字段是否有注释


关于索引属性:

您可以在数组或列表(或映射)属性上使用索引语法,但前提是它们被定义为标准 bean 属性。

所以如果你有这样的属性(property):

private String[] bar;
public String[] getBar(){
return bar;
}
public void setBar(String[] bar){
this.bar = bar;
}

或者像这样:

private List<String> bar;
public List<String> getBar(){
return bar;
}
public void setBar(List<String> bar){
this.bar = bar;
}

您可以使用表达式 ${bar[0]} 访问第一个成员

还有像这样的 map 属性:

private Map<String, String> bar;
public Map<String, String> getBar(){
return bar;
}
public void setBar(Map<String, String> bar){
this.bar = bar;
}

您可以像这样访问映射到 "baz" 的值 ${bar['baz']}

此功能建立在标准 beans 功能之上,因此它需要常规的 getter/setter。

关于JavaBeans 和内省(introspection) - 搞砸了 boolean 值和索引属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4708670/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com