Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / First Aid / August 2006

Tip: Looking for answers? Try searching our database.

accessing subclasse methods and fields with introspection / reflection

Thread view: 
Samy - 02 Aug 2006 16:40 GMT
Hi everyone,

I am trying to implement a new functionality in a library with reflection.
Anyone with a piece of advice ?

The problem is that I am having a class with a lot of subclasses with
several levels in the subtree. I have factories that instanciates end
classes (leaves). Those subclasses each define their own methods and I would
like to be able to list all the methods for

let's have an example. D extends C which extends B which extends A
A <- B <- C <- D
Imagine that every class implements a process<ClassName> method (A
implements processA(), B processB(), ...)

Now I would like to have a A.listMyMethods() which would return all the
processA, processB, processC and processD (since they are all abstract
except D meaning that an instance of my classes would could not be something
else than D)

From my tests, when I instanciate a D object and invoke a
myDObject.getClass().getMethods() I have what I want. But what I really
would want is to call myDObject.listMyMethods(). So that the object itself
would tell me it's methods.

Thanks for having read so far :-)

ps: The number of subclasses prohibits overriding each subclass to define
the method. with a hierachy of super.listMyMethods().
Oliver Wong - 02 Aug 2006 18:29 GMT
> From my tests, when I instanciate a D object and invoke a
> myDObject.getClass().getMethods() I have what I want. But what I really
> would want is to call myDObject.listMyMethods(). So that the object itself
> would tell me it's methods.

public [whatever] listMyMethods() {
 return this.getClass().getMethods();
}

   - Oliver
Samy - 03 Aug 2006 09:20 GMT
No that will not work. I already tryied .

I need to put the method in class A and the way you do it, it will only
return me the methods declared in A but what I want are those declared in A
B C and D.

Thanks anyway

>> From my tests, when I instanciate a D object and invoke a
>> myDObject.getClass().getMethods() I have what I want. But what I really
[quoted text clipped - 7 lines]
>
>    - Oliver
Oliver Wong - 03 Aug 2006 15:28 GMT
[post re-ordered]

>>> From my tests, when I instanciate a D object and invoke a
>>> myDObject.getClass().getMethods() I have what I want. But what I really
[quoted text clipped - 13 lines]
>
> Thanks anyway

   It works for me.

<SSCCE>
import java.lang.reflect.Method;

abstract class A {
public void methodA() {

}

public Method[] getMethods() {
 return this.getClass().getMethods();
}
}

abstract class B extends A {
public void methodB() {

}
}

abstract class C extends B {
public void methodC() {

}
}

public class D extends C {
 public void methodD() {

 }

 public static void main(String[] args) {
  for (Method m : new D().getMethods()) {
   System.out.println(m);
  }
 }
}
</SSCCE>

   - Oliver
Samy - 04 Aug 2006 16:02 GMT
Ooops, my fault.
Well, the fault of the code hierarchy in fact. I found a way to fix it.
Thank you a lot for the example. I had to test it before I could believe it
worked with your code and not with mine ;-)

The problem was that some of the classes I had were simulating inheritance
with delegating calls to an internal field ('has a' relation) Here is the
skeleton of the structure I had:

////////////////////////////////////////////////
import java.lang.reflect.Method;

interface IA {
public String[] methodIA();
public void printMethods();
}

interface IB {
public String[] methodIB();
}

interface IC {
public String[] methodIC();
}

abstract class MandatoryLegacy {
public abstract void mMandatoryLegacy();
}

/** this class is the only one really implementing IA*/
class AA implements IA {
public String[] methodIA(){return null;}
public void printMethods() {
 Method[] lMethods = getClass().getMethods();
 for (int i=0; i<lMethods.length; i++) {
  System.out.println("- " + lMethods[i].getName());
 }
}
}

/** Here is the *fake* implementation of IA */
abstract class A extends MandatoryLegacy implements IA {
AA mAA = new AA();
public void mMandatoryLegacy() {}
public String[] methodIA() {return mAA.methodIA();}
public void printMethods() {mAA.printMethods();}
}

abstract class B extends A implements IB {
public String[] methodIB() {return null;}
}

class C extends B implements IC {
public String[] methodIC() {return null;}
}

public class testReflect {
public static void main(String[] args) {
 C mC = new C();
 mC.printMethods();
}
}

////////////////////////////////////////////////

It outputs:
////////////////////////////////////////////////
- *printMethods*
- *methodIA*
- hashCode
- getClass
- wait
- wait
- wait
- equals
- notify
- notifyAll
- toString
////////////////////////////////////////////////

See, all the methods IB, IC etc. are missing. Anyway, my problem is now
solved. Thank you

The fix was to add a 'specialPrintMethods(Class iClass)' method to AA and
use it in A So A becomes:

abstract class A extends MandatoryLegacy implements IA {
AA mAA = new AA();
public void mMandatoryLegacy() {}
public String[] methodIA() {return mAA.specialPrintMethods(getClass());}
public void printMethods() {mAA.printMethods();}
}
Remi Arntzen - 02 Aug 2006 19:32 GMT
> Hi everyone,
>
> Now I would like to have a A.listMyMethods() which would return all the
> processA, processB, processC and processD (since they are all abstract
> except D meaning that an instance of my classes would could not be something
> else than D)

I took a quick look at the java.lang.Class documentation and couldn't
find a way to find a way to determin it's subclasses.

> From my tests, when I instanciate a D object and invoke a
> myDObject.getClass().getMethods() I have what I want. But what I really
> would want is to call myDObject.listMyMethods(). So that the object itself
> would tell me it's methods.

java.lang.reflect.Proxy.newProxyInstance(D.getClass().getClassLoader(),
blah, k);

where k = new InvocationHandler() {
       Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
           if (method.getName() == "listMyMethods") {
               return proxy.getClass().getMethods();
           } else {
               return method.invoke(proxy, args);
           }
       }
}

pragmatically override any method. muhahahaaaa!
also note that I haven't actually used this method in a while, so my
understanding of it might not be completely accurate/(work at all).
Samy - 03 Aug 2006 09:22 GMT
I didn't know of that proxy class. I will check in that area. Thank you

>> Hi everyone,
>>
[quoted text clipped - 30 lines]
> also note that I haven't actually used this method in a while, so my
> understanding of it might not be completely accurate/(work at all).
Samy - 03 Aug 2006 10:40 GMT
hmm, it happens that I can't use it that straight forward. The way you call
it you make a reference to class D. which I can't do when i am in class A.

The main problem is : 'Can an object know it's instanciation type?'.
From a purely object point of view it is impossible. An object doesn't have
to know anything from it's derived objects. This is just impossible.
But if it can't be done by the object by it's own resources, maybe it can be
achieved from the external. If the JVM could be asked by an object what it's
instanciation class is, it would solve my problem. But I have no idea of how
to do it ;-(

Does anyone have a clue ?

>I didn't know of that proxy class. I will check in that area. Thank you
>
[quoted text clipped - 32 lines]
>> also note that I haven't actually used this method in a while, so my
>> understanding of it might not be completely accurate/(work at all).


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.