Java反射API为何返回两个feed方法?附代码示例
问题:Java反射API为何返回两个feed方法?
我定义了如下泛型接口:
import java.util.List; public interface Species<T> { T feed(List<String> numList); }
Animal类是Species接口的实现类:
import lombok.Data; import java.util.List; @Data public class Animal<T> implements Species<T> { private T t; @Override public T feed(List<String> numList) { return t; } }
Dog类继承自Animal类:
import java.util.List; public class Dog extends Animal<String>{ @Override public String feed(List<String> numList) { return "dog feed method"; } }
测试类代码:
public class TypeTest { public static void main(String[] args) { Class<Dog> dogClass = Dog.class; Method[] declaredMethods = dogClass.getDeclaredMethods(); for(Method m:declaredMethods){ System.out.println(m.getReturnType().getName()); } } }
运行输出:
java.lang.String java.lang.Object
查看declaredMethods变量时发现存在两个feed方法,请问这是为什么?
原因解析
这是泛型类型擦除和Java编译器生成**桥接方法(Bridge Method)**导致的结果:
泛型类型擦除机制:Java泛型是编译时特性,编译后泛型信息会被擦除。父类
Animal<T>的feed方法,编译后泛型返回类型会被擦除为Object,实际等同于:public Object feed(List numList) { return t; }桥接方法的生成:当
Dog继承Animal<String>并覆写feed方法时,你实现的是返回String的版本,但为了保证多态机制正常工作(比如把Dog向上转型为Animal/Species时,调用feed能正确命中Dog的实现),编译器会自动在Dog类中生成一个桥接方法:public Object feed(List numList) { return feed((List<String>) numList); }这个桥接方法返回
Object,内部直接调用你自定义的返回String的feed方法。反射的可见性:
getDeclaredMethods()会返回当前类所有声明的方法,包括编译器自动生成的桥接方法,所以你会看到两个feed方法。
如果只想获取自定义的方法,可以通过Method.isBridge()过滤桥接方法:
public class TypeTest { public static void main(String[] args) { Class<Dog> dogClass = Dog.class; Method[] declaredMethods = dogClass.getDeclaredMethods(); for(Method m:declaredMethods){ if(!m.isBridge()){ System.out.println(m.getReturnType().getName()); } } } }
此时输出只会显示java.lang.String。
内容的提问来源于stack exchange,提问作者nonoy
相关产品推荐
相关产品推荐

