1

How to compare two types of objects (NOT SOBJECTS) at runtime? Example:

Object ob1 = (String)'ab';
Object ob2 = (String)'ab';

Apparently if I debug ob1==ob2 gives me false. (false statement, see answers)

I have no clue what happens with Integer but I suspect it's the same.
Problem is that I cannot implement compareTo method for said objects.
My particular need is getting a value from an unknown type of field from an unknown type of sobject(established at runtime) then I have to compare one dynamic sobject field value to another dynamic sobject field value.

Edit: Okay, apparently I'm very tired and I didn't ask the proper question which is: I won't know if they will be string or integer or other type I just know they will be the same type.
So how can I compare two objects of the same type without actually knowing the type?
I aplogize for poor wording in my initial 'question'.

3
  • Object ob1 = (String)'ab'; Object ob2 = (String)'ab'; System.debug(ob1==ob2); gives me true. Can you recheck it?
    – kurunve
    Jan 10, 2018 at 17:15
  • Hmm, thanks. It is indeed true BUT this(what I tested before posting) give me false:Object ab = 'ab'; Object bc = 'ab'; system.debug('==>' + ab==bc);
    – stefan
    Jan 10, 2018 at 17:30
  • I was able to answer this question thanks to this comment, next time, include any code you used for testing issues like this in the post- makes it a lot easier for other people to debug. Jan 10, 2018 at 17:42

1 Answer 1

6

The snippet you posted in the comments is failing due to a common mistake. Its an order of operations error, because you're adding an extra string to your comparison, it gets merged into your string value, and screws up your comparison.

Your code is evaluated like this:

'==>' + 'ab' == 'ab'
('==>' + 'ab') == 'ab'
'==>ab' == 'ab' // false

If you leave out the '==>', you get this comparison instead:

'ab' == 'ab' // true

You can get it to output as expected by wrapping your comparison in () to seperate it from your outputted text.

System.debug('==>' + (ab == bc)); // '==>true'

This happens due to the Operator Precedence of + being higher than ==. Another way to phrase this would be that an + operation is evaluated before ==. Since () are evaluated first, we can force the order of operations to happen a certain way by wrapping the right code.


== will get you exact comparison for a large number of use cases. I've written an example which creates a pair type, Tuple, creates a number of test cases, and then tests all of them. All of these equality checks are successful.

== compares by value, expect for a few cases, such as user defined objects. If you expect a object which you wrote yourself to be checked using ==, you should provide an implementation for equals, otherwise those objects will be checked by reference.

A == B is equal to A.equals(B), for all intents and purposes. This means that no matter which types they are, if the equals function has been defined for that type (which it will be for all standard objects and sObjects), you'll get an accurate comparison.

Checking by value means that the exact field values will be compared, or the value of the object itself. Checking by reference means that the memory locations of these objects will be compared. You can force checking by reference by using === instead.

== is well documented in Expresssion Operators

See this example:

public class Tuple {

    public Object A { get; set; }
    public Object B { get; set; }

    public Tuple(Object A, Object B) {
        this.A = A; 
        this.B = B; 
    }

}

List<Tuple> tuples = new List<Tuple>();

tuples.add(new Tuple('a', 'a'));
tuples.add(new Tuple(1, 1));
tuples.add(new Tuple(1.7, 1.7));
tuples.add(new Tuple(true, true));
tuples.add(new Tuple(Date.newInstance(1990, 1, 1), Date.newInstance(1990, 1, 1)));
tuples.add(new Tuple(DateTime.newInstance(1990, 1, 1, 0, 0, 0), DateTime.newInstance(1990, 1, 1, 0, 0, 0)));
tuples.add(new Tuple('006c000000Gzm9f', '006c000000Gzm9f'));
tuples.add(new Tuple(600L, 600L));

tuples.add(new Tuple(new Account(Name='Test'), new Account(Name='Test')));

for (Tuple t:tuples) {
    System.assert(t.A == t.B);
}
3
  • Thank you for the clarification, I'm not paying attention apparently. Please see the edit for the actual question.
    – stefan
    Jan 10, 2018 at 18:10
  • I've updated my answer. == should work in nearly every case. If you have a more specific issue, I'd be glad to look into it, but I think I've covered just about every primitive object in my test code. Check the documentation for exact details on this operator. Jan 10, 2018 at 18:35
  • Yes you have! I'm more than happy with covering the primitives. I expect that field to be 99% of the time a String but there may be some wierd orgs that store a unique value as something else. Thank you! I was afraid I've run into yet another Apex limitation.
    – stefan
    Jan 11, 2018 at 8:47

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .