Kotlin:不能使用GenericTypeIndicator调用Firebase数据库的getValue

当使用Kotlin处理Firebase数据库时,如果我使用GenericTypeIndicator ,我似乎无法检索List<String>类型的值,如下所示:

 snap.getValue(object : GenericTypeIndicator<List<String>>() {}) 

它从Firebase SDK中产生一个例外如下:

 com.google.firebase.database.DatabaseException: Generic wildcard types are not supported at com.google.android.gms.internal.zzbtg.zza(Unknown Source) at com.google.android.gms.internal.zzbtg.zza(Unknown Source) at com.google.android.gms.internal.zzbtg.zza(Unknown Source) at com.google.android.gms.internal.zzbtg.zza(Unknown Source) at com.google.firebase.database.DataSnapshot.getValue(Unknown Source) 

但是,如果我从Java调用它,如下所示:

 snap.getValue(new GenericTypeIndicator<List<String>>() {}) 

我猜测它与类型通用有关,所以我这样做了:

 inline fun <reified T> genericType() = object: GenericTypeIndicator<T>() {} val stringListIndicator = genericType<List<String>>() snap.getValue(stringListIndicator) 

但同样的例外发生。

为什么这样?


编辑:我试图使用jadx-0.6.1反编译Java和Kotlin版本。

Java源码:

 public class Randommmm { private static final GenericTypeIndicator<List<String>> ti = new GenericTypeIndicator<List<String>>() { }; public static List<String> x(DataSnapshot snap) { return snap.getValue(ti); } } 

反编译:

 public class Randommmm { private static final GenericTypeIndicator<List<String>> ti = new C12761(); static class C12761 extends GenericTypeIndicator<List<String>> { C12761() { } } public static List<String> m48x(DataSnapshot snap) { return (List) snap.getValue(ti); } } 

Kotlin来源(1):

 object Randommmm { private val ti = object : GenericTypeIndicator<List<String>>() { } fun x(snap: DataSnapshot): List<String> { return snap.getValue(ti) } } 

反编译:

 public final class Randommmm { public static final Randommmm INSTANCE = null; private static final Randommmm$ti$1 ti = null; static class C12761 extends GenericTypeIndicator<List<String>> { C12761() { } } static { Randommmm randommmm = new Randommmm(); } private Randommmm() { INSTANCE = this; ti = new Randommmm$ti$1(); } @NotNull public final List<String> m48x(@NotNull DataSnapshot snap) { Intrinsics.checkParameterIsNotNull(snap, "snap"); Object value = snap.getValue(ti); Intrinsics.checkExpressionValueIsNotNull(value, "snap.getValue(ti)"); return (List) value; } } public final class Randommmm$ti$1 extends GenericTypeIndicator<List<? extends String>> { Randommmm$ti$1() { } } 

(2)使用ArrayList所建议的ArrayList

 object Randommmm { private val ti = object : GenericTypeIndicator<ArrayList<String>>() { } fun x(snap: DataSnapshot): List<String> { return snap.getValue(ti) } } 

反编译:

 public final class Randommmm { public static final Randommmm INSTANCE = null; private static final Randommmm$ti$1 ti = null; static class C12761 extends GenericTypeIndicator<List<String>> { C12761() { } } static { Randommmm randommmm = new Randommmm(); } private Randommmm() { INSTANCE = this; ti = new Randommmm$ti$1(); } @NotNull public final List<String> m48x(@NotNull DataSnapshot snap) { Intrinsics.checkParameterIsNotNull(snap, "snap"); Object value = snap.getValue(ti); Intrinsics.checkExpressionValueIsNotNull(value, "snap.getValue(ti)"); return (List) value; } } public final class Randommmm$ti$1 extends GenericTypeIndicator<ArrayList<String>> { Randommmm$ti$1() { } } 

在Kotlin,

 val ti = object : GenericTypeIndicator<List<String>>() {} 

生成为(在Java中):

 SyntethicClass ti = new SyntethicClass(); public final class SyntethicClass extends GenericTypeIndicator<List<? extends String>> {} 

注意通配符? extends String ? extends String而不是简单的String

有关说明,请参阅https://kotlinlang.org/docs/reference/java-to-kotlin-interop.html#variant-generics

为了防止这种情况,使用@JvmSuppressWildcards注释类型参数:

 val ti = object : GenericTypeIndicator<List<@JvmSuppressWildcards String>>() {} 

这变得超级丑陋,但它的作品。 或者,根据Doug的回答使用ArrayList

尝试改变这一行:

 snap.getValue(object : GenericTypeIndicator<List<String>>() {}) 

对此:

 snap.getValue(object : GenericTypeIndicator<ArrayList<String>>() {}) 

它适用于我,但我不知道为什么。