Java根据泛型类型做不同的事情

Java根据泛型类型做不同的事情,java,generics,Java,Generics,到目前为止,我有一个对象,看起来像下面 public class DataField implements JSONable { public final String name; public final Class<?> typeClass; private Object data; public <T> DataField(String name, Class<T> typeClass) { th

到目前为止,我有一个对象,看起来像下面

public class DataField implements JSONable
{
    public final String name;
    public final Class<?> typeClass;
    private Object data;

    public <T> DataField(String name, Class<T> typeClass)
    {
        this.name = name;
        this.typeClass = typeClass;

        data = null;
    }
    public <T> T getData(Class<T> passClass)
    {
        if(!typeClass.equals(passClass))
            throw new TypeMismatchException("Type mismatch");
        return passClass.cast(data);
    }
    public <T> T setData(T obj, Class<T> passClass)
    {
        if(!typeClass.equals(passClass))
            throw new TypeMismatchException("Type mismatch");
        data = (Object) obj;
    }
    public String toJSON()
    {
        //The part that bugs me
        StringBuilder sb = new StringBuilder();
        switch(type)
        {
        case "myPackage.DataField":
            if(isArray)
                return TakesADataObjOrCollectionOfDataObjs(sb,Arrays.asList(get(DataObj[].class)));
            else
                return TakesADataObjOrCollectionOfDataObjs(sb,get(DataObj.class));
        break;
        default:
            if(isArray)
                TakesAnObjectOrCollection(sb,Arrays.asList(get(Object[].class)));
            else
               TakesAnObjectOrCollection(sb,get(Object.class));
        break;
        }
        return sb.toString();
    }
}
//I did not include code for DataObj but it has a HashMap<String,DataField>
//fields on it and two functions for getting and setting field data 
//without actually divulging the field objects themselves.
public类数据字段实现JSO
{
公共最终字符串名;
公开期末班;
私有对象数据;
公共数据字段(字符串名称,类类型类)
{
this.name=名称;
this.typeClass=typeClass;
数据=空;
}
公共T getData(类passClass)
{
如果(!typeClass.equals(passClass))
抛出新的类型不匹配异常(“类型不匹配”);
返回passClass.cast(数据);
}
公共T设置数据(T对象,类passClass)
{
如果(!typeClass.equals(passClass))
抛出新的类型不匹配异常(“类型不匹配”);
数据=(对象)obj;
}
公共字符串toJSON()
{
//让我讨厌的部分
StringBuilder sb=新的StringBuilder();
开关(类型)
{
案例“myPackage.DataField”:
如果(isArray)
返回TakesADataObjOrCollectionOfDataObjs(sb,Arrays.asList(get(DataObj[].class));
其他的
return TakesADataObjOrCollectionOfDataObjs(sb,get(DataObj.class));
打破
违约:
如果(isArray)
TakesAnObjectOrCollection(sb,Arrays.asList(get(Object[].class));
其他的
TakesAnObjectOrCollection(sb,get(Object.class));
打破
}
使某人返回字符串();
}
}
//我没有包含DataObj的代码,但它有一个HashMap
//字段和两个用于获取和设置字段数据的函数
//而不会泄露场对象本身。

Background:问题在于最后一个
toJSON
函数。我有两个不同的函数(这里列出的是
TakesADataObjOrCollectionOfDataObjs
TakesAnObjectOrCollection
),它们根据对象是否实现
JSONable
执行不同的操作。现在我不能将所有这些简化为一个函数,让编译器选择,因为使用类型擦除,我不能同时使用
Collection
Collection
List函数,我建议您使用Jackson将对象转换为JSON字符串

这真的很容易开始工作(认真的),它可以节省你很多时间和潜在的错误。。。它还支持一些您可以使用的功能,我考虑的是
List
s的序列化,例如:)

这里是一个指向的链接。
这里有一个链接


下面是我刚刚制作的一个小示例,向您展示如何使用它:

public class Main {
    public final String mainStr = "Hello";
    
    public static void main(String[] args) throws JsonGenerationException, JsonMappingException, IOException {
        final ObjectMapper om = new ObjectMapper();
        System.out.println("Serialized Main: " + om.writeValueAsString(new Main()));
        System.out.println("Serialized A: " + om.writeValueAsString(new A()));
        System.out.println("Serialized AA: " + om.writeValueAsString(new AA()));
        System.out.println("Serialized B: " + om.writeValueAsString(new B()));
        System.out.println("Serialized List of A: " + om.writeValueAsString(Collections.singletonList(new A())));
    }
    
    static class A extends Main {
        public final String aStr = "World";
        public final int aInt = 42;
    }
    
    static class AA extends A {
        public final String aaStr = "Foo";
    }

    static class B {
        public final String bStr = "Bar";
        public final boolean bBool = true;
    }
}
乌普图特:

Serialized Main: {"mainStr":"Hello"}
Serialized A: {"mainStr":"Hello","aStr":"World","aInt":42}
Serialized AA: {"mainStr":"Hello","aStr":"World","aInt":42,"aaStr":"Foo"}
Serialized B: {"bStr":"Bar","bBool":true}
Serialized List of A: [{"mainStr":"Hello","aStr":"World","aInt":42}]
如果你在工作中遇到困难,我们可以继续讨论,我可以在那里给你更多的帮助


干杯

getData()
setData()
在我看来是错误的,就好像你基本上是在复制常规POJO的常规字段在做什么。驻留在
DataObjs
上的所有
数据字段都是从几个不同的来源(数据库、excel电子表格等)填充的。我拥有这些对象的原因是,我可以迭代多个对象,包括它们的字段,以检索和存储某些信息,而无需使用反射。即使使用反射,也会使某些事情变得非常困难或不可能完成,或者对于POJO的每个不同对象和字段都需要更多的手工输入代码。如果必须这样做,那么您必须承认您的代码会有点混乱。我所见过的大多数数据序列化框架(例如XStream)所做的就是创建一个
转换器
接口,每个实现都将与某个Java类进行转换。然后创建一个
映射>
映射,您可以使用它动态查找要使用的转换器。我目前正在研究它,但我认为时间限制不允许我重新开始。我已经很了解我现在的情况了。我会+1这个答案,如果我认为它适合我的情况,不管我是否会使用它。这很公平。但不要放弃,我真的相信这个解决方案是正确的!不要犹豫寻求更多的帮助,否则你可能会错过一些能让你的生活更轻松的大事;)祝你好运