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'.

  • Object ob1 = (String)'ab'; Object ob2 = (String)'ab'; System.debug(ob1==ob2); gives me true. Can you recheck it? – kurunve Jan 10 '18 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 '18 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. – battery.cord Jan 10 '18 at 17:42
5

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);
}
  • Thank you for the clarification, I'm not paying attention apparently. Please see the edit for the actual question. – stefan Jan 10 '18 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. – battery.cord Jan 10 '18 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 '18 at 8:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.