JAVA class對(duì)象是否能作為比較值

直接說結(jié)論:可以,但是不安全(可能性其實(shí)很小)
原因是 classpath下的類通常是由AppClassLoader加載的, 如果有另外一個(gè)繼承自ExtClassLoader的類加載器也加載了這些.class文件.那么class對(duì)象無論是hash也好,對(duì)象引用值也罷.都是不同的. 即: 他們會(huì)在方法區(qū)形成兩個(gè)類對(duì)象.
還有一種可能是: 使用了繼承自AppClassLoader的兩個(gè)不同的類加載器,分別通過 findClass方法而非loadClass方法進(jìn)行類加載.(loadClass會(huì)優(yōu)先委派雙親,如果雙親==null才會(huì)調(diào)用findClass).

    public static void main(String[] args) throws ClassNotFoundException, MalformedURLException {
        File filpath = new File("");
        String path = "file:"+filpath.getAbsoluteFile()+"/xxx.class";
        URL newurl=new URL(path);

        TestClassLoader loader1 = new TestClassLoader(newurl.getPath());
        TestClassLoader2 loader2 = new TestClassLoader2(newurl.getPath());

        Class<?> cls1 = loader1.findClass(CloudUserDAOImpl.class.getCanonicalName());
        Class<?> cls2 = loader2.findClass(CloudUserDAOImpl.class.getCanonicalName());

        Map result = new HashMap();
        // result.put(cls1, cls1);
        // result.put(cls2, cls2);
        // result.put("equalClass", cls1 == cls2);
        result.put("hash1", cls1.hashCode());
        result.put("hash2", cls2.hashCode());

        System.out.println(result);
    }

可以使用自定義的的classloader進(jìn)行測(cè)試

/**
 * @author dqy
 * @version 1.0
 * @date 2020/3/16 下午3:54
 */
public class TestClassLoader extends ClassLoader {
    //指定路徑
    private String path ;


    public TestClassLoader(String classPath){
        path = classPath;
    }

    /**
     * 重寫findClass方法
     * @param name 是我們這個(gè)類的全路徑
     * @return
     * @throws ClassNotFoundException
     */
    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        Class log = null;
        // 獲取該class文件字節(jié)碼數(shù)組
        byte[] classData = getData();

        if (classData != null) {
            // 將class的字節(jié)碼數(shù)組轉(zhuǎn)換成Class類的實(shí)例
            log = defineClass(name, classData, 0, classData.length);
        }
        return log;
    }

    /**
     * 將class文件轉(zhuǎn)化為字節(jié)碼數(shù)組
     * @return
     */
    private byte[] getData() {
        File file = new File(path);
        if (file.exists()){
            FileInputStream in = null;
            ByteArrayOutputStream out = null;
            try {
                in = new FileInputStream(file);
                out = new ByteArrayOutputStream();

                byte[] buffer = new byte[1024];
                int size = 0;
                while ((size = in.read(buffer)) != -1) {
                    out.write(buffer, 0, size);
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return out.toByteArray();
        } else {
            return null;
        }
    }
}

TestClassLoader2可以使用同樣代碼.
結(jié)果:


2020-03-16 18-12-12 的屏幕截圖.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • ClassLoader翻譯過來就是類加載器,普通的java開發(fā)者其實(shí)用到的不多,但對(duì)于某些框架開發(fā)者來說卻非常常見...
    時(shí)待吾閱讀 1,167評(píng)論 0 1
  • 轉(zhuǎn)發(fā):本篇文章已授權(quán)微信公眾號(hào) guolin_blog (郭霖)獨(dú)家發(fā)布 ClassLoader翻譯過來就是類加載...
    尼爾君閱讀 616評(píng)論 0 1
  • 1、classLoader 類加載器,將class文件加載到JVM虛擬機(jī)內(nèi)存中,使得程序可以運(yùn)行。通常情況下,JV...
    helloWorld_1118閱讀 2,355評(píng)論 0 2
  • 本篇文章已授權(quán)微信公眾號(hào) guolin_blog (郭霖)獨(dú)家發(fā)布 ClassLoader翻譯過來就是類加載器,普...
    尼爾君閱讀 715評(píng)論 1 0
  • 首先聲明,我是因?yàn)榭戳薎mportNew網(wǎng)站上的幾篇關(guān)于類加載器的文章之后,才萌生了寫這篇文章的想法。所以在寫這篇...
    陳安妮annie1閱讀 310評(píng)論 0 1

友情鏈接更多精彩內(nèi)容