from deepseek
🐛 主要Bug
1. 类型提取逻辑缺陷
kotlin
private fun extractTypeInfo(type: Type): TypeInfo {
if (type !is ParameterizedType) {
return TypeInfo(null, null) // ❌ 这里有问题
}
// ...
}问题:当类型是简单泛型(如Query<String>)时,rawType应该能正确提取,但当前逻辑在某些情况下会失败。
2. 参数名获取不可靠
kotlin
private fun getParameterName(param: Parameter): String {
return param.getAnnotation(Param::class.java)?.value?.takeIf { it.isNotEmpty() }
?: param.name.takeUnless { it.matches(Regex("arg\\d+")) }
?: "" // ❌ 可能返回空字符串
}问题:当编译时参数名丢失(常见情况)且没有@Param注解时,返回空字符串会导致后续提取失败。
3. 异常处理重复
kotlin
try {
// ...
} catch (e: ExtractionError) {
throw e // ❌ 冗余的catch-rethrow
} catch (e: InvocationError) {
throw e // ❌ 冗余的catch-rethrow
} catch (e: Exception) {
throw InvocationError(handlerName, method.name, e.cause ?: e)
}⚡ 优化建议
1. 改进类型提取
kotlin
private fun extractTypeInfo(type: Type): TypeInfo {
return when (type) {
is Class<*> -> TypeInfo(type, null)
is ParameterizedType -> {
val rawType = type.rawType as? Class<*>
val firstArg = type.actualTypeArguments.firstOrNull()
when {
rawType?.isList() == true && firstArg is Class<*> ->
TypeInfo(rawType, firstArg)
firstArg is Class<*> ->
TypeInfo(firstArg, null)
else -> TypeInfo(rawType, null)
}
}
else -> TypeInfo(null, null)
}
}2. 增强参数名处理
kotlin
private fun getParameterName(param: Parameter): String {
val annotatedName = param.getAnnotation(Param::class.java)?.value
if (!annotatedName.isNullOrEmpty()) return annotatedName
val paramName = param.name
if (!paramName.isNullOrEmpty() && !paramName.matches(Regex("arg\\d+"))) {
return paramName
}
// 提供更好的错误信息
throw ExtractionError.InvalidType(
param.type.simpleName,
"Parameter name not available. Use @Param annotation or enable parameter name retention."
)
}3. 简化异常处理
kotlin
try {
val args = extractors.map { it(ctx) }
method.invoke(null, *args.toTypedArray())
} catch (e: ExtractionError) {
throw e
} catch (e: InvocationError) {
throw e
} catch (e: Exception) {
throw InvocationError(handlerName, method.name, e.cause ?: e)
}
// 可以简化为:
try {
val args = extractors.map { it(ctx) }
method.invoke(null, *args.toTypedArray())
} catch (e: ExtractionError) {
throw e
} catch (e: InvocationError) {
throw e
} catch (e: Exception) {
throw InvocationError(handlerName, method.name, e.cause ?: e)
}4. 增加类型安全
kotlin
// 添加类型检查
private fun validateExtractorType(param: Parameter, expectedTypes: Set<Class<*>>) {
if (!expectedTypes.contains(param.type)) {
throw ExtractionError.InvalidType(
param.type.simpleName,
"Expected one of: ${expectedTypes.joinToString { it.simpleName }}"
)
}
}
// 在 buildExtractor 中使用:
when (rawType) {
Path::class.java -> {
validateExtractorType(param, setOf(Path::class.java))
buildPathExtractor(ctx, typeInfo)
}
// ...
}5. 改进默认值处理
kotlin
private fun getDefaultValue(clazz: Class<*>): Any? = when (clazz) {
Int::class.java, Integer::class.java -> 0
Long::class.java, java.lang.Long::class.java -> 0L
Double::class.java, java.lang.Double::class.java -> 0.0
Float::class.java, java.lang.Float::class.java -> 0.0f
Boolean::class.java, java.lang.Boolean::class.java -> false
String::class.java -> ""
else -> null // 对于不支持的类型返回null
}6. 添加缓存优化
kotlin
// 缓存提取器构建结果
private val extractorCache = ConcurrentHashMap<String, (Context) -> Any?>()
private fun buildExtractor(param: Parameter, handler: String, method: String): (Context) -> Any? {
val cacheKey = "$handler.$method.${param.name}.${param.type.name}"
return extractorCache.getOrPut(cacheKey) {
// 原有的构建逻辑
buildExtractorInternal(param, handler, method)
}
}7. 增强错误信息
kotlin
private data class ExtractorContext(
val handler: String,
val method: String,
val paramName: String,
val paramType: String,
val parameterIndex: Int // 添加参数位置信息
) {
override fun toString() = "$handler.$method(#$parameterIndex $paramType $paramName)"
}🔧 其他改进
添加输入验证:在关键方法开始处检查参数有效性
支持更多类型:如
BigDecimal、LocalDateTime等常见类型改进泛型支持:更好地处理嵌套泛型类型
添加日志:用于调试复杂的参数提取问题
这些改进将显著提升代码的健壮性、可维护性和用户体验。