java的一个变态问题,怀疑是JVM的BUG

kenli 2004-07-01 06:05:09
看下面的代码,如果直接使用PreparedStatement就会出AbstractMethodError,但是如果做了强制类型转换,就执行正确。
Class.forName("COM.ibm.db2.jdbc.app.DB2Driver");
Connection con = DriverManager.getConnection("jdbc:db2:sample", "db2admin", "db2admin");
// DB2PreparedStatement pstat = (DB2PreparedStatement) con.prepareStatement("UPDATE EMPLOYEE SET PHONENO=? WHERE EMPNO=?");
PreparedStatement pstat = con.prepareStatement("UPDATE EMPLOYEE SET PHONENO=? WHERE EMPNO=?");
pstat.getParameterMetaData();
pstat.close();

下面是两段代码的bytecode的不同部分:
(做了类型转换)
24 checkcast #46 <COM/ibm/db2/jdbc/app/>
27 astore_2
28 aload_2
29 invokevirtual #50 <COM/ibm/db2/jdbc/app/DB2PreparedStatement.getParameterMetaData>
====================================
(未作类型转换)
24 astore_2
25 aload_2
26 invokeinterface #50 <java/sql/PreparedStatement.getParameterMetaData> count 1
...全文
476 27 打赏 收藏 转发到动态 举报
写回复
用AI写文章
27 条回复
切换为时间正序
请发表友善的回复…
发表回复
tanghuan 2004-07-19
  • 打赏
  • 举报
回复
不要怀疑JVM,其实,JVM用谁的都一样,他是用来把字节码解释为本地机器码的一个虚拟CPU罢了,与JDK的版本无关,JDK的版本区别其实是提供的API的区别,

这个就象你的CPU是奔几的与你跑WIN95、98、2000、XP等无关一样。

不要认为很多驱动程序提供了类似某一个版本的方法头就认为他一定实现了这个方法,我过去反编译过好多驱动程序看过,好多他不实现这个方法,于是方法体中就只有一条语句,抛出异常,够狠吧。
kenli 2004-07-06
  • 打赏
  • 举报
回复
现在讨论驱动的问题已经不重要了,问题是这种情况出现了,正不正常,是不是JVM的bug,如果不是为什么会出现这样的结果。
因为DB2PreparedStatement是实现了PreparedStatement,而且实现了getParameterMethod这个Method,我看了这个class的bytecode。
达人们,继续讨论。
lightsword 2004-07-05
  • 打赏
  • 举报
回复
不错.
kenli 2004-07-05
  • 打赏
  • 举报
回复
换一个JVM就不行了,因为这个接口是jdk1.4才有的。
那位有最新的驱动啊?
gernett21 2004-07-05
  • 打赏
  • 举报
回复
强烈怀疑是驱动的问题,多换几个试试?
tanghuan 2004-07-05
  • 打赏
  • 举报
回复
这个压根就与JVM没有关系,别冤枉他,

这个是驱动程序没有提供这个版本的JDBC方法,(比如你用低版本比如DB2符合JDBC2以下的驱动,却去引用在JDBC3的接口方法)当然出错。
我以前用过DB2,在6.1版本中缺省安装的是JDBC1,要装JDBC2.0的话,要自己安装呢
allenhe 2004-07-05
  • 打赏
  • 举报
回复
虽然DB2PreparedStatement继承了PrepareStatement
但是由于它返回的是PrepareStatement

所以在调用内部方法的时候,有可能有方法没有重写
所以就会调用PrepareStatement的方法

应该是DB2驱动和jdbc驱动版本不一致的原因
你应该去查文档
lqtflwg718 2004-07-02
  • 打赏
  • 举报
回复
UPUPUPUP
lu8088 2004-07-02
  • 打赏
  • 举报
回复
mark up
haichuang 2004-07-02
  • 打赏
  • 举报
回复
怎么会是这样呢. 真奇怪. JVM是什么版本的? 与DB2的驱动支持的版本是否一致?
p9919cn 2004-07-02
  • 打赏
  • 举报
回复
学习,顶
goldenhua 2004-07-02
  • 打赏
  • 举报
回复
确实应该怀疑是jvm的bug
JohnsonShu 2004-07-02
  • 打赏
  • 举报
回复
多换几个JVM试试?
MyXin 2004-07-02
  • 打赏
  • 举报
回复
我正准备用DB2,待我看一下先!


ecaol 2004-07-02
  • 打赏
  • 举报
回复
UP
kenli 2004-07-02
  • 打赏
  • 举报
回复
我使用了原装的JDBC驱动啊。
另外我看了DB2PreparedStatement是implement了PreparedStatement interface的,这样照理代码两种情况执行的结果一定是一样的。
haichuang 2004-07-02
  • 打赏
  • 举报
回复
我估计应该是你的db2的驱动不支持jdk.1.4.2, 找一下他最新的驱动看看.
bluesky35 2004-07-02
  • 打赏
  • 举报
回复
建议换个低点的JVM试试.
kenli 2004-07-02
  • 打赏
  • 举报
回复
有可能是这样的问题,我去查了db2的文档,他实现的是JDBC 2 而getParameterMetaData是JDBC 3.0的Method,而同时呢DB2的这个东东又实现了其它接口,或者自己独特的Method:getParameterMetaData,这样它就没有实现PreparedStatement的getParameterMetaData而是实现了其它interface或者自己的getParameterMetaData,就出现了如上的怪问题。
那位达人证实我的猜想。
kenli 2004-07-02
  • 打赏
  • 举报
回复
==不一定的,也许在继承了以后对借口内容做了修改。
不明白,我做了classname的打印,
DB2PreparedStatement pstat = (DB2PreparedStatement) con.prepareStatement("UPDATE EMPLOYEE SET PHONENO=? WHERE EMPNO=?");
// PreparedStatement pstat = con.prepareStatement("UPDATE EMPLOYEE SET PHONENO=? WHERE EMPNO=?");
System.out.println(pstat.getClass().getName());
结果是一样的:COM.ibm.db2.jdbc.app.DB2PreparedStatement
加载更多回复(7)

62,615

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