Android 泛型@BindingConversion不';行不通

Android 泛型@BindingConversion不';行不通,android,generics,android-databinding,Android,Generics,Android Databinding,为什么不能在android数据绑定库中定义通用绑定转换 @BindingConversion public static <T> T convertMyClass(MyClass<T> obj) { return obj.get(); } @BindingConversion 公共静态T convertMyClass(MyClass obj){ 返回obj.get(); } 使用此方法,我得到无法找到参数类型为com.example.MyClass的属性“an

为什么不能在android数据绑定库中定义通用绑定转换

@BindingConversion
public static <T> T convertMyClass(MyClass<T> obj) {
    return obj.get();
}
@BindingConversion
公共静态T convertMyClass(MyClass obj){
返回obj.get();
}
使用此方法,我得到
无法找到参数类型为com.example.MyClass的属性“android:text”的setter
错误。定义显式类型可以正常工作

我试图找到
observefield
转换的方法,但没有成功。有人知道这是怎么发生的吗?有什么我做错了吗?

用两个字来说:

泛型是一把双刃剑,它切断了类型系统的一些运行时功能,以换取编译时检查。您告诉编译器重写代码以使这些类型转换“正常工作”。权衡是,它必须将“T”之类的泛型类引用转换为“Object”。因此,编译后方法的签名是

Object convertMyClass(MyClass)
数据绑定系统正在寻找返回类型“String”。所以甚至不考虑你的方法。

数据绑定系统可能会变得更智能,能够识别您的绑定转换,但我不会对该功能屏住呼吸

下面是一些演示类型擦除的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)
$echo'公共类A{public T deRef(java.util.concurrent.atomic.AtomicReference 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.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();
  }
}
public类MyStringClass扩展了MyClass{
@凌驾
公共字符串get(){
返回super.get();
}
@绑定转换
公共静态字符串convertMyClass(MyStringClass obj){
返回obj.get();
}
}

关于这一点,它不需要BindingConversion机制,因为数据绑定库在java代码中引用了它,因此编译时泛型检查完成了匹配类型的工作。

您认为有什么解决方法可以解决这个问题吗?@Bolein95我用一个解决方法更新了它。这对你有用吗?没有。泛型消失了。不管怎样,你的回答解释了这个问题。似乎我必须向数据绑定社区报告这一点。很抱歉,我没有提到这一部分。如果java代码引用带有泛型参数的类型,则不需要转换,因为泛型提供了该检查。因此,数据绑定引用了ObservaleField,这意味着当您使用ObservaleField时,使用泛型进行编译时检查可以确保代码正常工作,并且库不需要为转换器内省类。我实际上还没有查看数据绑定源,但是如果您查看了,我保证数据绑定源中的类型变量只会与您对ObservaleField的使用一起工作。