fastjson TypeReference解析嵌套泛型报错

zhte4eai  于 2021-11-27  发布在  Java
关注(0)|答案(4)|浏览(919)
package com.alibaba.json.bvt.issue_3300;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;

import junit.framework.TestCase;
import org.junit.Test;

/**

* @author yumin.pym
* /

public class Issue3448 extends TestCase {
    public static class SelfTypeReference<T> {

    }

    @Test
    public void test() {
        List<Map<String, List<String>>> list = new ArrayList<>(4);
        list.add(Collections.singletonMap("key1", Collections.singletonList("item")));
        String text = JSON.toJSONString(list);
        System.out.println("text = " + text);

        List<Map<String, List<String>>> result = parseObject(text,
            new SelfTypeReference<Map<String, List<String>>>() {});
        System.out.println("result = " + result);
    }

    public <T> List<T> parseObject(String text, SelfTypeReference<T> selfTypeReference) {
        Type genericSuperclass = selfTypeReference.getClass().getGenericSuperclass();
        Type[] actualTypeArguments = ((ParameterizedType)genericSuperclass).getActualTypeArguments();
        return JSON.parseObject(text, new TypeReference<List<T>>(actualTypeArguments) {});
    }
}

7fyelxc5

7fyelxc51#

这里的reture返回里里层泛型的类型,应该去掉return在外层统一返回
com.alibaba.fastjson.TypeReference#handlerParameterizedType

8cdiaqws

8cdiaqws2#

你的这个修复方式在某种情况下有问题,如下test_parseList2所示,而我的改法是可以正确处理。

package com.alibaba.json.bvt.issue_3300;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;

import junit.framework.TestCase;
import org.junit.Test;

/**

* @author yumin.pym
* /

public class Issue3448 extends TestCase {
    public static class Item {
        private String id;

        public Item() {
        }

        public Item(String id) {
            this.id = id;
        }

        public String getId() {
            return id;
        }

        public void setId(String id) {
            this.id = id;
        }
    }

    public static class SelfTypeReference<T> {

    }

    public static class SelfTypeReference2<T, R> {

    }

    private <T> List<T> parseList(String text, SelfTypeReference<T> selfTypeReference) {
        Type genericSuperclass = selfTypeReference.getClass().getGenericSuperclass();
        Type[] actualTypeArguments = ((ParameterizedType)genericSuperclass).getActualTypeArguments();
        return JSON.parseObject(text, new TypeReference<List<T>>(actualTypeArguments) {});
    }

    @Test
    public void test_parseList() {
        List<Map<String, List<String>>> list = new ArrayList(4);
        list.add(Collections.singletonMap("key1", Collections.singletonList("item")));
        String text = JSON.toJSONString(list);
        System.out.println("text = " + text);

        List<Map<String, List<String>>> result = parseList(text, new SelfTypeReference<Map<String, List<String>>>() {});
        System.out.println("result = " + result);
        TestCase.assertTrue(result.get(0) instanceof Map);
        TestCase.assertTrue(result.get(0).get("key1").get(0) instanceof String);
    }

    private <K, V> Map<K, V> parseMap(String text, SelfTypeReference2<K, V> selfTypeReference2) {
        Type genericSuperclass = selfTypeReference2.getClass().getGenericSuperclass();
        Type[] actualTypeArguments = ((ParameterizedType)genericSuperclass).getActualTypeArguments();
        return JSON.parseObject(text, new TypeReference<Map<K, V>>(actualTypeArguments) {});
    }

    @Test
    public void test_parseMap() {
        Map<String, String> map = Collections.singletonMap("key1", "value1");
        String text = JSON.toJSONString(map);

        Map<String, String> result = parseMap(text, new SelfTypeReference2<String, String>() {});
        System.out.println("result = " + result);
        TestCase.assertTrue(result instanceof Map);
        TestCase.assertEquals("value1", result.get("key1"));
    }

    private <T1, T2> List<Map<T1, List<T2>>> parseList2(String text, SelfTypeReference2<T1, T2> selfTypeReference2) {
        Type genericSuperclass = selfTypeReference2.getClass().getGenericSuperclass();
        Type[] actualTypeArguments = ((ParameterizedType)genericSuperclass).getActualTypeArguments();
        return JSON.parseObject(text, new TypeReference<List<Map<T1, List<T2>>>>(actualTypeArguments) {});
    }

    @Test
    public void test_parseList2() {
        List<Map<String, List<Item>>> list = new ArrayList(4);
        list.add(Collections.singletonMap("key1", Collections.singletonList(new Item("1001"))));
        String text = JSON.toJSONString(list);
        System.out.println("text = " + text);

        List<Map<String, List<Item>>> result = parseList2(text, new SelfTypeReference2<String, Item>() {});
        System.out.println("result = " + result);
        TestCase.assertTrue(result.get(0) instanceof Map);
        TestCase.assertTrue(result.get(0).get("key1").get(0) instanceof Item);
    }
}

我的修改可以正确处理,如下所示:

t98cgbkg

t98cgbkg3#

大佬真的细心啊

ivqmmu1c

ivqmmu1c4#

凭直觉,感觉你的修改有问题,但是得证明有问题。哈哈……

相关问题