15

I have a generic interface and a class implementing it:

import java.util.Arrays;

interface Interface<T> {
    void doSomething(T element);
}

class StringImpl implements Interface<String> {
    @Override
    public void doSomething(String element) {
        System.out.println("StringImpl: doSomething");
    }
}

public class Main {
    public static void main(String... args) {
        System.out.println(Arrays.toString(StringImpl.class.getDeclaredMethods()));
    }
}

And the result is

[public void com.ra.StringImpl.doSomething(java.lang.String), 
public void com.ra.StringImpl.doSomething(java.lang.Object)]

But in fact, I just want the implementing version:

public void com.ra.StringImpl.doSomething(java.lang.String)

Do you have any convient way to achieve it?

Andrew Tobilko
  • 48,120
  • 14
  • 91
  • 142
Ukonn Ra
  • 744
  • 6
  • 20

1 Answers1

27

Filter out bridge methods:

Method[] methods = Arrays.stream(StringImpl.class.getDeclaredMethods())
                         .filter(m -> !m.isBridge())
                         .toArray(Method[]::new);
Andrew Tobilko
  • 48,120
  • 14
  • 91
  • 142
  • 4
    Was about to answer with `!m.isSynthetic` but this is better. – Mena May 14 '18 at 14:11
  • 2
    @Mena yes this is better, not all synthetic methods are bridge – Eugene May 14 '18 at 14:23
  • 1
    @Andrew btw there are only two places where the compiler will create bridge methods - covariant return types and generics – Eugene May 14 '18 at 14:24
  • 1
    @Andrew I have checked the `modifiers` of the method in interface (and abstract class), which is 0x1041 => [synthetic, volatile, public]. But in my opinion, 0x1401 => [synthetic, abstract, public] is better. So I want to know why is `volatile` rather than `abstract`... – Ukonn Ra May 14 '18 at 14:29
  • 1
    @UkonnRa `volatile` method? – Eugene May 14 '18 at 14:30
  • 2
    @Eugene In fact, which means `Bridge`. `Bridge` and `Volatile` are both 0x40... I got it! – Ukonn Ra May 14 '18 at 14:33