通用@BindingConversion 不起作用
Generic @BindingConversion doesn't work
为什么无法在 android 数据绑定库中定义通用绑定转换?
@BindingConversion
public static <T> T convertMyClass(MyClass<T> obj) {
return obj.get();
}
使用此方法时出现 can not find the setter for attribute 'android:text' with parameter type com.example.MyClass<java.lang.String>
错误。定义显式类型没问题。
我试图找到 ObservableField<T>
转换的方式,但没有成功。有谁知道这是怎么回事?我做错了什么吗?
两个词:type erasure.
泛型是一把双刃剑,它切断了类型系统的一些 运行 时间能力,以换取编译时检查。您告诉编译器重写代码以进行这些类型转换 "just work." 代价是它必须将通用 class 引用(如 "T" 转换为 "Object"。所以编译后你的方法的签名是
Object convertMyClass(MyClass)
数据绑定系统正在寻找 return 类型 "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)
最后一行输出是泛型方法的方法签名。
一种变通方法是使用特定参数化子class 子class 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 代码中引用它,因此编译时泛型检查会完成匹配类型的工作向上。
为什么无法在 android 数据绑定库中定义通用绑定转换?
@BindingConversion
public static <T> T convertMyClass(MyClass<T> obj) {
return obj.get();
}
使用此方法时出现 can not find the setter for attribute 'android:text' with parameter type com.example.MyClass<java.lang.String>
错误。定义显式类型没问题。
我试图找到 ObservableField<T>
转换的方式,但没有成功。有谁知道这是怎么回事?我做错了什么吗?
两个词:type erasure.
泛型是一把双刃剑,它切断了类型系统的一些 运行 时间能力,以换取编译时检查。您告诉编译器重写代码以进行这些类型转换 "just work." 代价是它必须将通用 class 引用(如 "T" 转换为 "Object"。所以编译后你的方法的签名是
Object convertMyClass(MyClass)
数据绑定系统正在寻找 return 类型 "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)
最后一行输出是泛型方法的方法签名。
一种变通方法是使用特定参数化子class 子class 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 代码中引用它,因此编译时泛型检查会完成匹配类型的工作向上。