2014-02-18 30 views
0

我寫了一個Java類來練習反射。這是獲取正確的解決問題的縮短版:Java,reflectionCompare和String

import org.apache.commons.lang3.builder.CompareToBuilder; 

public class StringExample { 
public StringExample(){ 
    String[] persons = {"John","Paul","George","Ringo"}; 
    System.out.println("Person 1\tPerson2\t->\tString.compareTo\tReflection\t\tDifferent?\n"); 
    for (int i=0;i<persons.length;i++) 
     for (int j=0;j<persons.length;j++) { 

// Here the problem arises 

      int sct = signum(persons[i].compareTo(persons[j])), 
        rct = signum(CompareToBuilder.reflectionCompare(persons[i], persons[j])); 
      System.out.println(persons[i]+"\t:\t"+persons[j]+"\t->\t"+sct+"\t\t|\t"+rct+"\t\t->\t"+(sct==rct?"ok":"fault")); 
     } 
} 

private int signum(int x) { 
    if (x<0) 
     return -1; 
    if (x>0) 
     return 1; 
    return 0; 
} 

public static void main(String[] a){ 
    new StringExample(); 
} 
} 

輸出:

人1 PERSON2 - > String.compareTo反射不同?

John:John - > 0 | 0 - > ok

John:Paul - > -1 | -1 - > ok

John:George - > 1 | -1 - > fault

John:Ringo - > -1 | -1 - > ok

Paul:John - > 1 | 1 - > ok

Paul:Paul - > 0 | 0 - > ok

Paul:George - > 1 | -1 - > fault

Paul:Ringo - > -1 | -1 - > ok

George:John - > -1 | 1 - > fault

George:Paul - > -1 | 1 - > fault

George:George - > 0 | 0 - > ok

George:Ringo - > -1 | 1 - > fault

Ringo:John - > 1 | 1 - > ok

Ringo:Paul - > 1 | 1 - > ok

Ringo:George - > 1 | -1 - > fault

Ringo:Ringo - > 0 | 0 - > ok

「fault」指示CompareToBuilder.reflectionCompare返回與String自身的compareTo方法不同的符號。我發現只有String(既不是Integer,也不是int,也不是double,也不是double,也沒有自己的類實現Comparable)。

請幫我:爲什麼會發生這種情況?

+1

可以*您*解釋我們爲什麼workaroud是必要的?如果您不使用此解決方法會發生什麼?有什麼異常?如果是這樣,消息和堆棧跟蹤是什麼?如果不是,那有什麼問題? –

+1

你能否澄清你想要做的更多?這個問題對我來說不是很清楚。也許你可以先顯示,你是如何用'Integer'實現的,然後當你用'String'嘗試相同的方法時會發生什麼? –

回答

0

CompareToBuilder和Strings的問題在於比較兩個對象時,CompareToBuilder反射地考慮了所有字段。除了包含字符串的char數組之外,String還在內部顯式地存儲其大小。反思比較也考慮到了這一點,並導致了奇怪的行爲。

您實際上可以在調試器中看到所有Sting字段。整數,雙精度等只有它們作爲字段的值,因此它在那裏起作用。