Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Weird behavior - Class#getDeclaredMethods vs getMethods

I am aware of the fact that, Class#getDeclaredMethods returns declared methods of the class and Class#getMethods in additional contains the inherited methods. In short:

getDeclaredMethods is subset of getMethods

But how is the below output justified?

class A implements Comparator<Integer> {    
    public int compare(Integer o1, Integer o2) {
        return -1;
    }    
    private Object baz = "Hello";    
    private class Bar {
        private Bar() {
            System.out.println(baz);
        }
    }       
    Bar b = new Bar();    
}


for (Method m : claz.getDeclaredMethods()) {
    System.out.println(m.getName()+ " " + m.isSynthetic());
}

It prints:

access$1 synthetic(true)
compare synthetic(false)
compare synthetic(true)

For the below:

for (Method m : claz.getMethods()) {
    System.out.println(m.getName() + " synthetic(" + m.isSynthetic()+")" );
}

It prints:

compare synthetic(false)
compare synthetic(true)
...//removed others for brievity

When we try printing methods of A.class, apart from visible methods it contains 2 additional synthetic methods compare(Object, Object) (bridge method) and access$1 (for Bar to access elements of outer class Foo).

Both get printed in declaredMethods. But why doesn't getMethods print access$1?

like image 749
Jatin Avatar asked Sep 30 '22 17:09

Jatin


1 Answers

access$1 is not public - you can verify it by printing Modifier.isPublic(m.getModifiers()).

getMethods() only shows public methods:

Returns an array containing Method objects reflecting all the public member methods of the class [...]

like image 96
assylias Avatar answered Oct 03 '22 08:10

assylias