question abou equals method for objects from self made class - java

So , i took this screenshot from a mooc fi course , this is about defining a equals method to check the equality of the objects of your class.
my question is, in the below screenshot , if first check if (object calling the method == object passed into method as parameter) . if true it will return true , then check if the object passed as parameter is an instance of the class , if not the method will return false but it keep going executin the next line where it uses type cast to convert the object to the class type ? how? im a newbie so i dont understand how it doesnt return false and keep executing method in question's next line.
if (!(object instanceof class)) evaluates as true, shouldnt the method return false ?

Related

Using wild card as a return type in Java

Mockito.doReturn(true).when(a)
.isTest(Const.A,
Const.B);
In the above code cacheGet method returns a boolean value.(true/false)
I want to use a wildcard for that instead true or false.
Mockito.doReturn(?).when(a)
.isTest(Const.A,
Const.B);
I want to use the wildcard in place where '?' is.
How to do it in Java?
Your code
Mockito.doReturn(true).when(cacheAdaptorCore)
.cacheGet(OMSConst.DEFAULT_TENANCY_CODE,
OMSConst.APP_PARAM_DECIMAL_FORMATTER,
CACHE_NAMES.SYS_PARAMS_CACHE_CORE);
tells Mockito, "Hey Mockito, if, during the following test, somehow the method cacheAdapterCore.cacheGet() is called with the parameters OMSConst..., do not really call the method, but instead make the code believe that the method returns true."
Now try the same sentence with "... make the code believe that the method returns ???"
See, it makes no sense.
If you want to do different tests and for some you want the method to return true, and for others you want it to return false, then you have to write separate test methods and within them, tell Mockito to return true resp. false.
try this
String wildcard="";
if(true){
wildcard = //wildcard for true
}
else {
wildcard = //wildcard for false
}

Do if statements that call methods on an object modify the object?

