在C/C 語言中,聯合體(union),又稱為共用體,類似結構體(struct)的一種資料結構。聯合體(union)和結構體(struct)一樣,可以包含很多種資料型別和變量,兩者區別如下:
結構體(struct)中所有變數是「共存」的,同時所有變數都生效,各個變數佔據不同的記憶體空間;
聯合體(union)中是各變數是「互斥」的,同時只有一個變數生效,所有變數佔據同一塊記憶體空間。
當多個資料需要共享記憶體或多個資料每次只取其一時,可以採用聯合體(union)。
在Java語言中,沒有聯合體(union)和結構體(struct)概念,只有類別(class)的概念。眾所眾知,結構體(struct)可以用類別(class)來實現。其實,聯合體(union)也可以用類別(class)來實現。但是,這個類別不具備「多個資料需要共享記憶體」的功能,只具備「多個資料每次只取其一」的功能。
這裡,以微信協定的客戶訊息為例說明。根據我多年來的介面協定封裝經驗,主要有以下兩種實作方式。
Union類別實作:
/** 客户消息类 */@ToStringpublic class CustomerMessage { /** 属性相关 */ /** 消息类型 */ private String msgType; /** 目标用户 */ private String toUser; /** 共用体相关 */ /** 新闻内容 */ private News news; ... /** 常量相关 */ /** 新闻消息 */ public static final String MSG_TYPE_NEWS = "news"; ... /** 构造函数 */ public CustomerMessage() {} /** 构造函数 */ public CustomerMessage(String toUser) { this.toUser = toUser; } /** 构造函数 */ public CustomerMessage(String toUser, News news) { this.toUser = toUser; this.msgType = MSG_TYPE_NEWS; this.news = news; } /** 清除消息内容 */ private void removeMsgContent() { // 检查消息类型 if (Objects.isNull(msgType)) { return; } // 清除消息内容 if (MSG_TYPE_NEWS.equals(msgType)) { news = null; } else if (...) { ... } msgType = null; } /** 检查消息类型 */ private void checkMsgType(String msgType) { // 检查消息类型 if (Objects.isNull(msgType)) { throw new IllegalArgumentException("消息类型为空"); } // 比较消息类型 if (!Objects.equals(msgType, this.msgType)) { throw new IllegalArgumentException("消息类型不匹配"); } } /** 设置消息类型函数 */ public void setMsgType(String msgType) { // 清除消息内容 removeMsgContent(); // 检查消息类型 if (Objects.isNull(msgType)) { throw new IllegalArgumentException("消息类型为空"); } // 赋值消息内容 this.msgType = msgType; if (MSG_TYPE_NEWS.equals(msgType)) { news = new News(); } else if (...) { ... } else { throw new IllegalArgumentException("消息类型不支持"); } } /** 获取消息类型 */ public String getMsgType() { // 检查消息类型 if (Objects.isNull(msgType)) { throw new IllegalArgumentException("消息类型无效"); } // 返回消息类型 return this.msgType; } /** 设置新闻 */ public void setNews(News news) { // 清除消息内容 removeMsgContent(); // 赋值消息内容 this.msgType = MSG_TYPE_NEWS; this.news = news; } /** 获取新闻 */ public News getNews() { // 检查消息类型 checkMsgType(MSG_TYPE_NEWS); // 返回消息内容 return this.news; } ... }
Union類別使用:
String accessToken = ...; String toUser = ...; List<Article> articleList = ...; News news = new News(articleList); CustomerMessage customerMessage = new CustomerMessage(toUser, news); wechatApi.sendCustomerMessage(accessToken, customerMessage);
主要優缺點:
#優點:更貼近C/C 語言的聯合體(union);
缺點:實作邏輯較為複雜,參數型別驗證較多。
Union類別實作:
/** 客户消息类 */@Getter@Setter@ToStringpublic abstract class CustomerMessage { /** 属性相关 */ /** 消息类型 */ private String msgType; /** 目标用户 */ private String toUser; /** 常量相关 */ /** 新闻消息 */ public static final String MSG_TYPE_NEWS = "news"; ... /** 构造函数 */ public CustomerMessage(String msgType) { this.msgType = msgType; } /** 构造函数 */ public CustomerMessage(String msgType, String toUser) { this.msgType = msgType; this.toUser = toUser; } }/** 新闻客户消息类 */@Getter@Setter@ToString(callSuper = true)public class NewsCustomerMessage extends CustomerMessage { /** 属性相关 */ /** 新闻内容 */ private News news; /** 构造函数 */ public NewsCustomerMessage() { super(MSG_TYPE_NEWS); } /** 构造函数 */ public NewsCustomerMessage(String toUser, News news) { super(MSG_TYPE_NEWS, toUser); this.news = news; } }
Union類別使用:
String accessToken = ...; String toUser = ...; List<Article> articleList = ...; News news = new News(articleList); CustomerMessage customerMessage = new NewsCustomerMessage(toUser, news); wechatApi.sendCustomerMessage(accessToken, customerMessage);
主要優缺點:
優點:使用虛基類別和子類別進行拆分,各個子類別物件的概念明確;
缺點:與C /C 語言的聯合體(union)差異大,但是功能上大致一致。
在C/C 語言中,聯合體並不包括聯合體目前的資料型態。但在上面實作的Java聯合體中,已經包含了聯合體對應的資料型態。所以,從嚴格意義上來說,Java聯合體並不是真正的聯合體,只是一個具備「多個資料每次只取其一」功能的類別。
以上是java如何定義Union類別實作資料體的共存的詳細內容。更多資訊請關注PHP中文網其他相關文章!