C/C 言語では、Union は Union とも呼ばれ、構造体 (struct) と同様のデータ構造です。ユニオン (union) には、構造体 (struct) と同様に、多くのデータ型と変数を含めることができます。両者の違いは次のとおりです。
構造体 (struct) 内のすべての変数は「共存」します。 " "、すべての変数は同時に有効であり、各変数は異なるメモリ空間を占有します。
共用体では、各変数は「相互に排他的」であり、1 つの変数のみが使用されます。同時に有効になるため、すべての変数は同じメモリ空間を占有します。
複数のデータがメモリを共有する必要がある場合、または一度に複数のデータのうち 1 つだけを取得する必要がある場合は、共用体を使用できます。
Java 言語には、共用体や構造体 (struct) の概念はなく、クラスの概念のみがあります。ご存知のとおり、構造はクラスを使用して実装できます。実際、共用体はクラスを使用して実装することもできます。ただし、このクラスには「複数のデータがメモリを共有する必要がある」という機能はなく、「複数のデータのうち一度に1つだけ取り出せばよい」という機能しかありません。
ここでは、WeChat プロトコルの顧客メッセージを例として取り上げます。インターフェイス プロトコルのカプセル化に関する私の長年の経験に基づくと、実装方法は主に 2 つあります。
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 クラスの実装:
/** 客户消息类 */@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 言語の共用体は大きく異なりますが、機能は一般的に同じです。
C/C 言語では、共用体には共用体の現在のデータ型は含まれません。ただし、上記で実装された Java ユニオンには、そのユニオンに対応するデータ型がすでに含まれています。したがって、厳密に言えば、Javaのユニオンは本物のユニオンではなく、「一度に複数のデータのうち一つだけを取り出す」機能を持ったクラスです。
以上がデータ本体の共存を実現するために、Java は Union クラスをどのように定義するのでしょうか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。