在java中动态定义集合或对象类型变量
Posted
技术标签:
【中文标题】在java中动态定义集合或对象类型变量【英文标题】:dynamically define collection or object type variable in java 【发布时间】:2019-11-13 13:53:28 【问题描述】:我看到了许多匹配的问题,但没有回答我的问题。我想以一种我不确定我的 API 是否会返回单个对象或对象数组的方式使以下代码 sn-p 动态化。
List<Article> article = null;
我见过不同的例子,如下所示,但这并不能回答我的问题:
List<Animal> animals = new ArrayList<>();
问题是,我在我的 Java gson 模型类中定义了 article
变量,我真的不知道如何处理响应并使我的 article
动态运行。所以,如果有一个对象,那么它应该像单个对象而不是List
,如果有一个对象数组,那么它应该像List
。
我也不确定这样的事情是否可行,但我正在寻找任何可行形式的以下类型的功能:
<T> Article article = null;
注意:我也看到了这个Generic Type Doc.,但这无助于解决我的问题。
【问题讨论】:
【参考方案1】:考虑使用在内部执行聚合方法的方法扩展 ArrayList,以便在外部,无论有 0、1 或 N 个内部对象,它的行为都是相同的。
class Articles extends ArrayList<Article> ...
【讨论】:
我喜欢你的方法,但你能否再给我一些例子,这将如何实际使用和工作。 快速查看这里的示例:en.wikipedia.org/wiki/Gson。注意“公共汽车[]汽车;”是在类中,但访问数据是通过聚合数组中包含的内容的方法调用来执行的。如果我了解您的需要,您可以创建聚合方法,在内部调用超类中的迭代器。我的建议是 is-a 关系,而 wikipedia 示例是 has-a 关系,您需要评估哪个可能更合适。我假设的是,Gson 可以像任何其他对象一样序列化/序列化集合类。【参考方案2】:虽然@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",...]
让我们创建派生自java.util.ArrayList
的ArticleList
/**
* Custom type to handle both single Article and ArrayList<Article> types
*
* @author Yavuz Tas
*
*/
public class ArticleList extends ArrayList<Article>
在我们为ArticleList
类型实现自定义JsonAdapter
之后
/**
* 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;
最后我们将适配器注册到 GSON 模型中用于 API 响应的 article
字段,并将其类型更改为 ArticleList
:
@JsonAdapter(value = ArticleListJsonAdapter.class)
@SerializedName("article")
@Expose
private ArticleList article;
请注意,任何单个Article
响应都会自动添加到ArticleList
作为列表元素。您可以通过更改ArticleListJsonAdapter
的read
方法中的实现来更改此行为。
我希望这也有帮助。干杯!
【讨论】:
以上是关于在java中动态定义集合或对象类型变量的主要内容,如果未能解决你的问题,请参考以下文章