zombieParrot
zombieParrot

Reputation: 111

A strange clause in the documentation of java.lang.Class::getDeclaredMethods

From the documentation of java.lang.Class::getDeclaredMethods:

Returns an array containing Method objects reflecting all the declared methods of the class or interface represented by this Class object, including public, protected, default (package) access, and private methods, but excluding inherited methods. The declared methods may include methods not in the source of the class or interface, including bridge methods and other synthetic methods added by compilers. If this Class object represents a class or interface that has multiple declared methods with the same name and parameter types, but different return types, then the returned array has a Method object for each such method...

AFAIK java doesn't allow a class or an interface to have methods differing only by their return type(return type is not part of a function's signature), so how would this happen?

Upvotes: 5

Views: 91

Answers (1)

Turing85
Turing85

Reputation: 20195

To understand why this is possible, we need to understand that there are actually two worlds in Java: the Java language world, governed by the JLS, and the Java Virtual Machine world, governed by the JVM Specification.

Those worlds do not always match 1:1. You found one example. Another example are generics. Due to type erasure (oracle.com) the types are replaced with the upper bound through the compiler, thus all type information is lost at runtime. This is the reason why we cannot call .class on a generic parameter T.

Normally as programmers, we only interact with the Java language, and the compiler takes care of transforming the code into Bytecode that is executed on the JVM. Reflection, on the other hand, allows us to interact with objects at runtime. Thus, we get a glimpse into this world. In this specific case, the JVM Specification, $4.7.9.1 (docs.oracle.com) states:

...

A method signature encodes type information about a (possibly generic) method declaration. It describes any type parameters of the method; the (possibly parameterized) types of any formal parameters; the (possibly parameterized) return type, if any; and the types of any exceptions declared in the method's throws clause.

MethodSignature:
  [TypeParameters] ( {JavaTypeSignature} ) Result {ThrowsSignature}

Result:
  JavaTypeSignature
  VoidDescriptor

ThrowsSignature:
  ^ ClassTypeSignature
  ^ TypeVariableSignature

...

Upvotes: 4

Related Questions