How know if a method is part of an interface?

A

Andrea Polci

I have a class named MyClass implementing an interface named MyInterface.

I have also an instance of java.lang.reflect.Method describing a method
of MyClass (is the parameter of the invoke method in an
java.lang.reflect.InvocationHandler).
I need to know if Method is part of MyInterface or not.
Is there a way other than checking the method name and parameters type?

Thanks,
Andrea
 
O

Oscar kind

Andrea Polci said:
I have a class named MyClass implementing an interface named MyInterface.

I have also an instance of java.lang.reflect.Method describing a method
of MyClass (is the parameter of the invoke method in an
java.lang.reflect.InvocationHandler).
I need to know if Method is part of MyInterface or not.
Is there a way other than checking the method name and parameters type?

See Method.getDeclaringClass(), which gives you the class (or interface)
that declared (as opposed to implemented) the method.
 
A

Andrea Polci

Oscar said:
See Method.getDeclaringClass(), which gives you the class (or interface)
that declared (as opposed to implemented) the method.

No, aMethod.getDeclaringClass() give me MyClass.class even if aMethod is
declared into MyInterface.

Andrea
 
P

P.Hill

Can you tell us why? People do the wierdest things with reflection
and I'm wondering why you'd want to know. As part of some IDE plugin or ANT
tool it sounds great, but otherwise it sounds a bit odd.

-Paul
 
S

Sudsy

Andrea Polci wrote:
No, aMethod.getDeclaringClass() give me MyClass.class even if aMethod is
declared into MyInterface.

So did you check out the Class#isAssignableFrom( Class ) method? I don't
have time to try it myself...but then I don't have the problem! ;-)
 
C

Chris Uppal

Andrea said:
I need to know if Method is part of MyInterface or not.
Is there a way other than checking the method name and parameters type?

No. You have to test the name/parameters yourself.

-- chris
 
A

Andrea Polci

Sudsy said:
Andrea Polci wrote:



So did you check out the Class#isAssignableFrom( Class ) method? I don't
have time to try it myself...but then I don't have the problem! ;-)

It doesn't help. Consider this:

public interface AInterface {
void methodA();
}

public interface BInterface {
void methodB();
}

public class MyClass {
void methodA() { ... }
void methodB() { ... }
}

If aMethod is the instance of java.lang.reflect.Method that represent
methodA we have:

aMethod.getDeclaringClass().equals(MyClass.class);

BInterface.isAssignableFromb(aMethod.getDeclaringClass()) == true;
AInterface.isAssignableFromb(aMethod.getDeclaringClass()) == true;

So we can't say if aMethod is declared in AInterface or BInterface.

Andrea
 
A

Andrea Polci

P.Hill said:
Can you tell us why? People do the wierdest things with reflection
and I'm wondering why you'd want to know. As part of some IDE plugin or
ANT
tool it sounds great, but otherwise it sounds a bit odd.

I'll try but it isn't easy in english for me.

