1. 程式人生 > 其它 >java介面引數用抽象類或者介面型別接收【反序列化多型】

java介面引數用抽象類或者介面型別接收【反序列化多型】

技術標籤:java學習技術對比java學習異常積累javajava多型抽象類

介面引數用抽象類接收

傻得解決方法

眾所周知
在這裡插入圖片描述
所以只能用Map接收物件,然後轉換成物件?

看著就感覺很麻煩,然而我還是這樣做了,因為當時沒有想到其他方案

【這個方案就不貼了,因為壓根不覺得這是一個解決方案】

事實上,存在這樣的解決方案,It’s so much easier!

那就是:藉助Jackson的JsonTypeInfo註解實現多型類的解析!!!

JsonTypeInfo 註解簡單介紹

作用於類或介面,被用來處理多型型別的序列化及反序列化。

This is necessarily for polymorphic types, and may also be needed to link abstract declared types and matching concrete implementation.

才藝展示

1.抽象類

package jackson;

import com.
fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; import lombok.Data; @Data @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type", visible = true) @JsonSubTypes({@JsonSubTypes.Type(value = InputPageModel.class, name = "input")
, @JsonSubTypes.Type(value = NumberPageModel.class, name = "number")}) public abstract class Page { private String type; private String name; private String uiType; private String label; }

註解裡的visible欄位:如果為false,那麼反序列化時,型別id欄位(在這個demo裡是type欄位)的值將不會被反序列化到POJO中。

2.1 實現類1

package jackson;

import lombok.Data;

@Data
public class InputPage extends Page {
	
	private String input;
}

2.2 實現類2

package jackson;

import lombok.Data;

@Data
public class NumberPage extends Page {
	
	private Integer number;
}

介面處啥都不用改,哪哪都不用改,只是在抽象類上加了註解!!!

擴充套件:大型工程裡的應用

這個demo裡JsonTypeInfo藉助JsonSubTypes註解來感知抽象類的有哪些實現類,並且是如何匹配的。在大型工程中抽象類的子類很多(介面的實現很多),那麼JsonSubTypes註解就十分臃腫了。而且這種寫法是 違反開閉原則(OCP) 的。藉助以下方式可以將JsonSubTypes剔除掉,達到相同的效果。

1. 給子類加JsonTypeName註解

package jackson;

import com.fasterxml.jackson.annotation.JsonTypeName;
import lombok.Data;

@Data
@JsonTypeName(value = "input")
public class InputPage extends Page {
	
	private String input;
}

2. 藉助reflections框架,將所有JsonTypeName註解類掃描出來

ObjectMapper並不具備掃描實現JsonTypeName註解的類,因此需要自己手工掃描所有帶有這個註解的類。reflections框架在我的另一篇部落格 Reflections框架,類掃描神器 裡有介紹。

Set<Class<?>> classSet = reflections.getTypesAnnotatedWith(JsonTypeName.class);

3. 手工將掃出來的類註冊到ObjectMapper物件

最後一步,完成子類註冊

ObjectMapper  mapper   = new ObjectMapper();
classSet.parallelStream().forEach(clazz -> mapper.registerSubtypes(clazz));

這樣便可以在大型工程裡優雅的使用jackson解析多型類,每增加一個子型別,無需修改額外的程式碼。對擴充套件開放,對修改封閉。

其他主流json框架對多型的支援

框架是否支援備註
gson支援不支援註解,使用不方便 官方demo
fastjson不支援
json-lib不支援

當遇到json框架技術選型時,如果有處理多型的需求,那麼jackson無疑是最佳的選擇。

參考文件

參考方案