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);

总结:用类来模拟结构不好的地方是:如果遇到结构成员变量很多好几百(复杂的结构体,结构体嵌套再嵌套)就会很麻烦很难实现。

posted @   IT情深  阅读(641)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示