Point of exit from a method in Java - java

In Eclipse, is there any way to find which return statement a method returned from without logging flags at every return statment?
For example:
#Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof ABC)) {
return false;
}
ABC other = (ABC) obj;
if (var1 == null) {
if (other.var1 != null) {
return false;
}
} else if (!var1.equals(other.var1)) {
return false;
}
return true;
}
In this case, how do I find out at which point my equals method returned?

No, but a more understandable and debug friendly code can be with a boolean local variable that represents the result.
then you can see with debugger who assign it when and the return value before returned.

No. This is one reason that some people prefer single point of exit:
Why should a function have only one exit-point?
Note also the links in the first comment on that question.

Use breakpoints in debug mode.

Related

ArrayLIst<PojoClass> list.contain() is not working and return false?

This question ask many times in stackoverflow and i tried all masters answers.
But list.contain() return always false.
and also overide equal() method.
Here is my pojo class
public class RecentStickerPojo
{
File stickerName;
File folderName;
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
RecentStickerPojo other = (RecentStickerPojo) obj;
if (folderName != other.folderName&&stickerName!=other.stickerName)
return false;
return true;
}
}
in activity class
RecentStickerPojo recentStickerPojo=new RecentStickerPojo();
recentStickerPojo.setStickerName(s1);
recentStickerPojo.setFolderName(f1);
list.contains(recentStickerPojo) // return false
Don't forget to implement hashcode.
For strings, use equals (or !equals) and not == (or !=)
Also the equals' last 3 lines can be changed to:
return (folderName.equals(other.folderName) && stickerName.equals( other.stickerName);
No need to override hashcode, as List contains method will use equals method for comparing object. It seems you are comparing File objects directly which can be different. Yes, try by changing last comparison,
if (folderName.equals(other.folderName) && stickerName.equals(other.stickerName))

How to cover equals method in code coverage

New to code coverage, would like to have some insights...
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Person other = (Person) obj;
if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
return false;
}
if ((this.email == null) ? (other.email != null) : !this.email.equals(other.email)) {
return false;
}
if (this.age != other.age && (this.age == null || !this.age.equals(other.age))) {
return false;
}
return true;
}
How do I cover this in jcoco code coverage.
To have this class 100% tested you should create a test for every if and ?: operator. Every part of the code should be tested. For instance, the first if (this == obj), you should have a test where you do
#Test
public void testEqualsSameObj() {
MyClass sut = new MyClass(); // sut == system under test
assertTrue (sut.equals(sut));
}
And now make the next test for passing null:
#Test
public void testEqualsNull() {
MyClass sut = new MyClass(); // sut == system under test
assertFalse (sut.equals(null));
}
And continue with the next condition, until you cover all branches in the code.
You can take the sut from the method and store it in the test class as a member variable.
The equals could have 0% coverage because you might have not included the lombok.config file with with generated annotations as true.
Set,
config.stopBubbling = true;
lombok.addLombokGeneratedAnnotation = true
in lombok.config file
I'm not sure about the what method you are trying to get covered. What I understood from your question is: you are trying to cover equals code of the person.
So in order to cover that
1) have your name property of current object which referred by this as null
2) have your name property of current object as not null to cover the equals part of the code.
To understand more on this learn how ternary (? :) operator works.
I hope this answer helps.

Casting Object to a Pair

I am trying to get my "equals" method to work but am having trouble. This is supposed to be easy but I am new to this. I thought I had to cast otherOject to a pair in order to be able to use .fst and check if the pairs are equal, however I am having difficulty "casting" properly. Any help would be much appreciated. I have the following methods:
public void setFst(T1 aFirst)
{
fst = aFirst;
}
public void setSnd(T2 aSecond)
{
snd = aSecond;
}
public boolean equals(Object otherObject)
{
Pair aPair = (Pair)otherOject; //--------> ???
if(otherObject.fst.equals(this.fst) && otherObject.snd.equals(this.snd))
{
return true;
}
}
Here are the errors I am getting:
./Pair.java:84: cannot find symbol
symbol : variable fst
location: class java.lang.Object
if(otherObject.fst.equals(this.fst) && otherObject.snd.equals(this.snd))
^
./Pair.java:84: cannot find symbol
symbol : variable snd
location: class java.lang.Object
if(otherObject.fst.equals(this.fst) && otherObject.snd.equals(this.snd))
^
This isn't that easy, this has more pitfalls than you'd think.
Your equals method has to allow for having objects belonging to classes other than the class you're writing it for. You have to do is check to see if the argument is also a Pair:
if (otherObject == null) return false;
if (otherObject.getClass() != Pair.class) return false;
After this check is passed you can cast safely, and assign the cast object to a new local variable:
Pair otherPair = (Pair)otherObject;
then use the fields on otherPair for your equals check. At this point you're done with the otherObject parameter and the rest of the equals method shouldn't reference it anymore.
the whole thing would look like
public boolean equals(Object otherObject) {
if (otherObject == null) return false;
if (getClass() != otherObject.getClass()) return false;
Pair otherPair = (Pair)otherObject;
return otherPair.fst.equals(this.fst) && otherPair.snd.equals(this.snd);
}
assuming that fst and snd are not allowed to be null. Calling the equals method on a null member will cause a NullPointerException. To avoid the NPE if fst or snd are null, check if the members are null before calling equals on them:
public boolean equals(Object otherObject) {
// check if references are the same
if (this == otherObject) return true;
// check if arg is null or something other than a Pair
if (otherObject == null) return false;
if (getClass != otherObject.getClass()) return false;
Pair otherPair = (Pair)otherObject;
// check if one object's fst is null and the other is nonnull
if (otherPair.fst == null || this.fst == null) {
if (otherPair.fst != null || this.fst != null) return false;
}
// check if one object's snd is null and the other is nonnull
if (otherPair.snd == null || this.snd == null) {
if (otherPair.snd != null || this.snd != null) return false;
}
// each member is either null for both or nonnull for both
return ((otherPair.fst == null && this.fst == null) || otherPair.fst.equals(this.fst))
&& ((otherPair.snd == null && this.snd == null) || otherPair.snd.equals(this.snd));
}
This last bit is annoying to write, IDEs will generate this stuff for you. Here's what Eclipse generates:
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Pair other = (Pair) obj;
if (fst == null) {
if (other.fst != null)
return false;
} else if (!fst.equals(other.fst))
return false;
if (snd == null) {
if (other.snd != null)
return false;
} else if (!snd.equals(other.snd))
return false;
return true;
}
Remember to implement hashCode too.
The major problem is that after you have cast, you are comparing with the original otherObject, which still is an instance of the Object class, rather than the variable on the Left hand side of your assignment aPair which has the type Pair
So, this should get you going:
public boolean equals(Object otherObject)
{
Pair aPair = (Pair)otherOject; //--------> ???
if(aPair.fst.equals(this.fst) && aPair.snd.equals(this.snd))
{
return true;
}
}
Be careful here though. What you are doing is called unchecked casting. Your compiler might warn you about it. You don't know whether the object being passed to your equals method really can be cast to a Pair - it has to be an instance of Pair or a subclass of Pair for that to be a valid action. So, your cast might fail at runtime if, for instance, you pass a String or Integer object into the method.
EIT
#NathanHughes's more complete answer to this question shows you how to check the casting (using instanceof keyword), so I won't repeat it here.
I recommend the Oracle java tutorial docs for this kind of thing. Check this tutorial for classes and subclasses - the very end is about how to cast and check if it is valid to cast.
Best to do
#Override
public boolean equals(Object otherObject) {
if (otherObject instanceof Pair) {
Pair otherPair = (Pair)otherObject;
return otherPair.fst.equals(fst) && otherPair.snd.equals(snd))
}
return false;
}
Your otherObject is an instance of Object and there is no fst on the Object. Need to change to aPair.fst.equals.

