How does the equals() method work in Java?

Asked

Viewed 597 times

0

At the time I will use the method equals() I place an object of the type Person and it works, because?

How it works being that the object I passed is not the type Object?

I know all this has to do with class Object.

    @Override
    public boolean equals(Object obj) {
    Person contaDiferente = (Person) obj;
    if (this.salario == contaDiferente.salario) {
        return true;
    } else {
        return false;
    }
  • In java, every object extends from the class Object

  • @Naranteodoro, I believe the answer here can help in understanding your question.

3 answers

7

This is called polymorphism. See definition of this concept. It allows code reuse.

Type hierarchy

So all the types you create, in your example the Person, are at the same time other types. At least in Java there is always another type in the reference types created as a class.

In Java it can only have a type that inherits a structure of a type (classes), but can inherit from several types that do not form a complete object (interfaces), that is, that has not been (variables), only behaviors (methods) and contracts (method signature).

Understand the difference between subclass and subtype.

To ensure that a new class always has a type it is implicitly inherited from Object. This is the root type of Java, it has some methods already implemented that its type will always have in function of having inherited from Object (see the documentation what are they).

One of these methods is the equals(). we usually use the @override.

If you inherit from another type it will not be inheriting directly from Object, but indirectly yes, because if its type inherits from a type (always class) it must have inherited from Object, then in practice inherits from Object also.

Overlapping

Of course the methods may have a different implementation. The type you are inheriting may have overlapped what the Object did. Just as your type can overlap.

To overlapping is quite useful to allow you to perform the method according to the need of your type.

Polymorphism applied

So when you go to write a method that needs to deal with some feature of Object you do not need to write one for each type you create, you can create one that receives any object, parameter declared generically as Object, and he can handle it because he is a Object, besides being your own kind (Person). It can be other types at the same time too. IE, it can assume various forms, it has several facets.

Casting

But note that in your case it only works because you are using one cast. You are accessing the member salario of obj. You know that Person has this member. But he’s getting a Object, and you know this guy doesn’t have the limb salario. The only way the compiler will accept that you access salario is if you turn the object into Person. The `cast does that.

How does it work? Because the concrete object that was passed to this method is a Person, he receives as Object, but in fact it is only one facet of it, there is a "person" inside the object. If you try to access a member of the Object, funciona. Se tentar acessar um membro de Person` does not work, even if you know you have the member there. You have to instruct the compiler to accept what you want.

But think about it. And if you pass one Object same, or a Product, what happens to the code when it tries to do the cast? He’ll try to turn one Product in Person. The concrete object received as Object does not have the members of Person and the code will fail if you try to access them.

But something worse can happen. Your Person has a name and the Product also has a name. But they’re very different names, one of a person and the other of a product, you can’t use one as if it were the other. For this it was defined that its application already prevents the error in casting and a new type object will not exist. The casting will generate a null object.

The correct is to check if the transformation worked, otherwise it is a programming error your.

I don’t like this way of solving things, but it’s the way Java has it. It’s inefficient, it takes a lot of care and it’s easy to make a mistake. Breaks the security of types that language propagates as one of its trump cards.

I I answered a question with a safer example.

Your code would look better this way:

@Override
public boolean equals(Object obj) {
    // Um objeto é sempre igual a ele mesmo
    if (this == obj) return true; 
    // Um objeto nunca deve ser igual a null
    /* Uma pessoa só pode ser igual a outra pessoa.
     * Caso uma pessoa possa ser igual a uma de suas subclasses
     * use !(obj instanceof Person)
     */
    if (obj == null || getClass() != obj.getClass()) return false;
    // Converte a referencia para uma pessoa
    final Person other = (Person)obj;
    //alguma falhar ocorrer na transformação
    if (othe == null) return false;
    // Elas possuem o mesmo salario
    return this.salario == contaDiferente.salario;
}

I put in the Github for future reference.

Not all objects in Java derive from Object

Not all objects in Java derive from Object, at least until version 15 )or higher, are promising from 9). Something will change in future Java that will have the possibility to create types by value that derive from Object. It is not yet known whether the current types by value that do not derive from Object will pass drift or not. Then a Integer derives from Object, but a int does not drift. This has important implications that is not the case here.

Completion

Something tells me this method is semantically wrong. This should not compare wages, it should be concerned with the identity of the object and salary is not part of your identity. And something tells me salary type is not suitable to hold a monetary value.

Beware of information that picks up on the internet, you never know the commitment that the author has to pass on correct information to you, and he does not know your context well. For example, I don’t know if you understand everything I’m writing, which gives room for new questions, but I can’t write a complete book on the subject, you learn one thing at a time.

3


Works because any instance/object of type Person (or any other class) is also a Object.

Implicitly, all Java classes inherit from Object.

That’s why when you just create a class it already "comes with" the methods:

clone()
equals(Object obj)
finalize()
getClass()
hashCode()
notify()
notifyAll()
toString()
wait()
wait(long timeout)
wait(long timeout, int nanos)

For those are inherited class Object

  • so if I create a class and the more (daughters) do a extends of it, I can do that same scheme, or it only works with the Objects class ?

  • You can do the same thing. All classes in Java inherit from Object. If the parameter of your method is to type Object you can pass any type

0

Browser other questions tagged

You are not signed in. Login or sign up in order to post.