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)來了。。 定睛一看,這個(gè)Driver繼承了NonRegisteringDriver,而NonRegisteringDriver又實(shí)現(xiàn)了Driver,這是什么操作?其實(shí),這個(gè)是個(gè)障眼法而已,類怎么能實(shí)現(xiàn)另一個(gè)類呢?那到底是誰搞的鬼?答案是eclipse的反編譯插件JadClipse。
一般情況下,我們需要在IDE中較為方便地查看第三方j(luò)ar包的源代碼時(shí),一種方法是,可以安裝反編譯插件JadClipse等,但是需要注意的是,這些反編譯插件是有漏洞的,不然所有的class文件都能被無誤地反編譯出來,那所有就都是開源的了。
那怎么確定反編譯是否有錯(cuò)?可以查看反編譯后的代碼末尾,都會(huì)有反編譯過程的報(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語句的時(shí)候,會(huì)提示信息“Couldn't fully decompile method <name>”;當(dāng)有try-catch-finally語句的時(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處理不好。
所以說,查看反編譯出來的源碼時(shí),眼見不一定為真。想要查看源碼,最靠譜的還是盡量找到源碼包關(guān)聯(lián)起來。
最終,下載并關(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)文章
解決在微服務(wù)環(huán)境下遠(yuǎn)程調(diào)用feign和異步線程存在請(qǐng)求數(shù)據(jù)丟失問題
這篇文章主要介紹了解決在微服務(wù)環(huán)境下遠(yuǎn)程調(diào)用feign和異步線程存在請(qǐng)求數(shù)據(jù)丟失問題,主要包括無異步線程得情況下feign遠(yuǎn)程調(diào)用,異步情況下丟失上下文問題,需要的朋友可以參考下2022-05-05springboot詳解實(shí)現(xiàn)車險(xiǎn)理賠信息管理系統(tǒng)代碼
本系統(tǒng)基于Springboot開發(fā)實(shí)現(xiàn)了一個(gè)為用戶車險(xiǎn)進(jìn)行理賠信息管理的一個(gè)信息化管理系統(tǒng),核心的業(yè)務(wù)主要是用戶申請(qǐng)保險(xiǎn)理賠,管理員審核進(jìn)入理賠程序,事故調(diào)查員對(duì)事故進(jìn)行調(diào)查和現(xiàn)場勘察,這其中共涉及到三類用戶,購買保險(xiǎn)的客戶,事故調(diào)查員和系統(tǒng)管理員2022-06-06SpringBoot?整合?ElasticSearch操作各種高級(jí)查詢搜索
這篇文章主要介紹了SpringBoot?整合?ES?進(jìn)行各種高級(jí)查詢搜索的實(shí)踐記錄,本文主要圍繞?SpringBoot?整合?ElasticSearch?進(jìn)行各種高級(jí)查詢的介紹,需要的朋友可以參考下2022-06-06一文了解Java動(dòng)態(tài)代理的原理及實(shí)現(xiàn)
動(dòng)態(tài)代理指的是,代理類和目標(biāo)類的關(guān)系在程序運(yùn)行的時(shí)候確定的,客戶通過代理類來調(diào)用目標(biāo)對(duì)象的方法,是在程序運(yùn)行時(shí)根據(jù)需要?jiǎng)討B(tài)的創(chuàng)建目標(biāo)類的代理對(duì)象。本文將通過案例詳細(xì)講解一下Java動(dòng)態(tài)代理的原理及實(shí)現(xiàn),需要的可以參考一下2022-07-07RabbitMQ開啟SSL與SpringBoot連接測試的配置方法
本文基于 CentOS 7 + Git + OpenSSL + yum 安裝的 RabbitMQ,需要讀者提交安裝好。其他方式也可變通參考本文。對(duì)RabbitMQ開啟SSL與SpringBoot連接測試相關(guān)知識(shí)感興趣的朋友一起看看吧2022-01-01springsecurity?登錄認(rèn)證流程分析一(ajax)
這篇文章主要介紹了springsecurity?登錄認(rèn)證一(ajax篇),本文通過實(shí)例代碼圖文相結(jié)合給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2024-08-08