Kotlin:无法使用 GenericTypeIndicator 调用 Firebase 数据库的 getValue
Kotlin: Can't use GenericTypeIndicator to call Firebase Database's 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 ti = null;
static class C12761 extends GenericTypeIndicator<List<String>> {
C12761() {
}
}
static {
Randommmm randommmm = new Randommmm();
}
private Randommmm() {
INSTANCE = this;
ti = new Randommmm$ti();
}
@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 extends GenericTypeIndicator<List<? extends String>> {
Randommmm$ti() {
}
}
Kotlin 源代码 (2) 使用 ArrayList
,如 Doug 所建议:
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 ti = null;
static class C12761 extends GenericTypeIndicator<List<String>> {
C12761() {
}
}
static {
Randommmm randommmm = new Randommmm();
}
private Randommmm() {
INSTANCE = this;
ti = new Randommmm$ti();
}
@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 extends GenericTypeIndicator<ArrayList<String>> {
Randommmm$ti() {
}
}
尝试更改此行:
snap.getValue(object : GenericTypeIndicator<List<String>>() {})
为此:
snap.getValue(object : GenericTypeIndicator<ArrayList<String>>() {})
它对我有用,但我不知道为什么。
在 Kotlin 中,
val ti = object : GenericTypeIndicator<List<String>>() {}
生成为(在 Java 中):
SyntethicClass ti = new SyntethicClass();
public final class SyntethicClass extends GenericTypeIndicator<List<? 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>>() {}
这变得非常丑陋,但它确实有效。或者,根据 .
使用 ArrayList
当使用 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 ti = null;
static class C12761 extends GenericTypeIndicator<List<String>> {
C12761() {
}
}
static {
Randommmm randommmm = new Randommmm();
}
private Randommmm() {
INSTANCE = this;
ti = new Randommmm$ti();
}
@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 extends GenericTypeIndicator<List<? extends String>> {
Randommmm$ti() {
}
}
Kotlin 源代码 (2) 使用 ArrayList
,如 Doug 所建议:
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 ti = null;
static class C12761 extends GenericTypeIndicator<List<String>> {
C12761() {
}
}
static {
Randommmm randommmm = new Randommmm();
}
private Randommmm() {
INSTANCE = this;
ti = new Randommmm$ti();
}
@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 extends GenericTypeIndicator<ArrayList<String>> {
Randommmm$ti() {
}
}
尝试更改此行:
snap.getValue(object : GenericTypeIndicator<List<String>>() {})
为此:
snap.getValue(object : GenericTypeIndicator<ArrayList<String>>() {})
它对我有用,但我不知道为什么。
在 Kotlin 中,
val ti = object : GenericTypeIndicator<List<String>>() {}
生成为(在 Java 中):
SyntethicClass ti = new SyntethicClass();
public final class SyntethicClass extends GenericTypeIndicator<List<? 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>>() {}
这变得非常丑陋,但它确实有效。或者,根据
ArrayList