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