Java stores objects by reference... the reference just happens to be the value when we use primitives.
int is a primitive so
a == c => true
a == b => true
b == c => true
With Strings the situation is slightly different. Strings are effectively char arrays: char[] but are not considered primitive types in Java.. so:
"str1" == "str1" => false since you're comparing two object references now.
For this reason the Object class has the equals() method which allows you to compare reference objects (non-primitives) via something other than the object reference ID. The String (a subclass of Object.class) class overrides the equals method.
In your example (above) you say:
So why is ab==abc false. They are both pointing to same address.
This is incorrect. ab points to String that is "meowdeal" and abc points to a String that is also "meowdeal"... but crucially they are two distinct instances. Therefore:
ab==abc => false - here your checking for reference equality - are they the same object reference (no they are not)
ab.equals(abc) => true - here you're checking for string equality (is ab's "meowdeal" the same as abc's "meowdeal" - yes it is.
This is one of those curveball interview questions you might get from time to time so worth being aware of.