簡體   English   中英

檢測不同ClassLoader加載的類的Class對象等效性

[英]Detecting Class object equivalence for classes loaded by different ClassLoaders

我的任務是為方法findSubClassImplementation編寫單元測試,該方法返回給定Class對象的實例。 方法簽名如下所示:

public <T extends SuperClass> T findSubClassImplementation(Class<T> cls) throws Exception 

該方法在內部檢查所提供的Class對象是否屬於一組已知的類,然后返回該類的實例:

if (Subclass.class.equals(cls)) 
        return (T) new Subclass(args);

如果該類未知,則引發Exception。 該代碼給出

我試圖通過反射加載從SuperClass類繼承的所有類,然后將它們作為參數傳遞給findSubClassImplementation

Set<Class<? extends SuperClass>> subTypesOf = reflections.getSubTypesOf(SuperClass.class);
Class<? extends SuperClass> clazz = subTypesOf.iterator().next();
SuperClass instance = findSubClassImplementation(clazz);

然后,我使用Debugger進入該方法,然后可以看到以下代碼行:

if (Subclass.class.equals(cls)) 

返回錯誤,盡管cls = Subclass.class

我假設發生了什么: Class未實現equals,因此使用了equals的Object ,與“ ==”進行比較。 由於反射使用的類加載器不同於findSubClassImplementation使用的類加載器,因此兩個類對象是不同的。 這個假設正確嗎?

是否可以為我已使用反射加載的類獲取另一個Class對象? 您還有其他想法如何處理此問題嗎?

回答:

事實證明,我不太擅長閱讀:層次結構分為3個級別:超類->中級抽象類->子類。 總是與中間抽象類進行比較:

if (IntermediateAbstractClass.class.equals(cls)) return (T) new Subclass(args);

因此,我的問題不是非常准確或精確-如果您覺得我浪費了時間,對不起。 我將邁克爾·威爾斯的答案標記為正確的答案,因為他的建議促使我發現了我的誤會。 謝謝!

也許您不需要檢查cls是什么類,因為cls已經包含了您需要的所有信息。 簡單嘗試

public <T extends SuperClass> T findSubClassImplementation(Class<T> cls) throws Exception {
    // ... retrieve args
    final Class<?>[] constructorParamTypes = new Class<?>[args.length];
    for (int i = 0; i < args.length; i++) {
        constructorParamTypes[i] = args[i].getClass();
    }
    return cls.getConstructor(constructorParamTypes).newInstance(args);
}

或以Java 8方式:

public <T extends SuperClass> T findSubClassImplementation(Class<T> cls) throws Exception {
    // ... retrieve args
    final Class<?>[] constructorParamTypes = Arrays.stream(args).map(Object::getClass)
            .toArray(size -> new Class<?>[size]);
    return cls.getConstructor(constructorParamTypes).newInstance(args);
}

這些類肯定有一些不同之處...

您說Subclass.equals(otherSubclass)返回false,我們需要確定為什么會這樣。

檢查每個類的名稱是否相等,然后檢查每個類的類加載器是否相等。

根據您提供的用於執行反射的代碼,這里沒有任何暗示這實際上是由“反射”加載的這些類是從不同的類加載器加載的。

此外,嘗試各種類型的類,也許該類的某些獨特之處會導致這種行為。

可以嘗試的一種建議是將Integer添加到子類集中,然后將Number傳遞給該方法...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM