【问题标题】:dynamically define collection or object type variable in java在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.,但这无助于解决我的问题。

【问题讨论】:

    标签: java list object gson dynamictype


    【解决方案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.ArrayListArticleList

    /**
     * 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 作为列表元素。您可以通过更改ArticleListJsonAdapterread 方法中的实现来更改此行为。

    我希望这也有帮助。干杯!

    【讨论】:

      猜你喜欢
      • 2022-01-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多