子类上的Java静态反射

时间:2009-11-20 22:04:41

标签: java reflection orm static-methods

我在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方法知道它的哪个继承类正在调用它,这样我就可以返回正确的实例(也许可以调用正确的构造函数等)。继承的类可以是任何东西, 没有限制。

我尝试过堆栈跟踪,但它只能从测试跟踪到数据库。

有什么想法吗?

谢谢大家!

3 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:1)

明智之言:尝试实施自己的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的优势之一。

答案 2 :(得分:0)

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

简短:明智地使用Generics