argument type mismatch 参数类型不匹配

本文介绍了一个常见的SpringBoot项目中遇到的argumenttypemismatch错误及其解决方案。该错误通常发生在Controller方法接收Json格式数据时,未正确使用@RequestBody注解导致。

argument type mismatch 参数类型不匹配
开发接口时,遇到了一个错误,记录下:

java.lang.IllegalStateException: argument type mismatch
 [0] 
	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:195)
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:879)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793)
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
	at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:660)
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at com.slpay.filter.WebFilter.doFilter(WebFilter.java:26)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:373)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1594)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.IllegalArgumentException: argument type mismatch
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)
	... 48 common frames omitted

在springboot的项目中,Controller的方法中,入参为Map或者JsonObject类型时,前台发送Json格式的请求,后端Controller接受此段Json 时报 argument type mismatch 的错误。
原因:接受Json数据时没有打@RequestBody注解。

@RequestBody的详细介绍
https://blog.youkuaiyun.com/justry_deng/article/details/80972817

<think>我们正在处理一个VBA错误:"ByRef argument type mismatch"。该错误通常发生在过程调用时,实参与形参的类型声明匹配,且以ByRef方式传递。 以下是完整的解决方案,主要包括参数类型检查和强制转换机制: ```vba ' === 类型安全调用包装器 === Sub SafeCallExample() Dim intValue As Integer intValue = 10 ' 错误调用:期望Long但传递Integer ' 修复前:ProcessValue intValue -> 引发类型匹配 ' 修复方案1:强制转换类型 ProcessValue CLng(intValue) ' 修复方案2:修改变量声明 Dim longValue As Long longValue = intValue ProcessValue longValue End Sub Sub ProcessValue(ByRef value As Long) value = value * 2 End Sub ' === 通用参数验证函数 === Function ValidateParam(ByVal arg As Variant, ExpectedType As VbVarType) As Boolean If VarType(arg) <> ExpectedType Then ' 自定义错误处理 Err.Raise 13, Description:="类型匹配: 期望 " & TypeNameFromCode(ExpectedType) & _ ", 实际 " & TypeName(arg) ValidateParam = False Else ValidateParam = True End If End Function ' 类型代码转名称 Function TypeNameFromCode(typeCode As VbVarType) As String Select Case typeCode Case vbInteger: TypeNameFromCode = "Integer" Case vbLong: TypeNameFromCode = "Long" Case vbSingle: TypeNameFromCode = "Single" Case vbDouble: TypeNameFromCode = "Double" Case vbString: TypeNameFromCode = "String" Case vbBoolean: TypeNameFromCode = "Boolean" Case Else: TypeNameFromCode = "未知类型" End Select End Function ' === 主程序调用示例 === Sub MainProcedure() On Error GoTo ErrorHandler Dim userInput As Variant userInput = InputBox("请输入数字") ' 安全转换类型 Dim numericValue As Variant numericValue = Val(userInput) ' 调用前验证 If ValidateParam(numericValue, vbDouble) Then CalculateSquare numericValue End If Exit Sub ErrorHandler: MsgBox "错误: " & Err.Description, vbCritical End Sub Sub CalculateSquare(ByRef number As Double) number = number ^ 2 End Sub ``` ### 关键修复策略: 1. **参数类型显式转换** ```vba ' 将Integer转换为Long避免冲突 ProcessValue CLng(intValue) ``` - 使用`CLng`, `CInt`等转换函数 - 避免自动类型提升导致的错误 2. **变量声明标准化** ```vba ' 统一使用Long代替Integer Dim counter As Long ' 推荐 Dim index As Long ' 避免Integer溢出 ``` - VBA中`Long`比`Integer`更高效 - 减少32/64位兼容性问题 3. **动态类型验证** ```vba Function ValidateParam(arg As Variant, ExpectedType As VbVarType) As Boolean If VarType(arg) <> ExpectedType Then Err.Raise 13, ... ``` - 运行时检查参数类型 - 返回明确错误信息 4. **Variant中间转换** ```vba Sub Main() Dim v As Variant v = Sheet1.Range("A1").Value ' 未知类型 ProcessDouble CDbl(v) ' 显式转换 End Sub ``` - 处理从Excel单元格读取的确定类型 - 使用`CDbl`/`CStr`等确保类型安全 ### 永久解决方案: - **启用强制变量声明** 在模块顶部添加: ```vba Option Explicit ' 必须声明所有变量 ``` - **使用接口抽象** ```vba ' 定义严格类型接口 Public Sub Execute(ByVal param As IParameter) param.Validate param.Process End Sub ``` 此方案通过类型检查、转换机制和代码规范彻底解决ByRef类型匹配问题。 §§相关问题§§ 1. 如何处理Variant类型向具体类型转换时的溢出错误? 2. ByRef和ByVal参数传递在内存管理上有何本质区别? 3. 如何设计通用的VBA参数验证框架以减少类型错误? 4. 在类模块中如何强制实现严格的类型检查? 5. 是否应该始终避免在公共API中使用Variant类型? </think>针对"ByRef Argument Type Mismatch"错误,以下是完整解决方案。该错误发生在过程调用时传递的参数类型与目标过程声明的参数类型匹配: ```vba ' === 类型安全处理模块 === Option Explicit ' 自定义类型转换函数 Private Function ConvertToLong(ByVal value As Variant) As Long On Error GoTo ConversionError ConvertToLong = CLng(value) Exit Function ConversionError: Err.Raise 1001, "ConvertToLong", "无法转换为Long: " & CStr(value) End Function Private Function ConvertToString(ByVal value As Variant) As String On Error GoTo ConversionError ConvertToString = CStr(value) Exit Function ConversionError: Err.Raise 1002, "ConvertToString", "无法转换为String: " & TypeName(value) End Function ' === 主程序调用示例 === Sub ProcessData() On Error GoTo ErrorHandler Dim cellValue As Variant Dim rowNum As Long Dim sheetName As Variant ' 从工作表获取值 cellValue = ThisWorkbook.Sheets("Input").Range("A1").Value sheetName = ThisWorkbook.Sheets("Config").Range("B2").Value ' 安全调用示例1: 转换参数类型 rowNum = GetRowNumber(ConvertToLong(cellValue)) ' 安全调用示例2: 转换字符串参数 Dim targetSheet As Worksheet Set targetSheet = GetSheetByName(ConvertToString(sheetName)) ' 安全调用示例3: 使用自定义类型 Dim custData As CustomerData custData.Name = "John Doe" custData.ID = 12345 ProcessCustomer custData ' 正确传递自定义类型 ' 错误调用示例 (会引发类型匹配) ' ProcessCustomer "John Doe" ' 字符串而是CustomerData Exit Sub ErrorHandler: HandleTypeMismatchError End Sub ' === 正确类型定义的过程 === Private Function GetRowNumber(ByVal startIndex As Long) As Long ' 参数已声明为Long类型 GetRowNumber = startIndex + 10 End Function Private Function GetSheetByName(ByVal sheetName As String) As Worksheet ' 参数已声明为String类型 On Error Resume Next Set GetSheetByName = ThisWorkbook.Sheets(sheetName) If Err.Number <> 0 Then Set GetSheetByName = Nothing End Function ' 自定义数据类型 Private Type CustomerData ID As Long Name As String JoinDate As Date End Type ' 需要特定类型参数的过程 Private Sub ProcessCustomer(ByRef cust As CustomerData) ' 只能接受CustomerData类型 Debug.Print "处理客户: " & cust.Name End Sub ' === 错误处理程序 === Private Sub HandleTypeMismatchError() Dim errMsg As String Select Case Err.Number Case 13: ' 类型匹配 errMsg = "参数类型错误: " & Err.Description & vbCrLf errMsg = errMsg & "可能原因:" & vbCrLf errMsg = errMsg & "1. 传递了错误类型参数" & vbCrLf errMsg = errMsg & "2. 对象变量未正确初始化" & vbCrLf errMsg = errMsg & "3. 数组与普通变量混淆" Case 1001, 1002: ' 自定义转换错误 errMsg = "数据转换失败: " & Err.Description Case Else errMsg = "错误 #" & Err.Number & ": " & Err.Description End Select ' 显示错误详细信息 MsgBox errMsg, vbCritical, "类型匹配错误" ' 调试辅助 Debug.Print "错误发生在: " & Erl & " | " & Err.Source End Sub ``` ### 核心解决方案: 1. **参数类型显式转换** ```vba ' 安全转换 rowNum = GetRowNumber(ConvertToLong(cellValue)) ' 危险调用(可能出错) rowNum = GetRowNumber(cellValue) ' 如果cellValue是Long类型 ``` - 使用`ConvertToLong`、`ConvertToString`等自定义转换函数 - 避免直接从Excel单元格传递值到类型敏感参数 2. **自定义数据类型** ```vba Private Type CustomerData ID As Long Name As String End Type Sub ProcessCustomer(ByRef cust As CustomerData) ``` - 定义明确的结构化类型 - 确保传递的参数类型完全匹配 3. **变量声明最佳实践** ```vba ' 错误方式 Dim rowNum ' 默认为Variant类型 ' 正确方式 Dim rowNum As Long Dim sheetName As String ``` - 始终显式声明变量类型 - 避免使用未声明的Variant 4. **对象引用安全处理** ```vba ' 正确设置对象引用 Dim targetSheet As Worksheet Set targetSheet = GetSheetByName(ConvertToString(sheetName)) ' 危险方式 ProcessWorksheet sheetName ' 可能传递字符串而非Worksheet对象 ``` 5. **错误处理增强** ```vba Select Case Err.Number Case 13: ' 类型匹配 errMsg = "参数类型错误: " & Err.Description ... ``` - 专门处理错误13(类型匹配) - 提供具体解决方案提示 ### 预防措施: 1. **启用强制声明** ```vba Option Explicit ' 在所有模块顶部 ``` 2. **使用类型检查函数** ```vba If VarType(param) <> vbLong Then Err.Raise 13, "TypeCheck", "需要Long类型参数" End If ``` 3. **避免Variant类型参数** ```vba ' 推荐 Sub ProcessData(ByRef data) ' 推荐 Sub ProcessData(ByRef data As SpecificType) ``` 此方案通过类型安全转换、严格声明和自定义错误处理,彻底解决ByRef类型匹配问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值