Java 我如何将泛型错误地用于commons beanutils?

Java 我如何将泛型错误地用于commons beanutils?,java,generics,apache-commons-beanutils,Java,Generics,Apache Commons Beanutils,我有两个简单的界面: public interface HasId<ID extends Serializable> extends Serializable { T getId(); } 我实例化了一个人,然后将其传递给BeanUtils,我得到了奇怪的行为。例如,有时使用BeanUtils设置id效果很好,而其他时候,我会遇到一个异常,因为它找不到id的“write”方法。在反射过程中,它似乎找到了可序列化的getter,但没有找到可序列化的setter。它并没有始终如一地

我有两个简单的界面:

public interface HasId<ID extends Serializable> extends Serializable {
  T getId();
}
我实例化了一个
,然后将其传递给
BeanUtils
,我得到了奇怪的行为。例如,有时使用BeanUtils设置id效果很好,而其他时候,我会遇到一个异常,因为它找不到id的“write”方法。在反射过程中,它似乎找到了可序列化的getter,但没有找到可序列化的setter。它并没有始终如一地执行此操作,因此我怀疑调用person.getClass().getDeclaredMethod(“id”)并不总是返回相同的方法,但我可能错了

无论如何,这种不一致的行为确实令人恼火,因为,例如,它将在Eclipse中工作,但在Maven中不工作,或者它将工作很长时间,然后在其他地方发生一些不相关的更改时,它将停止工作


显然,我对泛型的理解还不够透彻,无法理解正在发生的事情,但有人能给我解释一下,并解释一下如何解决它吗?

我不太喜欢这种设计——我不喜欢只针对getter和setter的接口

我也不会让那个接口扩展为可序列化的;单一责任是这里最好的建议

但我会这样尝试:

public interface Identifiable<T extends Serializable> {
    T getId();
    void setId(T newId);
}

public class Person implements Identifiable<Long> {
    private Long id;
    public Long getId() { return this.id; }
    public void setId(Long id) { this.id = id; }        
}
可识别的公共接口{
T getId();
void setId(T newId);
}
公共类Person实现可识别{
私人长id;
public Long getId(){返回this.id;}
public void setId(长id){this.id=id;}
}

我使用的Apache Commons BeanUtils版本不支持Java 5,因此它不了解泛型、桥接方法等。我相信这就是问题所在,你使用的是哪种版本的BeanUtils?它是Java 5+aware吗?

你能分享你正在使用的BeanUtil代码吗?另外,当它失败时,您会遇到什么特殊异常?对于相同的
person
对象,甚至对于同一类的不同对象,
person.getClass().getDeclaredMethod(“id”)
不可能总是返回相同的方法。尝试找出导致错误的最小示例,并仔细查看。你可能会发现你的错误。如果不是,在这里发布代码和异常。这并不是说它对同一个人对象是不同的方法,而是在不同(不知怎么的)情况下对同一代码路径是不同的方法。我使用的是1.8.3-我相信这是最新的。根据它的文档,它是JDK 1.3兼容的,这就是你的问题。Spring的BeanRapper提供了类似的功能,如果你使用Spring3.0+它与JDK5+兼容。Doh!这是一个已知问题:。谢谢。BeanRapper看起来主要用于Spring本身。在Spring上下文之外,将其用作一种对象反射实用程序是常见的做法吗?(我正在使用Spring,但我正在处理的不是Springbean。)这(除了名称)是我尝试的迭代之一。我确实希望没有泛型,一切都很好,但当然,我遇到了一种情况,我有一个不长的id,所以我切换到你描述的界面,麻烦开始了。另外,如果您想将一个类标记为具有Id,您将如何做?我很乐意更新我的设计,如果这能解决我的问题,也有意义的话。既然你几乎没有应用程序的上下文,你怎么知道将一个类标记为具有ID是否有任何价值?有些人也可能有一个名为
Ambulary
的接口,它有
walk()
jog()
等方法,我碰巧知道在我的应用程序上下文中这是无用的,但我不会说它们没有价值,因为我不知道。身份证有什么特别之处吗?你说得对;我没有任何背景。我只是提出我的意见,没别的了。但我熟悉我必须向组件添加ID的上下文,通常是在主键和关系数据库的上下文中。我不使用像你这样的接口或任何方案来实现它。我只是继续,加上ID。
public class Person implements HasLongId {
  private Long id;
  private String name;

  public Long getId() {
      return this.id;
  }

  public void setId(Long id) {
      this.id = id;
  }

  public String getName() {
      return this.name;
  }

  public void setName(String name) {
      this.name = name;
  }
}
public interface Identifiable<T extends Serializable> {
    T getId();
    void setId(T newId);
}

public class Person implements Identifiable<Long> {
    private Long id;
    public Long getId() { return this.id; }
    public void setId(Long id) { this.id = id; }        
}