hashset return false when should return true

I'm programming a Maze and I have some problems.
I have:
HashSet<State> closedList = HashSet<State>(); //it hold State objects
My State class look like this:
public class State implements Comparable<State>{
private double f;
private double g;
private String state;
private State prev;
.
.
.
closedList.add(state);
closedList().contains(state); // this equals true
but when I do this:
State temp = State(0,0,"");
temp.setStateName(state.getStateName());
closedList().contains(temp); // this equals false
I have implemented equals and hashCode in State:
#Override
public int hashCode(){
return state.hashCode();
}
#Override
public boolean equals(Object object){
if(this.state == object){
return true;
}
if(object == null || object.getClass() != this.getClass()){
return false;
}
return false;
}
closedList().contains(state); // this equals true
This is a red herring, it only returns true because HashSet checks with == before it makes a call to equals.
What you should try is something like this:
State temp = new State(0, 0, "");
System.out.println(temp.equals(temp));
And you will find this returns false. Why is that? Well let's follow the logic through.
First, you have this check:
if(this.state == object){
return true;
}
If you really intended this to be the way it is, it means you were expecting equals to be called with the String state as the argument, like this:
temp.equals(temp.getStateName())
(And it's the case the above call would return true.) This is incorrect, one would not expect equals to return true for unrelated classes (and in terms of the equals contract, it's the case this is not symmetric). I assume this is unintended and just like a mistake. You should think more carefully about what your code is doing when you are writing it.
Also you should be comparing Strings with equals, not ==.
Then there is this construct:
if(object == null || object.getClass() != this.getClass()){
return false;
}
return false;
This is pointless because first what it implies logically is this, returning false either way:
if(object == null || object.getClass() != this.getClass()){
return false;
} else {
return false;
}
And, second, combined with the earlier check it is not particularly logical:
if(this.state == object)
return true;
if(object.getClass() != this.getClass())
return false;
This is returning true if object is == to a String but returning false if object's class is not State. These are mutually exclusive.
So the equals implementation you wrote doesn't work. The correct equals to match your hashCode is like this:
#Override
public boolean equals(Object object){
if(object == null || object.getClass() != this.getClass()){
return false;
}
State other = (State)object;
return this.state.equals(other.state);
}
First check that the object is not null and that its class is State (you had that part right), then check that the state member is equal to the other object's state member.

How can I get checkstyle to skip equals() and hashcode() methods generated by eclipse?

Our project contains several classes that we have equals() and hashCode() methods generated by Eclipse (Right Click -> Source -> Generate hashCode() and equals()).
Example:
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final MyTO other = (MyTO) obj;
if (num != other.num)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (table == null) {
if (other.table != null)
return false;
} else if (!table.equals(other.table))
return false;
return true;
}
These methods that work well for our application, but unfortunately do not pass our cyclomatic complexity checks with Checkstyle. Since these methods are auto-generated, we are not concerned with their complexity. We could suppress the entire class from Checkstyle, but we would prefer to be able to exclude just these two methods.
Does anyone know how to create a custom rule in Checkstyle that will allow us to exclude generated equals() and hashCode() methods in any way, without excluding the entire class?
You should set up a SupressionCommentFilter. More info on this here.
Sometimes there are legitimate reasons for violating a check. When this is a matter of the code in question and not personal preference, the best place to override the policy is in the code itself. Semi-structured comments can be associated with the check.

Categories