Java getMethods()返回方法I';t在实现通用接口时定义
一个简单的界面:Java getMethods()返回方法I';t在实现通用接口时定义,java,reflection,interface,Java,Reflection,Interface,一个简单的界面: interface Foo { void myMethod(String arg); } class FooImpl implements Foo { void myMethod(String arg){} public static void main(String[] args) { Class cls = FooImpl.class; try { for (Method method : cls.getMetho
interface Foo {
void myMethod(String arg);
}
class FooImpl implements Foo {
void myMethod(String arg){}
public static void main(String[] args) {
Class cls = FooImpl.class;
try {
for (Method method : cls.getMethods()) {
System.out.print(method.getName() + "\t");
for(Class paramCls : method.getParameterTypes()){
System.out.print(paramCls.getName() + ",");
}
System.out.println();
}
} catch (SecurityException e) {
// TODO Auto-generated catch block
}
}
}
产出将是:
myMethod java.lang.String,
...//Other Method
只打印一个myMethod
但如果我将接口更改为通用接口:
interface Foo<T> {
void myMethod(T arg);
}
class FooImpl implements Foo<String> {
void myMethod(String arg){}
}
为什么在将接口更改为泛型接口后,会产生另一个带有参数类型对象的方法?第一个方法是由编译器创建的。
如果为“”测试方法,则可以过滤掉“错误”的方法(还可以过滤掉协方差返回的一些奇怪结果)
以下代码不会打印myMethod java.lang.Object
:
import java.lang.reflect.Method;
public class FooImpl implements Foo<String> {
public void myMethod(String arg) {
}
public static void main(String[] args) throws Exception {
Class cls = FooImpl.class;
for (Method method : cls.getMethods()) {
if (!method.isBridge()) {
System.out.print(method.getName() + "\t");
for (Class paramCls : method.getParameterTypes()) {
System.out.print(paramCls.getName() + ",");
}
}
System.out.println();
}
}
}
interface Foo<T> {
public void myMethod(T arg);
}
import java.lang.reflect.Method;
公共类FooImpl实现Foo{
公共void myMethod(字符串arg){
}
公共静态void main(字符串[]args)引发异常{
类cls=FooImpl.Class;
for(方法:cls.getMethods()){
如果(!method.isBridge()){
System.out.print(方法.getName()+“\t”);
对于(类paramCls:method.getParameterTypes()){
System.out.print(paramCls.getName()+“,”);
}
}
System.out.println();
}
}
}
接口Foo{
公共无效方法(T参数);
}
更新:
引用博客:
Java中的桥接方法是合成方法,这对于
实现一些Java语言特性。最著名的样本是
协变返回类型和泛型中删除基时的一种情况
方法的参数与被调用的实际方法不同
更新上述博客中的代码:
public class SampleTwo {
public static class A<T> {
public T getT(T args) {
return args;
}
}
public static class B extends A<String> {
public String getT(String args) {
return args;
}
}
}
桥方法重写基类“A”中的方法,而不是
仅使用字符串参数(#3)调用一个,但也执行类型转换
转换为“java.lang.String”(#2)。这意味着,如果你执行
在下面的代码中,忽略编译器的“unchecked”警告,结果
将从桥接方法引发ClassCastException:
现在了解“什么是桥接方法”。阅读本教程,它解释了所有内容:
try {
for (Method method : cls.getMethods()) {
//these methods are called bridge methods
if(!method.isBridge()){
System.out.print(method.getName() + "\t");
for(Class paramCls : method.getParameterTypes()){
System.out.print(paramCls.getName() + ",");
}
System.out.println();
}
}
} catch (SecurityException e) {
// TODO Auto-generated catch block
}
public class SampleTwo {
public static class A<T> {
public T getT(T args) {
return args;
}
}
public static class B extends A<String> {
public String getT(String args) {
return args;
}
}
}
public SampleThree$B();
...
public java.lang.String getT(java.lang.String);
Code:
0: aload_1
1: areturn
public java.lang.Object getT(java.lang.Object);
Code:
0: aload_0
1: aload_1
2: checkcast #2; //class java/lang/String
5: invokevirtual #3; //Method getT:(Ljava/lang/String;)Ljava/lang/String;
8: areturn
}
A a = new B();
a.getT(new Object()));