I have many classes each exposing some properties (getter/setter
methods) and other methods, some of wich defined in a common interface.
Now I want to attach some common functionality to those properties and
common methods (for example user's permission checking, but not only) so
I have defined a class like this:

public class PermissionChecker {
private Object aObject;

public PermissionChecker(Object obj) {
this.aObject = obj;
}

public vodi setProperty(String propertyName, Object value) {
// Do the permission checking
// ...

PropertyUtils.setProperty(aObject, propertyName, value);
}

public Object getProperty(String propertyName) {
// ...
}

public void doSomething() {
// ...
}
}

I don't know if this is a good solution, but it is the solution we
adopted and I can't change it easily. Consider that usually we accessed
the properties throw reflection and there were few places were we do this.

The problem is that in some code I need to get the functionality of the
PermissionChecker without knowing of it. In that code I access the
object throw some interfaces (implemented by the original class) that
define the properties and the other methods.

I think I can do this with the java.lang.Proxy class.
Consider this code:

public interface MyPropertiesInterface {
public void setName(String name);
public String getName();
}

public interface MyCommonInterface {
public void doSomething();
}

public interface MyInterface
extends MyPropertiesInterface, MyCommonInterface{
}

public class MyClass implements MyInterface { ... }


....
{
MyInterface anObject = ....;
PermissionChecker pcheck = new PermissionChecker(anObject)
invHand = new MyInvocationHandler(pcheck);
MyInterface checkedObject = (MyInterface)Proxy.newProxyInstance(
loader,
new Class[]{ MyInterface.class },
invHand);

// Use the checked object as it was anObject
}


public class MyInvocationHandler
implements java.lang.reflect.InvocationHandler {

PermissionChecker pcheck;
Object anObject;

public MyInvocationHandler(PermissionChecker checker, Object obj) {
pckeck = checker;
anObject = obj;
}

public Object invoke(Object proxy, Method method, Object[] args) {
if(/* method is a property setter, I know how to do */){
// ...
String propertyName = ...;
pckeck.setProperty(propertyName, args[0]);
return null;
}
if(/* method is a property getter, I know how to do */) {
// ...
String propertyName = ...;
return pckeck.getProperty(propertyName);
}
if(/*method belongs to MyCommonInterface, I DON'T KNOW HOW TO DO*/){
// do something special :)
return ...;
}

method.invoke(anObject, args);
}
}


The problem is in the invoke method. I have to know if the method
belogns to MyMethodsInterface, but I don't know how to do (other than
manually compare the method name and the arguments classes).

Any suggestion?

Andrea Polci
 
C

Chris Smith

Andrea,

interface A
{
public void someMethod();
}

interface B
{
public void someMethod();
}

class C implements A, B
{
public void someMethod() { }
}

So what do you want as an answer, if you ask where C.someMethod is
declared?

--
www.designacourse.com
The Easiest Way to Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
A

Andrea Polci

Chris said:
Andrea,

interface A
{
public void someMethod();
}

interface B
{
public void someMethod();
}

class C implements A, B
{
public void someMethod() { }
}

So what do you want as an answer, if you ask where C.someMethod is
declared?

I don't want to know where C.someMethod is declared.

I want to know: is C.someMethod part of interface A?
The answer is "yes".

Andrea
 
S

Stefan Ram

Andrea Polci said:
I want to know: is C.someMethod part of interface A?
The answer is "yes".

Usually, this would be done at compile time:

(((A)(new C())).someMethod())

If this fails to compile, its not part of the interface.

Actually the whole reason of interfaces in Java is to support
these compile time checks in order to avoid failure during the
execution. Otherwise, the situation would be more like in
Smalltalk, where AFAIK such interfaces do not exist.

(If you want to check it at run time: This should not be
neccessary. But if you dynamically compile code at run time
without human intervention, then you might need this, if the
Java-Code was also generated at run time. In this case the
error messages from the compilation might be inspected.)
 
G

Guest

Andrea said:
I have a class named MyClass implementing an interface named MyInterface.

I have also an instance of java.lang.reflect.Method describing a method
of MyClass (is the parameter of the invoke method in an
java.lang.reflect.InvocationHandler).
I need to know if Method is part of MyInterface or not.
Is there a way other than checking the method name and parameters type?

As chris said: You have to test the name/parameters yourself.

Here a simple code fragment:

private static boolean sameSignature(Method a, Method b) {
Class[]ac = a.getParameterTypes();
Class[]bc = b.getParameterTypes();
if(ac.length != bc.length)
return false;
for(int i=0; i<ac.length; i++)
if(ac != bc)
return false;
return true;
}
public static boolean methodInInterface(Method m, Class ifc) {
if(!ifc.isInterface())
return false;
Method[]ifcm = ifc.getDeclaredMethods();
for(int i=0; i<ifcm.length; i++)
if(m.getName().equals(ifcm.getName()))
return sameSignature(m, ifcm) &&
ifcm.getReturnType().isAssignableFrom(m.getReturnType());
return false;
}

You can invoke methodInInterface to test if m is part of ifc interface.

- Dario
 

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,755
Messages
2,569,536
Members
45,016
Latest member
TatianaCha

Latest Threads

Top