用两个词:类型擦除。
泛型是一把双刃剑,它削减了类型系统的一些运行时功能,以换取编译时检查。您是在告诉编译器重写代码以使这些类型转换“正常工作”。权衡是它必须将像“T”这样的通用类引用变成“Object”。所以编译后你的方法的签名是
Object convertMyClass(MyClass)
数据绑定系统正在寻找返回类型“String”。所以甚至不考虑你的方法。
数据绑定系统可能会变得更智能,以便能够识别您的 BindingConversion,但我不会为那个功能屏住呼吸。
这是一些说明类型擦除的bash。
$ echo 'public class A{ public <T> T deRef(java.util.concurrent.atomic.AtomicReference<T> atom) {return atom.get();} }' >A.java
$ javac A.java
$ groovy -e 'println A.class.getMethod("deRef", java.util.concurrent.atomic.AtomicReference.class)'
public java.lang.Object A.deRef(java.util.concurrent.atomic.AtomicReference)
最后一行输出是泛型方法的方法签名。
一种解决方法是使用特定的参数化子类对 MyClass 进行子类化,如下所示:
public class MyStringClass extends MyClass<String> {
@Override
public String get() {
return super.get();
}
@BindingConversion
public static String convertMyClass(MyStringClass obj) {
return obj.get();
}
}
关于ObservableField,它不需要 BindingConversion 机制,因为数据绑定库在 java 代码中引用它,因此编译时泛型检查可以完成匹配类型的工作。