Skip to content

Commit

Permalink
优化 kotlin data class 默认值逻辑处理
Browse files Browse the repository at this point in the history
优化 Json 解析容错监听器的方法命名
  • Loading branch information
getActivity committed Dec 23, 2023
1 parent 20f012d commit 524a25c
Show file tree
Hide file tree
Showing 9 changed files with 62 additions and 22 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ android {
dependencies {
// Gson 解析容错:https://github.com/getActivity/GsonFactory
implementation 'com.github.getActivity:GsonFactory:9.2'
implementation 'com.github.getActivity:GsonFactory:9.3'
// Json 解析框架:https://github.com/google/gson
implementation 'com.google.code.gson:gson:2.10.1'
// Kotlin 反射库:用于反射 Kotlin data class 类对象
Expand Down
4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ android {
applicationId "com.hjq.gson.factory.demo"
minSdkVersion 16
targetSdkVersion 31
versionCode 920
versionName "9.2"
versionCode 930
versionName "9.3"
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package com.hjq.gson.factory.test

data class DataClassBean(
val name: String?,
val age: Int = 18,
val address: String?,
val birthday: Long = System.currentTimeMillis()
val name: String = "轮子哥",
val alias: String,
val address: String? = "",
val age: Int = 20,
val weight: Int,
val stature: Int? = 180,
)
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,12 @@ public void onParseObjectException(TypeToken<?> typeToken, String fieldName, Jso
}

@Override
public void onParseListException(TypeToken<?> typeToken, String fieldName, JsonToken listItemJsonToken) {
public void onParseListItemException(TypeToken<?> typeToken, String fieldName, JsonToken listItemJsonToken) {
handlerGsonParseException("解析 List 异常:" + typeToken + "#" + fieldName + ",后台返回的条目类型为:" + listItemJsonToken);
}

@Override
public void onParseMapException(TypeToken<?> typeToken, String fieldName, String mapItemKey, JsonToken mapItemJsonToken) {
public void onParseMapItemException(TypeToken<?> typeToken, String fieldName, String mapItemKey, JsonToken mapItemJsonToken) {
handlerGsonParseException("解析 Map 异常:" + typeToken + "#" + fieldName + ",mapItemKey = " + mapItemKey + ",后台返回的条目类型为:" + mapItemJsonToken);
}

Expand Down
4 changes: 2 additions & 2 deletions library/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ android {

defaultConfig {
minSdkVersion 12
versionCode 920
versionName "9.2"
versionCode 930
versionName "9.3"
}

// 使用 JDK 1.8
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,21 @@ public interface ParseExceptionCallback {
void onParseObjectException(TypeToken<?> typeToken, String fieldName, JsonToken jsonToken);

/**
* List 类型解析异常
* List item 类型解析异常
*
* @param typeToken 类型 Token
* @param fieldName 字段名称(可能为空)
* @param listItemJsonToken List 条目类型(可能为空)
*/
void onParseListException(TypeToken<?> typeToken, String fieldName, JsonToken listItemJsonToken);
void onParseListItemException(TypeToken<?> typeToken, String fieldName, JsonToken listItemJsonToken);

/**
* Map 类型解析异常
* Map item 类型解析异常
*
* @param typeToken 类型 Token
* @param fieldName 字段名称(可能为空)
* @param mapItemKey Map 集合中的 key 值,如果等于为 "null" 字符串,则证明后端返回了错误类型的 key 过来
* @param mapItemJsonToken Map 条目类型(可能为空)
*/
void onParseMapException(TypeToken<?> typeToken, String fieldName, String mapItemKey, JsonToken mapItemJsonToken);
void onParseMapItemException(TypeToken<?> typeToken, String fieldName, String mapItemKey, JsonToken mapItemJsonToken);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.hjq.gson.factory.constructor

import com.google.gson.internal.ObjectConstructor
import kotlin.reflect.KParameter
import kotlin.reflect.KType
import kotlin.reflect.full.primaryConstructor
import kotlin.reflect.jvm.isAccessible

Expand Down Expand Up @@ -33,11 +34,24 @@ class KotlinDataClassDefaultValueConstructor<T : Any>(private val rawType: Class
continue
}

when {
// 判断这个参数是不是可选的
constructor.parameters[i].isOptional -> fullInitialized = false
// 判断这个参数是否标记为空的
constructor.parameters[i].type.isMarkedNullable -> values[i] = null
val parameter = constructor.parameters[i]

// 判断这个参数是不是可选的
if (parameter.isOptional) {
fullInitialized = false
}

// 判断这个参数是否标记为空的
if (parameter.type.isMarkedNullable) {
values[i] = null
} else if (!parameter.isOptional) {
// 如果这个参数没有标记为可空的,并且没有携带默认值
// 就需要赋一个默认值给它,否则会实例化构造函数会出现崩溃
// java.lang.IllegalArgumentException: method XxxBean.<init> argument 3 has type int, got java.lang.Object
// 如果是基本数据类型就一定会出现崩溃,如果是对象的话,需要同时满足以下条件才会出现崩溃
// 1. 后台给这个参数返回 null 的情况下
// 2. 获取对象的时候,如果没有做判空,也会出现异常
values[i] = getTypeDefaultValue(parameter.type)
}
}

Expand All @@ -50,6 +64,30 @@ class KotlinDataClassDefaultValueConstructor<T : Any>(private val rawType: Class
return result as T
}

private fun getTypeDefaultValue(type: KType): Any? {
// "class kotlin.Int".endsWith("kotlin.Int")
if (String::class.toString().endsWith(type.toString())) {
return ""
} else if (Byte::class.toString().endsWith(type.toString())) {
return 0.toByte()
} else if (Short::class.toString().endsWith(type.toString())) {
return 0.toShort()
} else if (Int::class.toString().endsWith(type.toString())) {
return 0
} else if (Long::class.toString().endsWith(type.toString())) {
return 0L
} else if (Float::class.toString().endsWith(type.toString())) {
return 0.0f
} else if (Double::class.toString().endsWith(type.toString())) {
return 0.0
} else if (Char::class.toString().endsWith(type.toString())) {
return '\u0000'
} else if (Boolean::class.toString().endsWith(type.toString())) {
return false
}
return null
}

/** 一个简单的 Map,它使用参数索引而不是排序或哈希。 */
class IndexedParameterMap(
private val parameterKeys: List<KParameter>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public Collection<E> read(JsonReader in) throws IOException {
e.printStackTrace();
ParseExceptionCallback callback = GsonFactory.getParseExceptionCallback();
if (callback != null) {
callback.onParseListException(mTypeToken, mFieldName, itemJsonToken);
callback.onParseListItemException(mTypeToken, mFieldName, itemJsonToken);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ public Map<K, V> read(JsonReader in) throws IOException {
e.printStackTrace();
ParseExceptionCallback callback = GsonFactory.getParseExceptionCallback();
if (callback != null) {
callback.onParseMapException(mTypeToken, mFieldName, String.valueOf(key), itemJsonToken);
callback.onParseMapItemException(mTypeToken, mFieldName, String.valueOf(key), itemJsonToken);
}
}
}
Expand Down

0 comments on commit 524a25c

Please sign in to comment.