开发者

How to solve the problem: int cannot be dereferenced

Here I have some value which two of them are integer and I can't call a method on them since they are not reference. How can I solve this?

String srcAddr, dstAddr, protocol;
int srcPort, dstPort;

public int hashCode() {

        final int prime = 31;
        int result = 1;
        result = prime * result + ((dstAddr == null) ? 0 : dstAddr.hashCode());
        result = prime * result + ((dstPort == null) ? 0 : dstPort.hashCode());
        result = prime * result + ((srcAddr == null) ? 0 : srcAddr.hashCode());
        result = prime * result + ((srcPort == nu开发者_JAVA百科ll) ? 0 : srcPort.hashCode());
        return result;

}

Also, I have an equal method too, a part of it with the error is shown below ,which the same as above I can not compare int with a null.

@Override
public boolean equals(Object obj) {

    if (srcPort == null) {
        if (other.srcPort != null)
            return false;
    } else if (!srcPort.equals(other.srcPort))
        return false;

    if (srcPort == null) {
        if (other.srcPort != null)
            return false;
    } else if (!srcPort.equals(other.srcPort))
        return false;
}

How can I solve this error?


Writing hashcode and equals can be tedious and/or error-prone, and IDEs such as Eclipse can actually automate this task for you. There are many third party libraries that can facilitate this functionality as well.

To use something from the standard library, I recommend doing the following:

import java.util.Arrays;

// conveniently packs varargs to array 
private static Object[] pack(Object... objs) {
   return objs;
}

private Object[] fieldsAsArray() {
   return pack(srcAddr, dstAddr, protocol, srcPort, dstPort);
}

@Override public int hashCode() {
   return Arrays.hashCode(this.fieldsAsArray());
}

@Override public boolean equals(Object o) {
   // TODO: instanceof check, cast and assign o to other

   return Arrays.equals(this.fieldsAsArray(), other.fieldsAsArray());
}

This uses varargs, autoboxing, and java.util.Arrays utility method implementation for equality and hashcode of arrays. This will have an adequate (though perhaps not optimal) performance, but the code is succint and readable, and can always be optimized later if/when necessary.


Third party library options

From Apache Commons Lang, you can use EqualsBuilder and HashCodeBuilder.

The documentation has example of typical usage:

@Override public boolean equals(Object obj) {
   if (obj == null) { return false; }
   if (obj == this) { return true; }
   if (obj.getClass() != this.getClass()) {
     return false;
   }
   MyClass other = (MyClass) obj;
   return new EqualsBuilder()
                 .appendSuper(super.equals(obj))
                 .append(field1, other.field1)
                 .append(field2, other.field2)
                 .append(field3, other.field3)
                 .isEquals();
}

@Override public int hashCode() {
   return new HashCodeBuilder(17, 37)
                 .append(field1)
                 .append(field2)
                 .append(field3)
                 .toHashCode();
} 

The resulting code is very readable, very maintainable, and less error prone.

Related questions

  • Overriding equals and hashCode in Java


For the hashcode method, you can just leave the ints as they are. Ints are their own hascodes. For the equals method, just compare them using =. So the code becomes:

public class Connection {

    String srcAddr, dstAddr, protocol; int srcPort, dstPort;

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((dstAddr == null) ? 0 : dstAddr.hashCode());
        result = prime * result + dstPort;
        result = prime * result
                + ((protocol == null) ? 0 : protocol.hashCode());
        result = prime * result + ((srcAddr == null) ? 0 : srcAddr.hashCode());
        result = prime * result + srcPort;
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Connection other = (Connection) obj;
        if (dstAddr == null) {
            if (other.dstAddr != null)
                return false;
        } else if (!dstAddr.equals(other.dstAddr))
            return false;
        if (dstPort != other.dstPort)
            return false;
        if (protocol == null) {
            if (other.protocol != null)
                return false;
        } else if (!protocol.equals(other.protocol))
            return false;
        if (srcAddr == null) {
            if (other.srcAddr != null)
                return false;
        } else if (!srcAddr.equals(other.srcAddr))
            return false;
        if (srcPort != other.srcPort)
            return false;
        return true;
    }

}

Writing correct implementations of hashCode and equals is tricky. Better use your IDE to generate them. That's what I did here too.


You need to use the boxed primitives, specifically Integer. There's a similar object for each primitive, and they define the methods you're interested in (hashCode,equals).


Initalise the integers to something (say -1) and compare them to -1

I don't see why you want to get the Hashcode of an integer. Hashcode takes an object and returns a unique(?) integer based on the object. An integer is just a primitive object and you should need to get a hashcode from it to identify it.

I would just refer to the integers directly and have a check for -1 (if you initialise them to -1) instead of a check to null. (It is my understanding that a port is never -1, do correct me if this is false)


srcPort and dstPort are primitive ints.

In your hashCode() method, you are comparing dstPort and srcPort to null. You can't do that with primitive types in Java. Just write the lines in your hashCode() method like this:

result = prime * result + ((dstAddr == null) ? 0 : dstAddr.hashCode());
result = prime * result + dstPort;
result = prime * result + ((srcAddr == null) ? 0 : srcAddr.hashCode());
result = prime * result + srcPort;

In your equals() method, you are trying to call the equals() method on srcPort. You cannot call methods on primitive types in Java. Use == to compare pritimive types.

Note that your equals() method also contains the same block of code twice; this is most likely a mistake. And don't you have to check srcAddr and dstAddr as well in your equals() method? What is other in your equals() method? Is this the complete code or only part of it?


I think Shakedown has the answer for you, just used the boxed Integer type like so:

String srcAddr, dstAddr, protocol; Integer srcPort, dstPort;

public int hashCode() {

    final int prime = 31;
    int result = 1;
    result = prime * result + ((dstAddr == null) ? 0 : dstAddr.hashCode());
    result = prime * result + ((dstPort == null) ? 0 : dstPort);
    result = prime * result + ((srcAddr == null) ? 0 : srcAddr.hashCode());
    result = prime * result + ((srcPort == null) ? 0 : srcPort);
    return result;

}

or alternatively use 0 as a default value (since that's what you return if the value isn't set anyway) like so:

String srcAddr="", dstAddr=""; int srcPort=0,dstPort=0; //empty string has hashCode 0

public int hashCode() {
  final int prime = 31;
  int result = 1;
  result = prime * result + dstAddr.hashCode();
  result = prime * result + dstPort;
  result = prime * result + srcAddr.hashCode();
  result = prime * result + srcPort;
  return result;
}

This way you don't need to worry about the implicit cost of auto-boxing if that is an issue


There are two problems here. First, ints declared at the class level as instance or class variables are always initialized to a value. It doesn't matter what that value is, they are defined to be something, even if you don't explicitly do it. Second, it makes no sense to call hashCode() on something that is a primitive type as these don't have methods you can invoke.

My implementation would look something like this:

public int hashCode() {

        final int prime = 31;
        int result = 1;
        result = prime * result + ((dstAddr == null) ? 0 : dstAddr.hashCode());
        result = prime * result + dstPort;
        result = prime * result + ((srcAddr == null) ? 0 : srcAddr.hashCode());
        result = prime * result + srcPort.hashCode;
        return result;

}

public boolean equals(Object obj) {
    if (!(obj instanceof MyClass)) {
        return false;
    }

    //Cast obj to a MyClass

    if (other.srcPort != scrPort) {
            return false;
    }

    if (other.dstPort != dstPort) {
            return false;
    }

    //Check the other variables too.

    //We didn't fall into any if-statements.
    return true;
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