Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java: how to write proper equals method for classes that really do not have any state?

Consider this interface:

public interface Listenable {
  void listen();
}

Consider this implementation:

public class Listener implements Listenable {
  public void listen() {
    System.out.println("I am listening");
  }
}

Now I am doing remoting via RMI and I am passing instances of such classes to server (maybe some black-magic proxies are spawn there, not sure).

The only solution I was able to invent so far, and I have to say it's pretty idiotic, is to add this code to Listener class:

public class Listener implements Listenable {
  private double id;
  private Random rand = new Random();
  public Listener() {
    this.id = rand.nextDouble();
  }
  public void listen() {
    System.out.println("I am listening");
  }
  public int hashCode() { ... } // calculate from id
  // same for equals - compare by id
}

This usually works, but we all know how evil this is :/ How should one deal with such a situation?

UPDATE:

Stanard equals did not work for me, because instances are over different VMs (I mentioned remoting), so it couldn't work. I will need some state variable after all, or suggest something good for comparing such classes on remote VMs. I am very sorry for confusion.

like image 703
Xorty Avatar asked Dec 09 '22 08:12

Xorty


2 Answers

Make the listener an enum singleton:

public enum Listener implements Listenable {
  INSTANCE;

  public void listen() {
    System.out.println("I am listening");
  }
}

Then there will be only one instance of Listener and equality is guaranteed.

You may not want to expose the fact that you're using an enum for this or even that the listener is a singleton at all. What you can do is make the enum a private inner enum of some class with static methods (called Listenables, let's say) and just expose this implementation through a static method:

public static Listenable printingListenable() {
  return Listener.INSTANCE;
}
like image 116
ColinD Avatar answered Dec 14 '22 23:12

ColinD


IMHO equality of objects is defined by the equality of their state. If the object does not hold any state (arguably it shouldn't be called an object, but that's a different story), all the instances of that object are logically equal. So don't bother and write:

public boolean equals(Object obj) {
  return obj instanceof Listener;
}

public int hashCode() {
  return 0;
}
like image 27
Tomasz Nurkiewicz Avatar answered Dec 15 '22 00:12

Tomasz Nurkiewicz