I'm trying to perform actions on my object, but only do so if certain things are true. I have several methods which is consider "action" methods, they do some action that attempts to modify the object and returns true/false if that action can be done.
Example 1
Thing thing = new Thing();
if (thing.changeSomething()){
if (thing.shouldDoSomething()){
//do more things
}
}
I know about compound boolean expressions like to check if a number in a valid range of values
if(number>0 && number<=10)
//number is valid
But haven't really done much when the sub-expressions are method calls
Example 2
if ( thing.changeSomething() && (thing.shouldDoSomething() ){
//do more things
}
Is Example 2 the same as Example 1?
Will Example 2 call the shouldDoSomething() method? Because I don't want this to happen because sometimes shouldDoSomething() actually has other implications & changes other aspects of the object.
Calling
if (thing.changeSomething()){
if (thing.shouldDoSomething()){
is esentially equivalent to
if (thing.changeSomething() && thing.shouldDoSomething()){
I guess they are translated to the exact same IL.
However as mentioned in the comments the second method is only executed if the first one evaluates to true. If the first operand of an &&-operator is already false there´s no need to execute the second also, so your shouldDoSomething-method isn´t executed if changeSomething allready returned false.
Btw. this applies to both Java and C#.
In Java, the logical AND operator && is a short circuit operator, meaning the right side is not evaluated if the result of the expression can be determined solely from the left operand. Specifically, if the left side evaluates to false, the whole expression is false and the right side does not need to be evaluated to determine that.
In the case of your function calls:
if ( thing.changeSomething() && (thing.shouldDoSomething() ){
//do more things
}
If thing.changeSomething() returns false then thing.shouldDoSomething() will not be called since the expression evaluates to false regardless of what this function may return. So yes, the above is equivalent to:
if ( thing.changeSomething() ) {
if (thing.shouldDoSomething() ){
//do more things
}
}
The simple answer and what it comes down to is, it depends on if the thing.changeSomething() method returns a boolean. It is going to create problems if it does not. It is very possible to define this method to do something and return true after it does what it was supposed to do. In which case the second example would work.
If it does not return boolean you should see an error or it might not work to your liking.
It should call the method when to do it that way in example 2. What I would recommend because you don't want that is to create getter() and checker() methods that you use to get info on the object without having to change it. This can also be done with data fields, depends on class structure.
Hope this is more digestible and helps!

Method Overloading ambiguity [duplicate]

The sample code is :
public class OverloadingTest {
public static void test(Object obj){
System.out.println("Object called");
}
public static void test(String obj){
System.out.println("String called");
}
public static void main(String[] args){
test(null);
System.out.println("10%2==0 is "+(10%2==0));
test((10%2==0)?null:new Object());
test((10%2==0)?null:null);
}
And the output is :
String called
10%2==0 is true
Object called
String called
The first call to test(null) invokes the method with String argument , which is understandable according to The Java Language Specification .
1) Can anyone explain me on what basis test() is invoked in preceding calls ?
2) Again when we put , say a if condition :
if(10%2==0){
test(null);
}
else
{
test(new Object());
}
It always invokes the method with String argument .
Will the compiler compute the expression (10%2) while compiling ? I want to know whether expressions are computed at compile time or run time . Thanks.
Java uses early binding. The most specific method is chosen at compile time. The most specific method is chosen by number of parameters and type of parameters. Number of parameters is not relevant in this case. This leaves us with the type of parameters.
What type do the parameters have? Both parameters are expressions, using the ternary conditional operator. The question reduces to: What type does the conditional ternary operator return? The type is computed at compile time.
Given are the two expressions:
(10%2==0)? null : new Object(); // A
(10%2==0)? null : null; // B
The rules of type evaluation are listed here. In B it is easy, both terms are exactly the same: null will be returned (whatever type that may be) (JLS: "If the second and third operands have the same type (which may be the null type), then that is the type of the conditional expression."). In A the second term is from a specific class. As this is more specific and null can be substituted for an object of class Object the type of the whole expression is Object (JLS: "If one of the second and third operands is of the null type and the type of the other is a reference type, then the type of the conditional expression is that reference type.").
After the type evaluation of the expressions the method selection is as expected.
The example with if you give is different: You call the methods with objects of two different types. The ternary conditional operator always is evaluated to one type at compile time that fits both terms.
JLS 15.25:
The type of a conditional expression is determined as follows:
[...]
If one of the second and third operands is of the null type and the type of the other
is a reference type, then the type of the conditional expression is that reference
type.
[...]
So the type of
10 % 2 == 0 ? null : new Object();
is Object.
test((10%2==0)?null:new Object());
Is the same as:
Object o;
if(10%2==0)
o=null;
else
o=new Object();
test(o);
Since type of o is Object (just like the type of (10%2==0)?null:new Object()) test(Object) will be always called. The value of o doesn't matter.
Your answer is : Runtime because in runtime specify parameter is instance of String or not so in compile-time can't find this.
This is the really nice question.
Let me try to clarify your code that you have written above.
In your first method call
test(null);
In this the null will be converted into string type so calling the test(String obj), as per JLS you are convinced with the call.
In the second method call
test((10%2==0)?null:new Object());
Which is going to return the boolean "true" value. So first boolean "true" value is going to auto cast into Boolean Wrapper class object. Boolean wrapper Object is finding the best match with your new Object() option in the ternary operator. And the method calls with Object as a parameter so it calls the following method
public static void test(Object obj)
For the experiment sake you can try the following combinations then you will get better clarity.
test((10 % 2 == 0) ? new Object() : "stringObj" );
test((10 % 2 == 0) ? new Object() : null );
test((10 % 2 == 0) ? "stringObj" : null );
Finally in the last when you are calling with the following code.
test((10%2==0)?null:null);
This time again it returns as boolean "true" value, and it will again follow the same casts as explained above. But this time there is no new Object() parameter is there in your ternary operator. So it will be auto type cast into null Object. Again it follows same method call as the your first method call.
In the last when you asked for code if you put in if .. else statement. Then also the compiler doing the fair decision with the code.
if(10%2==0) {
test(null);
}
Here all the time your if condition is true and calling this code test(null). Therefore all the time it call the firsttest(String obj) method with String as parameter as explained above.
I think your problem is that you are making the wrong assumption, your expressions:
test((10%2==0)?null:new Object());
and
test((10%2==0)?null:null;
Will always call test(null), and that's why they will go through test (Object).
as #Banthar mentionend the ?: operator assigns a value to a variable first then evaluates the condition.
On the other hand, the if condition you mentioned always returns true, so the compiler will replace the whole if-else block with only the body of the if.
1) the test() method is determined by the type of the parameter at the compilation time :
test((Object) null);
test((Object)"String");
output :
Object called
Object called
2) The compiler is even smarter, the compiled code is equivalent to just :
test(null);
you can check the bytecode with javap -c:
0: aconst_null
1: invokestatic #6 // Method test:(Ljava/lang/String;)V
4: return
This is what Java Language Specifications say about the problem.
If more than one method declaration is both accessible and applicable
to a method invocation, it is necessary to choose one to provide the
descriptor for the run-time method dispatch. The Java programming
language uses the rule that the most specific method is chosen.
This is test(String) method in your case.
And because of that if you add...
public static void test(Integer obj){
System.out.println("Ingeter called");
}
it will show compilation error -The method test(String) is ambiguous for the type OverloadingTest.
Just like JLS says:
It is possible that no method is the most specific, because there are
two or more maximally specific methods. In this case:
If all the maximally specific methods have the same signature, then:
If one of the maximally specific methods is not declared abstract, it
is the most specific method. Otherwise, all the maximally specific
methods are necessarily declared abstract. The most specific method is
chosen arbitrarily among the maximally specific methods. However, the
most specific method is considered to throw a checked exception if and
only if that exception is declared in the throws clauses of each of
the maximally specific methods. Otherwise, we say that the method
invocation is ambiguous, and a compile-time error occurs.

What does the word "equals" mean in Java API?

I'm not sure anyone will know the answer to this question, unless you are responsible for writing the Jave API, but when the Java API says "equals", does it always mean that a.equals(b) evaluates to true, or sometime does it mean a == b is true? I have recently extended a class and wondered if I needed to override a method depending on where or not it used == or .equals. Specifically, I extended javafx.beans.binding.ObjectExpression and was curious about the .isEqualTo(Object other) method. I checked the source (here) and found that this method uses .equals for comparison. I'm curious if I can be confident that when I read things like
"Creates a new BooleanExpression that holds true if this ObjectExpression is equal to a constant value."
that the method is not using the == operator. Although, as I think of it, the API can't possibly mean .equals either, since (for example)
String constant = "constant";
ObjectExpress<String> stringExpression = new MyStringExpression("constant");
constant.equals(stringExpression)
will always evaluates to false. So maybe my question should be "when the API says 'equals', does it always refer to the most reasonable way to apply .equal or sometime does it refer to the analogous way to apply ==?"
EDIT
I think based on the answers I should clarify: this is not a question about the difference between == and .equal. It is about to which the Java API is referring when it uses the English word "equals".
It's clear that you do understand the difference between equals() and ==. So your question is rather philosophical :)
Generally, many APIs use "equals to" in the meaning of equals() and "is the same as" in the meaning of ==. E.g. JUnit has assertion method assertEquals() and assertSame().
However, use your common sense and analyze the language of the doucmentation. Notice in your quoted sentence from API the usage of the indefinite article:
"Creates a new BooleanExpression that holds true if this
ObjectExpression is equal to a constant value."
"a constant value" clearly means any constant value, not the same value as the "constant" value. So it is clear that this cannot mean the same as constant.equals(stringExpression).
So take it in this way: when documentation says "equals", take it that it relates to the content of the variable, not to its reference. But use common sense and read the sentence as a whole :)
Does it answer your question? :P
does it always mean that a.equals(b) evaluates to true, or sometime
does it mean a == b is true?
when the API says 'equals', does it always refer to the most
reasonable way to apply .equal or sometime does it refer to the
analogous way to apply ==?"
It's about overriding equals() method, In java, only += operator overloaded, other operators can't be overloaded means, you can't override ==
When writing an API-doc when using the term "equal" this should usually mean "equal in terms of the equals()-method". If it really does depends on the thoroughness of the writer of the documentation, but in the official API-docs I would always take as having this meaning.
For your question "can it also mean ==": it can in the way that Object's equals()-method just checks for reference-identity, that is it checks using ==.
If you use .equals it will compare the value. By using == you are comparing the reference and these doesn't have to be the same even if your values are the same.
See following website for a full explanation: http://www.javabeat.net/what-is-difference-between-equals-and/
I've copied a part of his example:
s1 = new String("abc");
s2 = new String("abc");
Now, if you use the equals() method to check for their equivalence as
if(s1.equals(s2))
System.out.println("s1.equals(s2) is TRUE");
else
System.out.println("s1.equals(s2) is FALSE");
You will get the output as TRUE as the equals() method check for the content equality.
Lets check the == operator..
if(s1==s2)
System.out.printlln("s1==s2 is TRUE");
else
System.out.println("s1==s2 is FALSE");
Now you will get the FALSE as output because both s1 and s2 are pointing to two different objects even though both of them share the same string content. It is because of new String() everytime a new object is created.
When some one creates a java class it inherit boolean equals(Object o) method from class 'Object', as all user defined class when not extending any other class extends class Object implicitly.
When this class is instantiated using new operator the equality of this objects are achieved by using this underline formula.
return (this == obj);
Hence it will return true if and only if both object refers to the same object on the heap i.e (a == b) = true
class Abc{}
Abc a = new Abc();
Abc b = a;
a==b //(true)
a.equals(b) //(true)
And suppose they are instance of same class but are two different object than
class Abc{}
Abc a = new Abc();
Abc b = new Abc();
a==b; //(false)
a.equals(b); //(false)
But when an class created overrides this equals method then this equality is evaluated using the new formula provided while overriding it. for example .equals object override by java.util.Date
public boolean equals(Object obj) {
return obj instanceof Date && getTime() == ((Date) obj).getTime();
}
This will return true if and only both Date object have equal value returned by getTime() method.
Hope this helps. Feel free to ask further questions if any doubt.

Why is a certain boolean false though it should be true? [duplicate]

This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 9 years ago.
I wrote a Java program that should support English and German language. If a parameter is set and if it equals "english" or "English", it shall call a method that does the English version and if there is no parameter or it doesn't equal "English" or "english", it shall call the method for the German version.
However, (args[0]=="english"||args[0]=="English") is false no matter what my parameter is, even if it should be true and I don't get why that's the case.
Here is the main method, the other ones aren't important, so I'll leave them away.
public static void main(String[] args){
boolean input=args.length==1;
System.out.println(input);
boolean mode = false;
if (input) mode=args[0]=="English"||args[0]=="english";
System.out.println(mode);
if(input&&mode) english();
else german();
}
Does anyone have a clue why it won't be true, regardless of my parameter?
Use the equals() method for String value comparison.
args[0].equals("English")||args[0].equals("english")
or even better(in this case)
args[0].equalsIgnoreCase("English")
== is for object reference comparisons. Don't use it for comparing the values.
You can't compare strings in Java in this way because Java Machine compare pointers to the string objects. To make correct compassion use function equals:
if( "english".equalsIgnoreCase( args[0] ) ) {
// English language
}
Strings should not be compared with == but with equals method.
Use
args[0].equalsIgnoreCase("English")
it will compare for both, "english" and "English".
better version is
"English".equalsIgnoreCase(args[0]);
this will make sure, if args[0] is null, i.e no argument in your case, it will not throw NPE.
Explaination : Because in Java, == compares objects not there values, i.e if two references are holding same object or not. Objects content are compared with equals method of Object class, which String class overrides.

Categories

Resources