定义union类实现数据体的共存在c/c++语言中,联合体(union),又称共用体,类似结构体(struct)的一种数据结构。联合体(union)和结构体(struct)一样,可以包含很多种数据类型和变量,两者区别如下:
结构体(struct)中所有变量是“共存”的,同时所有变量都生效,各个变量占据不同的内存空间;
联合体(union)中是各变量是“互斥”的,同时只有一个变量生效,所有变量占据同一块内存空间。
当多个数据需要共享内存或者多个数据每次只取其一时,可以采用联合体(union)。
在java语言中,没有联合体(union)和结构体(struct)概念,只有类(class)的概念。众所众知,结构体(struct)可以用类(class)来实现。其实,联合体(union)也可以用类(class)来实现。但是,这个类不具备“多个数据需要共享内存”的功能,只具备“多个数据每次只取其一”的功能。
这里,以微信协议的客户消息为例说明。根据我多年来的接口协议封装经验,主要有以下两种实现方式。
1.使用函数方式实现unionunion类实现:
/** 客户消息类 */@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);
缺点:实现逻辑较为复杂,参数类型验证较多。
2.使用继承方式实现unionunion类实现:
/** 客户消息类 */@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类实现数据体的共存的详细内容。
