Java類如何實(shí)現(xiàn)一個(gè)類的障眼法(JadClipse的bug)
Java類實(shí)現(xiàn)一個(gè)類的障眼法
眾所周知,Java的類只能去實(shí)現(xiàn)(implements)一個(gè)或多個(gè)接口,而不能去實(shí)現(xiàn)(implements)一個(gè)類。
然而,有的朋友可能會(huì)注意到這樣的現(xiàn)象,在eclipse里,查看JDBC的com.mysql.cj.Driver.class和它的父類com.mysql.cj.NonRegisteringDriver.class源碼,鼠標(biāo)放到NonRegisteringDriver所實(shí)現(xiàn)的接口名Driver上,確確實(shí)實(shí)地看到tooltip提示“com.mysql.cj.Driver”
如下圖所示:

什么鬼?Java類還可以實(shí)現(xiàn)類了嗎?老師不是這么教的啊。。試試能不能鼠標(biāo)點(diǎn)進(jìn)去 。。

竟然真的點(diǎn)進(jìn)來(lái)了。。 定睛一看,這個(gè)Driver繼承了NonRegisteringDriver,而NonRegisteringDriver又實(shí)現(xiàn)了Driver,這是什么操作?其實(shí),這個(gè)是個(gè)障眼法而已,類怎么能實(shí)現(xiàn)另一個(gè)類呢?那到底是誰(shuí)搞的鬼?答案是eclipse的反編譯插件JadClipse。
一般情況下,我們需要在IDE中較為方便地查看第三方j(luò)ar包的源代碼時(shí),一種方法是,可以安裝反編譯插件JadClipse等,但是需要注意的是,這些反編譯插件是有漏洞的,不然所有的class文件都能被無(wú)誤地反編譯出來(lái),那所有就都是開源的了。
那怎么確定反編譯是否有錯(cuò)?可以查看反編譯后的代碼末尾,都會(huì)有反編譯過(guò)程的報(bào)告信息和錯(cuò)誤異常,如下:
/*jadclipse*/// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
package com.mysql.cj.jdbc;
import com.mysql.cj.*;
import xx..;
// Referenced classes of package com.mysql.cj.jdbc:
// ConnectionImpl, JdbcPropertySetImpl, AbandonedConnectionCleanupThread, JdbcConnection
public class NonRegisteringDriver
implements Driver
{
...
}
/*
DECOMPILATION REPORT
Decompiled from: D:\maven-repository\mysql\mysql-connector-java\8.0.13\mysql-connector-java-8.0.13.jar
Total time: 55 ms
Jad reported messages/errors:
Couldn't fully decompile method cleanup
Couldn't resolve all exception handlers in method cleanup
Couldn't fully decompile method connect
Couldn't resolve all exception handlers in method connect
Exit status: 0
Caught exceptions:
*/很明顯看到,反編譯類com.mysql.cj.jdbc.NonRegisteringDriver的時(shí)候出現(xiàn)了一些錯(cuò)誤。
Jad的bug和限制
- 包含有內(nèi)部類,則jad處理構(gòu)造函數(shù)的參數(shù)時(shí)會(huì)出錯(cuò);
- 不支持zip和jar包(注:如果使用Eclipse插件,則很容易得到包中的某個(gè)類的反編譯代碼);
- 當(dāng)有標(biāo)簽塊,嵌套循環(huán)中有break/continue,有g(shù)oto語(yǔ)句的時(shí)候,會(huì)提示信息“Couldn't fully decompile method <name>”;當(dāng)有try-catch-finally語(yǔ)句的時(shí)候會(huì)提示信息“Couldn't resolve all exception handlers in method <name>”;
- 目前,Jad忽略了行號(hào)表屬性和源文件屬性的內(nèi)容;
- Jad不能處理繼承信息,總是把java.lang.Object作為兩個(gè)不同類的通用父類,需要的時(shí)候做強(qiáng)制轉(zhuǎn)換;
- Jad對(duì)inlined functions處理不好。
所以說(shuō),查看反編譯出來(lái)的源碼時(shí),眼見不一定為真。想要查看源碼,最靠譜的還是盡量找到源碼包關(guān)聯(lián)起來(lái)。
最終,下載并關(guān)聯(lián)源碼包,發(fā)現(xiàn)com.mysql.cj.jdbc.NonRegisteringDriver真正實(shí)現(xiàn)的是java.sql.Driver。
我的環(huán)境如下
- eclipse Version: Mars.2 Release (4.5.2)
- JadClipse Version: v1.5.8g
- mysql-connector-java.jar Version: 8.0.13
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
spring導(dǎo)入framework報(bào)紅問(wèn)題
這篇文章主要介紹了spring導(dǎo)入framework報(bào)紅問(wèn)題及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-07-07
Java實(shí)現(xiàn)迅雷地址轉(zhuǎn)成普通地址實(shí)例代碼
本篇文章主要介紹了Java實(shí)現(xiàn)迅雷地址轉(zhuǎn)成普通地址實(shí)例代碼,非常具有實(shí)用價(jià)值,有興趣的可以了解一下。2017-03-03
Kotlin + Retrofit + RxJava簡(jiǎn)單封裝使用詳解
這篇文章主要介紹了Kotlin + Retrofit + RxJava簡(jiǎn)單封裝使用詳解,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-07-07
關(guān)于Java中try finally return語(yǔ)句的執(zhí)行順序淺析
這篇文章主要介紹了關(guān)于Java中try finally return語(yǔ)句的執(zhí)行順序淺析,需要的朋友可以參考下2017-08-08
Java中DecimalFormat用法及符號(hào)含義
DecimalFormat是NumberFormat的一個(gè)具體子類,用于格式化十進(jìn)制數(shù)字。這篇文章介紹了DecimalFormat的用法及符號(hào)含義,需要的朋友可以收藏下,方便下次瀏覽觀看2021-12-12
java正則表達(dá)式獲取指定HTML標(biāo)簽的指定屬性值且替換的方法
下面小編就為大家?guī)?lái)一篇java正則表達(dá)式獲取指定HTML標(biāo)簽的指定屬性值且替換的方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-12-12
oracle數(shù)據(jù)庫(kù)導(dǎo)入TXT文件方法介紹
這篇文章主要介紹了oracle數(shù)據(jù)庫(kù)導(dǎo)入TXT文件方法介紹,文中向大家展示了具體代碼示例,需要的朋友可以參考下。2017-09-09

