Question

I have written a Java class to practice reflection. This is a shorten version that gets right to the problem:

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();
}
}

Output:

Person 1 Person2 -> String.compareTo Reflection Different?

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" indicates where CompareToBuilder.reflectionCompare returns a signum different from String's own compareTo method. I found this only with String (neither Integer, nor int, nor Double, nor double, nor own classes implementing Comparable).

Please help me: Why is this happening?

Était-ce utile?

La solution

The problem with CompareToBuilder and Strings is that the CompareToBuilder reflectively takes all fields into account when comparing two objects. Besides the char array which contains the String, a String additionally stores its size internally explicitly. The reflective comparison takes this into account as well leading to the strange behaviour.

You can actually see all Sting fields in a debugger. Integer, Double, etc. do only have their value as field, hence, there it works.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top