1

Recently I was writing a code to check if sobject had changed values in fields. And I came across a question. Right now I have this code to check values diff:

Object newValue = newRecord.get(fieldName);
Object oldValue = oldRecord.get(fieldName);
Boolean isValueChanged = (
    (oldValue == null && newValue != null) ||
    (oldValue != null && newValue == null) ||
    (oldValue != null && !oldValue.equals(newValue))
);

But my colleague wrote another check in another place this way:

Object newValue = newRecord.get(fieldName);
Object oldValue = oldRecord.get(fieldName);
Boolean isValueChanged = newValue != oldValue;

Would it be working for all field values normally this way? I know Strings, numbers (Double, Decimal) and Date/Time are well comparable through == and !=, but still not sure if this solution has no bad use cases.

Thanks

1 Answer 1

1

Apex string comparisons using == and != are case insensitive. That means that your colleague's code is not identical to your own. However, I do agree that you don't need the extra null checks. If you're looking for a case-sensitive comparison of strings, plus support for all other objects, consider:

Object oldValue = oldRecord.get(fieldName);
Object newValue = newRecord.get(fieldName);
Boolean isValueChanged = 
    oldValue?.equals(newValue) == false ||
    newValue?.equals(oldValue) == false;

The Safe Navigation Operator ?. returns null if the left-hand operand is null, rather than throwing a NullPointerException. Thus, for all data types, isValueChanged will be false if both values are null or both values are not null and equal to each other, or true if just one of the values are null or the values are not equal to each other.

However, if you do not need this extra case-sensitive comparison, your colleague's code would be the shortest possible code that uses variables. For example, if you only care about the value changing, and not the value itself, it would be just as simple to write:

if(oldRecord.get(fieldName) == false || newRecord.get(fieldName) == false) {
  // ...
}

Here, we don't need to waste time with the variables, since each value is only used once. Keep in mind that this is still a case-insensitive comparison, so the exact solution depends on your business logic requirements.

4
  • Never knew that == comparison is case-insensitive, thank you! Jun 1, 2023 at 10:05
  • Wait, I tried and got this: Object oldValue = 'a', newValue = 'b'; System.debug(oldValue?.equals(newValue) != newValue?.equals(oldValue)); In that case 'a'.equals('b') returns false, as well as 'b'.equals('a'). Therefore, isValueChanged becomes false because false != false => false. So this method fails for both non-null different values. Jun 1, 2023 at 10:44
  • 1
    @JackVeromeev Yeah, I think I actually meant oldValue?.equals(newValue) == false || newValue?.equals(oldValue) == false. I didn't think it all the way through apparently.
    – sfdcfox
    Jun 1, 2023 at 15:40
  • Thank you for the fixes! I didn't know that ?. notation avoids NPE for method invocation, now my code will get much simpler :) Jun 2, 2023 at 11:00

You must log in to answer this question.

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