【问题标题】:Java static reflection on subclasses子类上的 Java 静态反射
【发布时间】:2009-11-20 22:04:40
【问题描述】:

我正在用 Java 实现一种 ORM。我正在尝试做一个仅在父类中的静态查找方法。让我进入正题:

public class DB {
  public static Object find (int id) {
    // i want to return anew instance of the calling subclass
  }
}

public class Item extends DB {
  // nothing here
}

public class Test {
  public static void main () {
    Item i = (Item) Item.find(2);
    ...
  }
}

我不知道如何让 find 方法知道它的哪个继承类正在调用它,以便我可以返回正确的实例(并且可能调用正确的构造函数等)并且继承的类可以是任何东西, 没有限制。

我尝试过stacktrace,但它只是从Test 跟踪到DB。

有什么想法吗?

谢谢大家!

【问题讨论】:

  • 不幸的是,这是一个家庭作业项目。我们不能使用第三方软件(Java 大声笑除外)。无论如何,谢谢你的所有答案,他们非常有帮助!

标签: java reflection orm static-methods


【解决方案1】:

静态方法不是继承的,所以你不能这样做。解决此问题的一种常见方法(不包括使用 的可用 ORM 解决方案之一)是将您的类层次结构分成两部分:

  • “实体”(例如代表您的实际数据的类)
  • 和“DAO”(数据访问对象)- 包含操作数据持久性方法的类。

【讨论】:

    【解决方案2】:

    致智者的一句话:尝试实现自己的 ORM 可能是个坏主意。像hibernate 这样的项目已经非常详细地介绍了这个任务,所以如果你自己动手,你可能会重新发明轮子,并可能尝试解决已经解决的问题。

    关于主题的更多信息,ChssPly76 是正确的,因为您无法完成此操作,因为 Java 中如何处理静态方法。当 VM 加载静态方法调用的字节码时,它将执行查找以找到方法实际位于的位置。它不会在Item 类上找到它,因此它将调用绑定到DB.find

    但是!有可能通过一些字节码争论来实现你想要做的事情。查看示例中静态方法调用的字节码(使用javap -c),我们得到以下信息:

    invokestatic Method Item.find:(I)Ljava/lang/Object
    

    因此,一旦您的调用到达DB.find,您可以按照堆栈跟踪返回调用站点,然后检查调用站点的字节码以检索调用的实际目标。理论上,无论如何,因为我自己在实践中还没有看到这一点。另外,请注意不要像这样破解字节码,因为这里是龙。

    感谢您识别 active record pattern,并希望在 Java 中使用它。我同意这是一种比 Java 中的大多数数据库访问模式更有意义的设计模式,它是 Ruby 和 PHP 的优势之一。

    【讨论】:

    • 是的,它让我更加欣赏activerecord!感谢您对字节码的洞察力,这是核心!看到这一点很有趣。
    【解决方案3】:

    我认为您可能会发现 IBM developerworks 上的“Generic DAO”文章很有用。

    简短:明智地使用Generics

    【讨论】:

      猜你喜欢
      • 2012-03-26
      • 2011-03-22
      • 2015-03-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-20
      • 1970-01-01
      相关资源
      最近更新 更多