2009-11-20 83 views
0

我正在Java中实现一种ORM。我正在试图做一个只在父类中的静态查找方法。让我得到的一点是:关于子类的Java静态反射

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

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

任何想法?

谢谢大家!

+0

不幸的是,这是一个家庭作业项目。我们不能使用第三方软件(除了Java哈哈)。 不管怎样,谢谢你所有的答案,他们非常有帮助! – mooman 2009-11-21 01:42:50

回答

2

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

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

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

短:明智地使用Generics

1

明智的一句话:尝试实现自己的ORM可能是一个糟糕的主意。诸如hibernate之类的项目已经详细介绍了这一任务,因此如果您自己推出自己,您可能会重新发明轮子,并可能尝试解决已经解决的问题。

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

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

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

因此,一旦你的呼叫到达DB.find,你可以按照堆栈跟踪回调用点,然后再检查字段代码在callsite上查找实际的通话目标。无论如何,从理论上讲,我在实践中并没有看到这一点。另外,要小心这样的黑客字节码,因为这里是龙。

用于识别active record pattern并希望在Java中使用它的荣誉。我确实认为这是一种设计模式,它比在Java中找到的大多数数据库访问模式更有意义,这也是Ruby和PHP的强项之一。

+0

是的,这让我更加欣赏activerecord!谢谢你对字节码的洞察,这是硬核!看到这一点非常有趣。 – mooman 2009-11-21 01:46:19