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

Elements.getAllMembers returns interface methods where it should return class methods

    XMLWordPrintable

Details

    • Bug
    • Resolution: Other
    • P4
    • 23
    • 21
    • core-libs
    • None

    Description

      For example, Elements.getAllMembers( Elements.getTypeElement("java.util.List") ) returns a list that contains List.equals and List.hashCode, but should instead contain Object.equals and Object.hashCode.

      Why? Because of the rules in 8.4.8. "Inheritance, Overriding, and Hiding" and some additional rationale and thoughts in 9.4.1.2. "Requirements in Overriding".

      - 8.4.8. Inheritance, Overriding, and Hiding

      A class C inherits from its direct superclass type D all concrete methods m (both static and instance) for which all of the following are true:

       m is a member of D.

       m is public, protected, or declared with package access in the same package as C.

       No method declared in C has a signature that is a subsignature (§8.4.2) of the signature of m as a member of D.

      - 9.4.1.2. Requirements in Overriding

      The prohibition against declaring one of the Object methods as a default method may be surprising. There are, after all, cases like java.util.List in which the behavior of toString and equals are precisely defined. The motivation becomes clearer, however, when some broader design decisions are understood:

      First, methods inherited from a superclass are allowed to override methods inherited from superinterfaces (§8.4.8.1). So, every implementing class would automatically override an interface's toString default. This is longstanding behavior in the Java programming language. It is not something we wish to change with the design of default methods, because that would conflict with the goal of allowing interfaces to unobtrusively evolve, only providing default behavior when a class doesn't already have it through the class hierarchy.

      Second, interfaces do not inherit from Object, but rather implicitly declare many of the same methods as Object (§9.2). So, there is no common ancestor for the toString declared in Object and the toString declared in an interface. At best, if both were candidates for inheritance by a class, they would conflict. Working around this problem would require awkward commingling of the class and interface inheritance trees.

      Third, use cases for declaring Object methods in interfaces typically assume a linear interface hierarchy; the feature does not generalize very well to multiple inheritance scenarios.

      Fourth, the Object methods are so fundamental that it seems dangerous to allow an arbitrary superinterface to silently add a default method that changes their behavior.

      An interface is free, however, to define another method that provides behavior useful for classes that override the Object methods. For example, the java.util.List interface could declare an elementString method that produces the string described by the contract of toString; implementors of toString in classes could then delegate to this method.



      Attachments

        Issue Links

          Activity

            People

              darcy Joe Darcy
              prappo Pavel Rappo
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: