Merging interfaces

S

Stefan Ram

I used this piece of code to find the return type of the
method "f" in the interface "C" under Java 1.6.

interface A { java.lang.Object f(); }
interface B { B f(); }
interface C extends A, B {}

public class Main
{ public static void main( final java.lang.String[] args )
{ java.lang.reflect.Method method = null; try
{ method = C.class.getMethod( "f",( java.lang.Class[] )null ); }
catch( final java.lang.NoSuchMethodException noSuchMethodException )
{ throw new java.lang.RuntimeException( noSuchMethodException ); }
java.lang.System.out.println( method.getReturnType() ); }}

A reader of this post might try to predict the outcome
without actually running or compiling it. -- The range of
possible predictions also includes »It will not compile,«
or »It will produce a run-time error«.
 
E

Ed

Thomas said:
Looks like a bug to me. Documentation reads:

You're up late tonight, Thomas.

I'm on my way out to a Stockholm pub.

Life could be worse ...

..ed
 
T

Thomas Hawtin

Stefan said:
I used this piece of code to find the return type of the
method "f" in the interface "C" under Java 1.6.

interface A { java.lang.Object f(); }
interface B { B f(); }
interface C extends A, B {}
[...]
A reader of this post might try to predict the outcome
without actually running or compiling it. -- The range of
possible predictions also includes »It will not compile,«
or »It will produce a run-time error«.

Looks like a bug to me. Documentation reads:

"If more than one such method is found in C, and one of these methods
has a return type that is more specific than any of the others, that
method is reflected; otherwise one of the methods is chosen arbitrarily.

"Note that there may be more than one matching method in a class because
while the Java language forbids a class to declare multiple methods with
the same signature but different return types, the Java virtual machine
does not. This increased flexibility in the virtual machine can be used
to implement various language features. For example, covariant returns
can be implemented with bridge methods; the bridge method and the method
being overridden would have the same signature but different return types."

http://download.java.net/jdk6/docs/api/

In this case one method is more specific than the other.

The docs are a bit peculiar. Consider three methods, two of which are
more specific than the third but are not ordered themselves. The docs
say that the definitely least specific method can be picked.

The sentence "Let C be the class represented by this object:" is also a
little loose. The (Class) object also represents interfaces (and arrays).

Tom Hawtin
 
S

Stefan Ram

Thomas Hawtin said:
Looks like a bug to me. Documentation reads:

Thanks for your thoughts and quotations!

I still have a lot to learn about interfaces. For example,
without trying, I would not be able to predict the behavior
for:

interface A { java.lang.Object f(); }
interface B { java.lang.Object f(); }
interface C extends B, A {}
class D implements C
{ public java.lang.Object f(){ return null; }}

public class Main
{ public static void main( final java.lang.String[] args )
{ java.lang.reflect.Method[] methods = C.class.getMethods();
java.lang.System.out.println( methods.length );
for( java.lang.reflect.Method method: methods )
java.lang.System.out.println( method ); }}

I would have guessed that "C extends B, A" would either be
illegal (»duplicate method error«) or would merge both »f« to
a single method. But instead both »f« are retained as the
output of »main« shows.

Then, I would believe, that it was not possible to implement
such an interface with two equal methods. However the compiler
accepts my declaration of »D«. So now, the two methods are
somewhat »merged« indeed.
 
S

Stefan Ram

interface A { java.lang.Object f(); }
interface B { java.lang.Object f(); }
interface C extends B, A {}
I would have guessed that "C extends B, A" would either be
illegal (»duplicate method error«) or would merge both »f« to
a single method. But instead both »f« are retained as the
output of »main« shows.

OK, I now see that the compiler does not actually create a new
list of members for the interface »C« but essentially it keeps
a list of direct parent interfaces (»A« and »B«), so that it
can not »merge« anything. However, eventually, when the
interface »C« is used, the compiler behaves as if both methods
would have been merged to a single method.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,997
Messages
2,570,241
Members
46,832
Latest member
UtaHetrick

Latest Threads

Top