From becfc7f16e8f04b9d7535350e8792a9268624e66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BD=AE=E5=AD=90=E5=93=A5?= Date: Sat, 25 Nov 2023 23:05:42 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=20Kotlin=20data=20class=20?= =?UTF-8?q?=E5=AE=9E=E4=BE=8B=E5=8C=96=E7=9A=84=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...otlinDataClassDefaultValueConstructor.java | 69 ++++++++++++++++--- 1 file changed, 61 insertions(+), 8 deletions(-) diff --git a/library/src/main/java/com/hjq/gson/factory/constructor/KotlinDataClassDefaultValueConstructor.java b/library/src/main/java/com/hjq/gson/factory/constructor/KotlinDataClassDefaultValueConstructor.java index 7f9f9e2..89c68c3 100644 --- a/library/src/main/java/com/hjq/gson/factory/constructor/KotlinDataClassDefaultValueConstructor.java +++ b/library/src/main/java/com/hjq/gson/factory/constructor/KotlinDataClassDefaultValueConstructor.java @@ -3,6 +3,7 @@ import com.google.gson.internal.ObjectConstructor; import com.google.gson.internal.Primitives; import java.lang.reflect.Constructor; +import java.lang.reflect.Field; /** * author : Android 轮子哥 @@ -33,21 +34,73 @@ public T construct() { // 如果参数小于 3 个,证明不是我们要的目标构造函数,就继续下一个循环 // 如果最后一个参数是 DefaultConstructorMarker 类型,并且最后第二个参数是 int 类型 - if (parameterLength < 3 || - (!DEFAULT_CONSTRUCTOR_MARKER_CLASS_NAME.equals(parameterTypes[parameterTypes.length - 1].getName()) && - !int.class.isAssignableFrom(parameterTypes[parameterTypes.length - 2]))) { + if (parameterLength < 3) { + continue; + } + + // 如果最后一个参数必须是 DefaultConstructorMarker 类型 + if (!DEFAULT_CONSTRUCTOR_MARKER_CLASS_NAME.equals(parameterTypes[parameterTypes.length - 1].getName())) { + continue; + } + + Field[] fields = mRawType.getDeclaredFields(); + + // kotlin data class 构造函数中的参数一定比字段数量要多 + // 因为里面的构造函数中的参数,除了类原有的字段外 + // 还有 N 个 int 标记位和 DefaultConstructorMarker 类型对象 + if (parameterTypes.length <= fields.length) { continue; } Object[] parameterValue = new Object[parameterLength]; - // 这个参数是标记位,用于判断有没有设置默认值进去,会进行 & 位运算进行判断 - // 这里设置成 Integer.MAX_VALUE,Integer.MAX_VALUE & 大于 0 的值,都会等于那个值 - // 这样就能每次都能走到设置默认值那里 - // Github 地址:https://github.com/getActivity/GsonFactory/issues/27 - parameterValue[parameterLength - 2] = Integer.MAX_VALUE; // 这个参数 DefaultConstructorMarker 类型,用于标记构造函数是 Kotlin 语法自动生成的 parameterValue[parameterLength - 1] = null; + for (int i = fields.length; i < parameterTypes.length - 1; i++) { + if (!int.class.isAssignableFrom(parameterTypes[i])) { + continue; + } + + // 这个参数是标记位,用于判断有没有设置默认值进去,会进行 & 位运算进行判断 + // 这里设置成 Integer.MAX_VALUE,Integer.MAX_VALUE & 大于 0 的值,都会等于那个值 + // 这样就能每次都能走到设置默认值那里,需要注意的是,这样的标记位在参数多的时候可能不止一个 + // 一个 int 标记位最多只能用于 32 个参数,如果超出了的话,就会新增多一个 int 标记位 + // 1. (i & 1) != 0 ? 0 : i + // 2. (i & 2) != 0 ? 0 : i + // 3. (i & 4) != 0 ? 0 : i + // 4. (i & 8) != 0 ? 0 : i + // 5. (i & 16) != 0 ? 0 : i + // 6. (i & 32) != 0 ? 0 : i + // 7. (i & 64) != 0 ? 0 : i + // 8. (i & 128) != 0 ? 0 : i + // 9. (i & 256) != 0 ? 0 : i + // 10. (i & 512) != 0 ? 0 : i + // 11. (i & 1024) != 0 ? 0 : i + // 12. (i & 2048) != 0 ? 0 : i + // 13. (i & 4096) != 0 ? 0 : i + // 14. (i & 8192) != 0 ? 0 : i + // 15. (i & 16384) != 0 ? 0 : i + // 16. (i & 32768) != 0 ? 0 : i + // 17. (i & 65536) != 0 ? 0 : i + // 18. (i & 131072) != 0 ? 0 : i + // 19. (i & 262144) != 0 ? 0 : i + // 20. (i & 524288) != 0 ? 0 : i + // 21. (i & 1048576) != 0 ? 0 : i + // 22. (i & 2097152) != 0 ? 0 : i + // 23. (i & 4194304) != 0 ? 0 : i + // 24. (i & 8388608) != 0 ? 0 : i + // 25. (i & 16777216) != 0 ? 0 : i + // 26. (i & 33554432) != 0 ? 0 : i + // 27. (i & 67108864) != 0 ? 0 : i + // 28. (i & 134217728) != 0 ? 0 : i + // 29. (i & 268435456) != 0 ? 0 : i + // 30. (i & 536870912) != 0 ? 0 : i + // 31. (i & 1073741824) != 0 ? 0 : i + // 32. (i & -2147483648) != 0 ? 0 : i(注意:-2147483648 = Integer.MIN_VALUE) + // Github 地址:https://github.com/getActivity/GsonFactory/issues/27 + parameterValue[i] = Integer.MAX_VALUE; + } + for (int i = 0; i < parameterTypes.length - 2; i++) { Class parameterType = parameterTypes[i]; parameterValue[i] = getTypeDefaultValue(parameterType);