Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8181769

Introduce interface with type-safe equals

    XMLWordPrintable

    Details

      Description

      A DESCRIPTION OF THE REQUEST :
      The expression like `a.equals(b)` looks sane but it can be always `false` especially when variables `a` and `b` holds objects of incomparable types, e.g. `a` holds `java.lang.String` and `b` holds `java.util.Date`. Please note that such *always-false-equals* expressions may appear during refactoring when type of variables is changed and these cases are not reported by compiler and static analysis tools may not handle such issues in general. It would be good if compiler reported error when we try to compare incomparable types. As workaround we could write `a.compareTo(b) == 0` instead of `a.equals(b)`, but this may be less efficient. Checking whether comparable objects are equals often require less efforts than finding out which one is greater or less than the other. Also there are cases when classes do not implement `java.lang.Comparable<T>` but they may have type-safe equals. E.g. `java.util.ArrayList` can be checked for equality with other classes that implements `java.util.List`, but `java.util.List` does not extend `java.lang.Comparable<java.util.List>`.

      In order to solve this issue it is proposed to introduce new interface `java.lang.ComparableEQ<T>` with method `boolean isEqualTo(T)`.
      ```
      interface ComparableEQ<T> {
          /**
           * returns true if `this` is equal to `o`.
           * throws NullPointerException if `o` is null.
           */
          boolean isEqualTo(T o);
      }
      ```
      The name of interface and its method may be different, but in order to avoid overloading the name of the method should not be `equals`.

      It also makes sense of extend existing interface `java.lang.Comparable<T>` with this new interface and provide default implementation for `isEqualTo` method.
      ```
      interface Comparable<T> extends ComparableEQ<T> {
          int compareTo(T o);

          default boolean isEqualTo(T o) {
              return compareTo(o) == 0;
          }
      }
      ```
      Implementors of `java.lang.Comparable<T>` may define `isEqualTo` more efficiently than through `compareTo` method.

      Please also note some differences between proposed `ComparableEQ<T>` and .NET `IEquatable<T>`:
      * In .NET `Equals` method is overloaded (there are `IEquatable<T>.Equals(T)` and `Object.Equals(Object)`), but `ComparableEQ<T>.isEqualTo(T)` should have other name as `Object.equals(Object)` intentionally.
      * `IEquatable<T>.Equals(T)` returns false if argument is null, but `ComparableEQ<T>.isEqualTo(T)` should throw NPE as `Comparable<T>.compareTo(T)` does.

      JUSTIFICATION :
      This RFE helps to avoid bug related to unintentional comparison of incomparable types.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Long a = 1
      String b = "1"
      boolean c = a.isEqualTo(b); // compilation error: The method isEqualTo(Long) in the type Long is not applicable for the arguments (String)
      ACTUAL -
      Long a = 1
      String b = "1"
      boolean c = a.equals(b); // always false

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              Unassigned Unassigned
              Reporter:
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved: