4 Replies Latest reply: Dec 17, 2009 11:00 AM by 843798 RSS

    need help in reflection and getDeclaredMethods()

    843798
      I have this layout of classes:
      interface I1 {
      public I1 f( Object c1 ) {
      }
      }
      public interface I2 extends I 1 {
      @HW4Method
      public I2 f( Object c1 ) { }
      }
      class C2 implements I1 {
      @HW4Method
      public C2 f( Object o ) { }
      }
      @HW4Class
      class C3 extends C2 implements I2 {
      public C3 f( Object o ) { }
      }
      When invoking:
      System.out.println(C3.class.getDeclaredMethods().length);
      I get output: 4
      I tried to check who are those 4 methods in this array by printing their return values and got I1,I2,C2,C3

      Now, when changing all f's return value to "Object" I seem to get output: 1


      What I want to do is given a class, get ONLY its own declared methods. In the case above I want to get only C3::f.
      Any suggestions guys?

      Thanks!!
        • 1. Re: need help in reflection and getDeclaredMethods()
          EJP
          When invoking:
          System.out.println(C3.class.getDeclaredMethods().length);
          I get output: 4
          I get four compile errors. It would help if you posted the actual code. When I fix that I get this:
          public volatile GetDeclaredMethods$C2 GetDeclaredMethods$C3.f(java.lang.Object)
          public volatile GetDeclaredMethods$I1 GetDeclaredMethods$C3.f(java.lang.Object)
          public volatile GetDeclaredMethods$I2 GetDeclaredMethods$C3.f(java.lang.Object)
          public GetDeclaredMethods$C3 GetDeclaredMethods$C3.f(java.lang.Object)
          of which the 'volatile' ones are compiler-generated thunks, because you've changed the return types from I1/I2 to C1/C2. Which is perflectly legitimate (covariant return types) but it needs an implementation. The last one is the actual method you declared in C3.
          Now, when changing all f's return value to "Object" I seem to get output: 1
          That would be because there is only one method in that case, which the successive derived classes override, and no thunks are required.
          What I want to do is given a class, get ONLY its own declared methods. In the case above I want to get only C3::f.
          Class.getDeclaredMethods() is supposed to do precisely that: 'Returns an array of Method objects reflecting all the methods declared by the class or interface represented by this Class object. This includes public, protected, default (package) access, and private methods, but excludes inherited methods.'

          If you get rid of all the overloading and covariance you will get what you want, but you probably don't really want that.
          • 2. Re: need help in reflection and getDeclaredMethods()
            843798
            Thanks ejp!

            this is the workaround that works:
            public static Set<Method> getDeclaredMethodFor(Class<?> aClass)
                 {
                      Set<Method> set = new HashSet<Method>();
                      for(Method m: aClass.getDeclaredMethods())
                      {
                           try
                           {
                                set.add(aClass.getDeclaredMethod(m.getName(), m.getParameterTypes()));
                           }
                           catch (NoSuchMethodException e) {}
                      }
                      return set;
                 }
            Edited by: adam678 on Dec 17, 2009 2:23 AM
            • 3. Re: need help in reflection and getDeclaredMethods()
              EJP
              You seem to be be relying on getDeclaredMethod() returning exactly the method you want, given the method name and argument types.

              Can you really rely on that?

              I would change the return types from C1/C2 to I1/I2 for a start, and re-examine the need for covariant return types too.
              • 4. Re: need help in reflection and getDeclaredMethods()
                843798
                Yeah, I tested it and it works. I think the reason is that getDeclaredMethod(name,args) will return the actual method that given this signature (name,args), will be invoked when called, otherwise, we will get cases in which for example, In a program that uses reflection, an inappropriate method will be dynamically invoked...