Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix BeanUtils#getEnumValueField, for issue #2682 #2821

Merged
merged 3 commits into from
Jul 23, 2024
Merged

Conversation

poo0054
Copy link
Contributor

@poo0054 poo0054 commented Jul 20, 2024

What this PR does / why we need it?

修复了 [#2682] 。

我碰见了和 [#2682] 一样的问题

产生原因前提

如果继承了 com.baomidou.mybatisplus.annotation.IEnum<T extends Serializable> 类,并且需要使用 IEnum#getValue 方法或者注解上面添加@JSONField(value = true)注解。

步骤解析

json反序列化:执行到 BeanUtils#getEnumValueField 方法,里面获取所有的Method进行循环,这时候继承了IEnum接口会找到俩名称个一样的Method 方法。只不过getReturnType返回类不同,并在 if (methodName.startsWith("get")) {分支中没有对同名方法做处理。最后到了 new ObjectReaderImplEnum 方法的时候 ,如下代码

   public ObjectReaderImplEnum(
            Class enumClass,
            Method createMethod,
            Member valueField,
            Enum[] enums,
            Enum[] ordinalEnums,
            long[] enumNameHashCodes
    ) {
 ......
 if (valueField instanceof Field) {
            valueFieldType = ((Field) valueField).getType();
        } else if (valueField instanceof Method) {
            valueFieldType = ((Method) valueField).getReturnType();
        }

首先获取了Serializable(继承了 IEnum 接口) 。然后在如下代码

   public ObjectReaderImplEnum(
            Class enumClass,
            Method createMethod,
            Member valueField,
            Enum[] enums,
            Enum[] ordinalEnums,
            long[] enumNameHashCodes
    ) {
 ......
 if (valueFieldType == String.class) {
                stringValues = new String[enums.length];
            } else {
                intValues = new long[enums.length];
            }

中就会使用 intValues 。在下面解析的时候就会出现bug。

复原

如果使用里面的BizType枚举是无法复原该bug,在调用#.getMethods()获取所有方法的时候,String getValue()Serializable getValue之前。

我创建了 com.alibaba.fastjson2.issues_2600.Issue2682#RobotActEnum枚举,该枚举可以保证Serializable getValueString getValue() 之前,然后触发这个bug。请问一下这个class反射获取所有方法的时候顺序是怎样造成的。

解决思路

我是在BeanUtils#getEnumValueField 中的 if (methodName.startsWith("get")) { 里面 如果发现俩个方法名称完全一样,就认为是重写方法,然后使用isAssignableFrom确认子类的方法是哪个 (枚举中使用子类)

Summary of your change

修复 BeanUtils#getEnumValueField

Please indicate you've done the following:

  • Made sure tests are passing and test coverage is added if needed.
  • Made sure commit message follow the rule of Conventional Commits specification.
  • Considered the docs impact and opened a new docs issue or PR with docs changes if needed.

@CLAassistant
Copy link

CLAassistant commented Jul 20, 2024

CLA assistant check
All committers have signed the CLA.

@wenshao
Copy link
Member

wenshao commented Jul 20, 2024

你需要本地只能够mvn validate修复codestyle问题

@poo0054

This comment was marked as resolved.

@wenshao wenshao merged commit bcccf7b into alibaba:main Jul 23, 2024
1 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants