Java中如何实现类似C++的struct、Dephi的Type Record等结构体方法?
众所周知C,C++中的struct结构体很好用,特别是在结构化数据封装网络传输、跨进程通信、数据交互上非常方便,Delphi中也有这个实现方法,叫record或者packet record,type record;
Delphi中的结构体定义及使用如下:
//定义结构体 type PMsg = ^TMsg; TMsg = record FontName :string[20]; FontColor :Integer; FontSize :Integer; FontStyle :string[4]; Content :array[0..4096] of Char; //不能超过UDP包长 end; //初始化(实例化) procedure TForm1.btnSendClick(Sender: TObject); var Smsg:TMsg; //发送消息结构 begin //.... Smsg.FontName:='宋体' Smsg.XXX:=xxx; ....; //取值则是: XXX:=Smsg.FontName; .....; end; //接收到的数据流直接可以传递给TMsg结构体,然后可以直接获取成员值 procedure TForm1.IdUDPServer1UDPRead(Sender: TObject; AData: TStream; ABinding: TIdSocketHandle); var Rmsg:TMsg; //接收消息结构 OldCount:integer; begin AData.ReadBuffer(Rmsg,AData.Size); //RichEdit1.SelStart:=MaxInt; //RichEdit1.Paragraph.FirstIndent:=0; //RichEdit1.SelAttributes.Color := clBlue; //RichEdit1.Lines.Add(DateTimeToStr(Now)+' : 来自 '+ABinding.PeerIP+' 的消息 :'); //RichEdit1.Paragraph.FirstIndent:=18; // OldCount:=Length(RichEdit1.Text); //showmessage(rmsg.FontName); //showmessage(rmsg.FontStyle); //showmessage(rmsg.Content); //RichEdit1.SelStart:=MaxInt; RichEdit1.SelAttributes.Color :=Rmsg.FontColor; RichEdit1.SelAttributes.Name:=Rmsg.FontName; RichEdit1.SelAttributes.Size:=Rmsg.FontSize; RichEdit1.SelAttributes.Style:=EnStyle(Rmsg.FontStyle); ConvertMsgToFace(RichEdit1,Rmsg.Content,OldCount); end;
Java中要如何实现呢?
众所周知JDK 1.5开始增加了对泛型的支持,但到1.8却仍未加入对struct的支持 。和C/C++,Delphi,C#不同,Java中没有结构体。这是Java作为高级语言的进步,但也使得它在进行网络字节流封装发送上显得捉襟见肘。这里所指的是在进行网络编程,串口编程等需要和某些C或其它较底层语言中结构体定义的协议接口进行通讯时,Java由于缺乏结构体和字节数组之间的有效转换方法,会带来编程上的困境。 按照通常的想法,我们需要自己去手动的一个字节,一个字节的拼凑截取,来实现C语言中结构体定义的数据包。在面对大量接口的时候,这样做显然绝非可行办法。造成这个问题的根本原因是因为JAVA没有指针!,指针这一对内存在字节量级操作的语法特性在Java当中是不成立的。其结果就是在C语言里面通过填充内存块结构体来完成的编程变得复杂。
C/C++里面的结构体在储存(同类型或不同类型的成组的)数据的时候很方便,Java中没有Struct,但是我们可以用类来实现Struct的功能。然后创建类的对象数组,就可以像操作C/C++中的结构体那样。
struct在c#中也有实现,C#中是将结构体写进栈中,而java摒弃了struct目的是统一将对象写入堆中,方便垃圾回收。
所以建议用类代替结构体,毕竟类就是扩展了功能的结构体,而结构体就是类的原形
如果你从前是用C++的,那么你应该知道,在C++中类与结构的唯一区别就是:类定义中默认成员是private域的,而结构定义中默认的为public域。所以你要做的就是把struct变为class。
Java实现方法如下:
package Test_struct; public class struct { public static class dog { private String dogname; private int dogage; private String dogcolor; private boolean dogisgoodboy; private String remark; } public static void main(String[] args) { // 实例化结构体(简单类) dog mydog = new dog(); // 对结构体(简单类)成员进行赋值操作) mydog.dogname = "汪汪"; mydog.dogage = 2; mydog.dogcolor = "black"; mydog.dogisgoodboy = true; mydog.remark = "我是备注内容XXXXX,代表成功记录!"; // 访问结构体(简单类)成员变量值 System.out.println(String.format("狗的名字:%s \n狗的年龄:%d \n狗的颜色:%s \n狗乖吗:%b \n备注内容:%s", mydog.dogname, mydog.dogage, mydog.dogcolor, mydog.dogisgoodboy, mydog.remark)); } }
上图代码执行返回的结果如下:
上面的例子中,如果我想实现上述类结构体数组化,在实例化的时候进行如下操作即可做到:
比如类dog,他的数组就是dog [] xxx = new dog[10];
//创建自定义类数组 dog[] dog1 = new dog[10]; dog1[0] = new dog(); // 创建数组对象,为数组对象开辟空间 dog1[0].dogname = "阿黄"; // 先声明,再创建,之后才能使用 dog1[0].dogage=5; System.out.println(dog1[0].dogname); System.out.println(dog1[0].dogage);
总结:用类来模拟结构不好的地方是:如果遇到结构成员变量很多好几百(复杂的结构体,结构体嵌套再嵌套)就会很麻烦很难实现。
本文来自博客园,作者:IT情深,转载请注明原文链接:https://www.cnblogs.com/wh445306/p/16751934.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?