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 @ 2022-10-04 00:15  IT情深  阅读(593)  评论(0编辑  收藏  举报