截至目前,我有一个看起来类似于下面的对象.
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.
Run Code Online (Sandbox Code Playgroud)
背景:问题在于最后一个toJSON
功能.我有两个不同的函数(在这里列为TakesADataObjOrCollectionOfDataObjs
和TakesAnObjectOrCollection
),它们根据对象是否实现来执行不同的操作JSONable
.现在,我不能简化这些都源于一个功能,让编译器选择因为类型擦除,我不能有一个函数,它都Collection<?>
和Collection<? extends JSONable>
他们有相同的函数签名.
很简单,当我只需要区分just Object
和DataObj
types(这是一个非常简单的检查,我所要做的就是传递Class<?>
我们正在使用的类型),但现在我需要开始存储List<?>
和List<? extends JSONable>
.
当前解决方案:我确实为此解决方案提供了一些代码,但它与上图所示的不同.目前的解决方案是只包括我正在使用的通用类型,以及有typeClass
和a genericTypeClass
.这个问题是它开始变得非常混乱,因为:
typeClass
需要现在两种方法,一种采用既typeClass
和genericTypeClass
,而另一种typeClass
却设置genericTypeClass
为null.toJSON
开关语句将充满更多的情况下,每一个支持通用的,然后在每个那些,检查genericTypeClass
,看它是否是一个DataObj
与否.
问题:有没有其他方法可以创建此类来执行我想要的操作(存储不同的数据但仍然能够根据DataField
保留的类型输出不同的JSON )?
希望只是解释情况而不是询问3或4个其他相关问题,只会问这个问题,这将阻止我成为XY问题的牺牲品.
我建议您使用Jackson将对象转换为JSON Strings。
它真的很容易开始工作(说真的),它可以节省你大量的时间和潜在的错误...它还支持一些你可以使用的功能,List
例如我正在考虑 s 的序列化:)
这是一个有趣博客的链接,可帮助您了解 Jackson Json。这里是Jackson Json 下载页面
的链接。
下面是我刚刚制作的一个小示例,旨在向您展示如何使用它:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
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}]
Run Code Online (Sandbox Code Playgroud)
如果您在使用时遇到困难,我们可以在聊天中进行讨论,我可以在那里为您提供更多帮助。
干杯!