java - 在java中动态定义集合或对象类型变量
问题描述
我看到了许多匹配的问题,但没有回答我的问题。我想以一种我不确定我的 API 是否会返回单个对象或对象数组的方式使以下代码片段动态化。
List<Article> article = null;
我已经看到了如下不同的示例,但这并不能回答我的问题:
List<Animal> animals = new ArrayList<>();
问题是,我article
在我的 Java gson模型类中定义了变量,我真的不知道如何处理响应并使我article
的行为动态。所以,如果有一个对象,那么它应该像单个对象而不是List
,如果有对象数组,那么它应该像List
.
我也不确定这样的事情是否可行,但我正在寻找任何可行形式的以下类型的功能:
<T> Article article = null;
注意:我也看过这个Generic Type Doc。但这无助于解决我的问题。
解决方案
尽管@Jeff Stewart 的回答可能是一个可行的解决方案,但我想补充一点。如果类型安全不是您需要的问题,您也可以考虑将article
变量定义为Object
. 但是,您应该稍后在使用时检查您的变量,例如:
if(article instanceof Collection){
// article is an array of objects
} else {
// article is a single object
}
更新: 感谢@Jeff Stewart 的想法,我实现了一个更合适的解决方案,可以在单一类型中处理单个值和多个值。
考虑您的 API 响应是这样的:
"article": {"name":"article1",...}
- or -
"article": [{"name":"article1",...}, {"name":"article2",...}]
让我们创建ArticleList
派生自java.util.ArrayList
/**
* Custom type to handle both single Article and ArrayList<Article> types
*
* @author Yavuz Tas
*
*/
public class ArticleList extends ArrayList<Article> {
}
在我们实现自定义JsonAdapter
类型ArticleList
之后
/**
* Custom JsonAdapter for GSON to handle {@link ArticleList} converstion
*
* @author Yavuz Tas
*
*/
public class ArticleListJsonAdapter extends TypeAdapter<ArticleList> {
/*
* We just create another instance of GSON here in order to reuse their
* predefined object and collection adapters
*/
private static final Gson gson = new Gson();
private static final TypeAdapter<Article> objectTypeAdapter = gson.getAdapter(Article.class);
private static final TypeAdapter<List<Article>> listTypeAdapter = gson.getAdapter(new TypeToken<List<Article>>() {
});
@Override
public void write(JsonWriter out, ArticleList list) throws IOException {
/*
* Since we do not serialize ArticleList by gson we can omit this part but
* anyway we can simply implement by reusing listTypeAdapter
*/
listTypeAdapter.write(out, new ArrayList<Article>(list));
}
@Override
public ArticleList read(JsonReader in) throws IOException {
ArticleList deserializedObject = new ArticleList();
// type of next token
JsonToken peek = in.peek();
// if the json field is single object just add this object to list as an
// element
if (JsonToken.BEGIN_OBJECT.equals(peek)) {
Article object = objectTypeAdapter.read(in);
deserializedObject.add(object);
}
// if the json field is array then implement normal array deserialization
if (JsonToken.BEGIN_ARRAY.equals(peek)) {
List<Article> list = listTypeAdapter.read(in);
deserializedObject.addAll(list);
}
return deserializedObject;
}
}
最后,我们将适配器注册到article
GSON 模型中用于 API 响应的字段,并将其类型更改为ArticleList
:
@JsonAdapter(value = ArticleListJsonAdapter.class)
@SerializedName("article")
@Expose
private ArticleList article;
请注意,任何单个Article
响应都会自动添加ArticleList
为列表元素。read
您可以通过更改方法中的实现来更改此行为ArticleListJsonAdapter
。
我希望这也有帮助。干杯!
推荐阅读
- angular - 如何将错误消息/状态传递给孩子 - ControlValueAccessor
- flutter - Flutter 显示 Draft JS 内容
- javascript - useState 变量未在代码片段的第一次运行时设置
- amazon-cognito - response-to-auth-challenge 返回错误:提供的会话无效
- html - 在一行中显示文本在 x 轴上旋转
- css - 使用 css 调整 WordPress 中数据网格的列
- html - 框对齐很重要 CSS
- python - Python 用 tkinter 制作截屏程序
- java - 将日期传递给控制器时出现异常 - Spring MVC
- android - 在颤动中制作 CheckBoxListTile 的 DropDownButton