۲۹ شهریور ۱۴۰۳

Techboy

اخبار و اطلاعات روز تکنولوژی

مقداردهی اولیه کلاس و شی در جاوا

در اینجا همه چیزهایی است که باید در مورد مقداردهی اولیه کلاس ها و اشیاء جاوا قبل از اجرای آنها در JVM بدانید.

در اینجا همه چیزهایی است که باید در مورد مقداردهی اولیه کلاس ها و اشیاء جاوا قبل از اجرای آنها در JVM بدانید.

کلاس ها و اشیاء در جاوا باید قبل از استفاده مقداردهی اولیه شوند. شما قبلاً یاد گرفته اید که فیلدهای کلاس مقداردهی اولیه می شوند به مقادیر پیش‌فرض زمانی که کلاس‌ها بارگذاری می‌شوند، و اینکه اشیاء از طریق سازنده‌ها مقداردهی اولیه می‌شوند—اما هنوز مقداردهی اولیه‌سازی وجود دارد. این آموزش تمام ویژگی های جاوا را برای مقداردهی اولیه کلاس ها و اشیاء معرفی می کند.

آنچه در این آموزش جاوا خواهید آموخت

  • نحوه تنظیم اولیه کلاس جاوا
  • نحوه کار با بلوک های اولیه سازی کلاس
  • نحوه مقداردهی اولیه اشیاء جاوا

چگونه یک کلاس جاوا را مقداردهی اولیه کنیم

قبل از اینکه پشتیبانی جاوا برای مقداردهی اولیه کلاس را بررسی کنیم، اجازه دهید مراحل اولیه سازی کلاس جاوا را مرور کنیم. فهرست ۱ را در نظر بگیرید.

class SomeClass
{
   static boolean b;
   static byte by;
   static char c;
   static double d;
   static float f;
   static int i;
   static long l;
   static short s;
   static String st;
}

فهرست ۱ کلاس SomeClass را اعلام می‌کند. این کلاس نه فیلد از انواع boolean، byte، char، double، float، int، long، کوتاه و رشته. هنگامی که SomeClass بارگیری می‌شود، بیت‌های هر فیلد روی صفر تنظیم می‌شوند که به صورت زیر تفسیر می‌کنید:

false
۰
u0000
۰.۰
۰.۰
۰
۰
۰
null

فیلدهای کلاس قبلی به طور ضمنی به صفر مقداردهی شدند. با این حال، همانطور که در فهرست ۲ نشان داده شده است، می توانید به طور صریح فیلدهای کلاس را با اختصاص مستقیم مقادیر به آنها مقداردهی اولیه کنید.

class SomeClass
{
   static boolean b = true;
   static byte by = 1;
   static char c = 'A';
   static double d = 2.0;
   static float f = 3.0f;
   static int i = 4;
   static long l = 5000000000L;
   static short s = 20000;
   static String st = "abc";
}

مقدار هر تکلیف باید با نوع فیلد کلاس سازگار باشد. هر متغیر مقدار را مستقیماً ذخیره می کند، به استثنای st. متغیر st ارجاع به یک شی String را ذخیره می کند که حاوی abc است.

ارجاع به فیلدهای کلاس

هنگام مقداردهی اولیه یک فیلد کلاس، قانونی است که آن را به مقدار فیلد کلاسی که قبلاً مقداردهی اولیه شده است، مقداردهی کنید. به عنوان مثال، فهرست ۳ y را به مقدار x مقداردهی می‌کند. هر دو فیلد به ۲ مقداردهی اولیه می شوند.

class SomeClass
{
   static int x = 2;
   static int y = x;

   public static void main(String[] args)
   {
      System.out.println(x);
      System.out.println(y);
   }
}

با این حال، معکوس آن قانونی نیست: شما نمی توانید یک فیلد کلاس را به مقدار یک فیلد کلاس اعلام شده بعدی مقداردهی کنید. کامپایلر جاوا وقتی با این سناریو مواجه می شود، مرجع ارسال غیر قانونی را خروجی می دهد. فهرست ۴ را در نظر بگیرید.

class SomeClass
{
   static int x = y;
   static int y = 2;

   public static void main(String[] args)
   {
      System.out.println(x);
      System.out.println(y);
   }
}

کامپایلر وقتی با static int x = y; مواجه شد، مرجع ارسال غیرقانونی را گزارش می‌کند. این به این دلیل است که کد منبع از بالا به پایین کامپایل شده است و کامپایلر هنوز y را ندیده است. (اگر y به طور صریح مقداردهی اولیه نشده باشد، این پیام را نیز ارسال می کند.)

نحوه کار با بلوک های اولیه سازی کلاس

در برخی موارد، ممکن است بخواهید اولیه سازی های پیچیده مبتنی بر کلاس را انجام دهید. شما این کار را بعد از بارگذاری یک کلاس و قبل از ایجاد هر شی از آن کلاس انجام خواهید داد (با فرض اینکه کلاس یک کلاس کاربردی نباشد). برای این کار می توانید از بلوک اولیه سازی کلاس استفاده کنید.

یک بلوک اولیه سازی کلاس بلوکی از عبارات است که قبل از آن کلمه کلیدی static وارد بدنه کلاس می شود. هنگامی که کلاس بارگذاری می شود، این دستورات اجرا می شوند. فهرست ۵ را در نظر بگیرید.

class Graphics
{
   static double[] sines, cosines;
   static
   {
      sines = new double[360];
      cosines = new double[360];
      for (int i = 0; i < sines.length; i++)
      {
         sines[i] = Math.sin(Math.toRadians(i));
         cosines[i] = Math.cos(Math.toRadians(i));
      }
   }
}

فهرست ۵ یک کلاس Graphics را اعلام می کند که متغیرهای آرایه سینوس و cosines را اعلام می کند. همچنین یک بلوک اولیه سازی کلاس را اعلام می کند که آرایه های ۳۶۰ عنصری را ایجاد می کند که مراجع آنها به سینوس و cosines اختصاص داده می شوند. سپس با فراخوانی sin() و sin() کلاس Math از یک عبارت for برای مقداردهی اولیه این عناصر آرایه به مقادیر سینوسی و کسینوس مناسب استفاده می کند. متدهای code>cos(). (ریاضی بخشی از کتابخانه کلاس استاندارد جاوا است. در مقاله آینده درباره این کلاس و این روش ها صحبت خواهم کرد.)

ترفند عملکرد

از آنجایی که عملکرد برای برنامه های گرافیکی مهم است و از آنجا که دسترسی به عنصر آرایه سریعتر از فراخوانی یک روش است، توسعه دهندگان به ترفندهای عملکردی مانند ایجاد و مقداردهی اولیه آرایه های سینوس و کسینوس متوسل می شوند.

ترکیب اولیه سازهای فیلد کلاس و بلوک های اولیه سازی کلاس

شما می توانید چندین مقداردهی اولیه فیلد کلاس و بلوک های اولیه سازی کلاس را در یک برنامه کاربردی ترکیب کنید. فهرست ۶ مثالی را ارائه می دهد.

class MCFICIB
{
   static int x = 10;

   static double temp = 98.6;

   static
   {
      System.out.println("x = " + x);
      temp = (temp - 32) * 5.0/9.0; // convert to Celsius
      System.out.println("temp = " + temp);
   }

   static int y = x + 5;

   static
   {
      System.out.println("y = " + y);
   }

   public static void main(String[] args)
   {
   }
}

لیست ۶ یک جفت فیلد کلاس (x و y) را اعلام و مقداردهی اولیه می‌کند، و یک جفت مقداردهی اولیه static را اعلام می‌کند. این فهرست را مطابق شکل کامپایل کنید:

javac MCFICIB.java

سپس برنامه به دست آمده را اجرا کنید:

java MCFICIB

شما باید خروجی زیر را مشاهده کنید:

x = 10
temp = 37.0
y = 15

این خروجی نشان می‌دهد که مقداردهی اولیه کلاس به ترتیب از بالا به پایین انجام می‌شود.

روش‌های

()

هنگام کامپایل کردن اولیه سازهای کلاس و بلوک های اولیه سازی کلاس، کامپایلر جاوا بایت کد کامپایل شده را (به ترتیب از بالا به پایین) در روش خاصی به نام () ذخیره می کند. براکت های زاویه ای از تضاد نام جلوگیری می کنند: نمی توانید یک روش () را در کد منبع اعلام کنید زیرا < و > کاراکترهای در زمینه شناسه غیرقانونی هستند.

بعد از بارگیری کلاس، JVM قبل از فراخوانی main() (زمانی که main() وجود دارد، این متد را فراخوانی می‌کند.

بیایید نگاهی به داخل MCFICIB.class بیندازیم. جداسازی جزئی زیر اطلاعات ذخیره شده را برای فیلدهای x، temp و y نشان می‌دهد:

Field #1

۰۰۰۰۰۲۹۰        Access Flags                          ACC_STATIC
۰۰۰۰۰۲۹۲        Name                                  x
۰۰۰۰۰۲۹۴        Descriptor                            I
۰۰۰۰۰۲۹۶        Attributes Count                      0

Field #2

۰۰۰۰۰۲۹۸        Access Flags                          ACC_STATIC
۰۰۰۰۰۲۹a        Name                                  temp
۰۰۰۰۰۲۹c        Descriptor                            D
۰۰۰۰۰۲۹e        Attributes Count                      0

Field #3

۰۰۰۰۰۲a0        Access Flags                          ACC_STATIC
۰۰۰۰۰۲a2        Name                                  y
۰۰۰۰۰۲a4        Descriptor                            I
۰۰۰۰۰۲a6        Attributes Count                      0

خط Descriptor نوع توصیفگر JVM را برای فیلد مشخص می‌کند. نوع با یک حرف نشان داده می شود: I برای int و D برای double.

جداسازی جزئی زیر، توالی دستورالعمل بایت کد را برای روش () نشان می دهد. هر خط با یک عدد اعشاری شروع می شود که آدرس آفست مبتنی بر صفر دستورالعمل بعدی را مشخص می کند:

  ۰        bipush 10
  ۲        putstatic MCFICIB/x I
  ۵        ldc2_w #98.6
  ۸        putstatic MCFICIB/temp D
 ۱۱        getstatic java/lang/System/out Ljava/io/PrintStream;
 ۱۴        new java/lang/StringBuilder
 ۱۷        dup
 ۱۸        invokespecial java/lang/StringBuilder/<init>()V
 ۲۱        ldc "x = "
 ۲۳        invokevirtual java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder;
 ۲۶        getstatic MCFICIB/x I
 ۲۹        invokevirtual java/lang/StringBuilder/append(I)Ljava/lang/StringBuilder;
 ۳۲        invokevirtual java/lang/StringBuilder/toString()Ljava/lang/String;
 ۳۵        invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V
 ۳۸        getstatic MCFICIB/temp D
 ۴۱        ldc2_w #32
 ۴۴        dsub
 ۴۵        ldc2_w #5
 ۴۸        dmul
 ۴۹        ldc2_w #9
 ۵۲        ddiv
 ۵۳        putstatic MCFICIB/temp D
 ۵۶        getstatic java/lang/System/out Ljava/io/PrintStream;
 ۵۹        new java/lang/StringBuilder
 ۶۲        dup
 ۶۳        invokespecial java/lang/StringBuilder/<init>()V
 ۶۶        ldc "temp = "
 ۶۸        invokevirtual java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder;
 ۷۱        getstatic MCFICIB/temp D
 ۷۴        invokevirtual java/lang/StringBuilder/append(D)Ljava/lang/StringBuilder;
 ۷۷        invokevirtual java/lang/StringBuilder/toString()Ljava/lang/String;
 ۸۰        invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V
 ۸۳        getstatic MCFICIB/x I
 ۸۶        iconst_5
 ۸۷        iadd
 ۸۸        putstatic MCFICIB/y I
 ۹۱        getstatic java/lang/System/out Ljava/io/PrintStream;
 ۹۴        new java/lang/StringBuilder
 ۹۷        dup
 ۹۸        invokespecial java/lang/StringBuilder/<init>()V
۱۰۱        ldc "y = "
۱۰۳        invokevirtual java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder;
۱۰۶        getstatic MCFICIB/y I
۱۰۹        invokevirtual java/lang/StringBuilder/append(I)Ljava/lang/StringBuilder;
۱۱۲        invokevirtual java/lang/StringBuilder/toString()Ljava/lang/String;
۱۱۵        invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V
۱۱۸        return

توالی دستورالعمل از offset 0 تا offset 2 معادل اولیه ساز فیلد کلاس زیر است:

static int x = 10;

توالی دستورالعمل از offset 5 تا offset 8 معادل اولیه ساز فیلد کلاس زیر است:

static double temp = 98.6;

توالی دستورالعمل از افست ۱۱ تا آفست ۸۰ معادل بلوک اولیه سازی کلاس زیر است:

static
{
   System.out.println("x = " + x);
   temp = (temp - 32) * 5.0/9.0; // convert to Celsius
   System.out.println("temp = " + temp);
}

توالی دستورالعمل از offset 83 تا offset 88 معادل اولیه ساز فیلد کلاس زیر است:

static int y = x + 5;

توالی دستورالعمل از offset 91 تا offset 115 معادل بلوک اولیه سازی کلاس زیر است:

static
{
   System.out.println("y = " + y);
}

در نهایت، دستور return در offset 118 اجرا را از () به بخشی از JVM برمی‌گرداند که این متد را فراخوانی کرده است.

در مورد معنای بایت نگران نباشید

نکته مهم در این تمرین این است که ببینید تمام کدهای موجود در فهرست ۶ فهرست ۶ در فهرست اولیه سازهای فیلد کلاس و بلوک های مقداردهی اولیه کلاس در متد () قرار دارند و به ترتیب از بالا به پایین اجرا می شوند. .

نحوه مقداردهی اولیه اشیاء جاوا

بعد از اینکه یک کلاس بارگذاری و مقداردهی اولیه شد، اغلب می خواهید اشیایی از کلاس ایجاد کنید. همانطور که در معرفی اخیر من برای برنامه نویسی با کلاس ها و آبجکت ها یاد گرفتید. /a>، یک شی را از طریق کدی که در سازنده کلاس قرار می دهید مقداردهی اولیه می کنید. فهرست ۷ را در نظر بگیرید.

class City
{
   private String name;
   int population;

   City(String name, int population)
   {
      this.name = name;
      this.population = population;
   }

   @Override
   public String toString()
   {
      return name + ": " + population;
   }

   public static void main(String[] args)
   {
      City newYork = new City("New York", 8491079);
      System.out.println(newYork); // Output: New York: 8491079
   }
}

فهرست ۷ یک کلاس City را با فیلدهای name و population اعلام می‌کند. هنگامی که یک شی City ایجاد می شود، سازنده City (نام رشته، جمعیت int) فراخوانی می شود تا این فیلدها را به آرگومان های سازنده فراخوانده شده مقداردهی کند. (من همچنین روش Public String toString() Object را نادیده گرفته ام تا نام شهر و مقدار جمعیت را به راحتی به عنوان یک رشته برگردانم. System.out.println () در نهایت این متد را فراخوانی می کند تا نمایش رشته شیء را که خروجی آن است، برگرداند.)

قبل از فراخوانی سازنده، name و population حاوی چه مقادیری هستند؟ می توانید با وارد کردن System.out.println(this.name) متوجه شوید. System.out.println(this.population); در شروع سازنده. پس از کامپایل کردن کد منبع (javac City.java) و اجرای برنامه (java Citynull را برای name مشاهده خواهید کرد. و ۰ برای جمعیت. عملگر new فیلدهای شی (نمونه) یک شی را قبل از اجرای سازنده صفر می کند.

همانند فیلدهای کلاس، می توانید به صراحت فیلدهای شی را مقداردهی اولیه کنید. برای مثال، می‌توانید نام رشته = "نیویورک"؛ یا int جمعیت = ۸۴۹۱۰۷۹; را مشخص کنید. با این حال، معمولاً با انجام این کار چیزی به دست نمی آید، زیرا این فیلدها در سازنده مقداردهی اولیه می شوند. تنها مزیتی که می توانم به آن فکر کنم این است که یک مقدار پیش فرض را به یک فیلد شی اختصاص دهیم. این مقدار زمانی استفاده می شود که سازنده ای را فراخوانی می کنید که فیلد را مقداردهی اولیه نمی کند:

int numDoors = 4; // default value assigned to numDoors

Car(String make, String model, int year)
{
   this(make, model, year, numDoors);
}

Car(String make, String model, int year, int numDoors)
{
   this.make = make;
   this.model = model;
   this.year = year;
   this.numDoors = numDoors;
}

آینه سازی شیء، مقدار دهی اولیه کلاس را آینه می کند

به غیر از سازنده ها، مقداردهی اولیه شی منعکس کننده مقداردهی اولیه کلاس است. به جای اولیه سازهای فیلد کلاس، مقداردهی اولیه فیلد شی دارید. علاوه بر این، به جای بلوک های اولیه سازی کلاس، بلوک های اولیه سازی شی دارید. همچنین می‌توانید به فیلدهای شیء که قبلاً اعلام شده و مقداردهی اولیه شده است ارجاع دهید، اما نمی‌توانید به فیلدهای شیء اعلام شده و مقداردهی اولیه ارجاع دهید. همه این مفاهیم در فهرست ۸ نشان داده شده است.

class Mirror
{
   int x = 2;
   int y = x;

   {
      System.out.println("x = " + x);
      System.out.println("y = " + y);
   }

   public static void main(String[] args)
   {
      Mirror mirror = new Mirror();
   }
}

فهرست ۸ نشان می دهد که یک بلوک اولیه سازی شی بلوکی از عبارات معرفی شده به بدنه کلاس است. بر خلاف یک بلوک مقداردهی اولیه کلاس، یک بلوک مقداردهی اولیه شی با هیچ چیز پیشوندی ندارد. از آنجایی که می‌توانید یک شی را در یک سازنده مقداردهی اولیه کنید، تنها کاربرد خوب بلوک اولیه‌سازی شی، در زمینه یک کلاس ناشناس است که سازنده‌ای ندارد و در مقاله آینده درباره آن صحبت خواهم کرد.

فهرست ۸ (javac Mirror.java) را کامپایل کنید و برنامه به دست آمده را اجرا کنید (java Mirror). خروجی زیر را خواهید دید:

x = 2
y = 2

ترکیب سازنده ها و مقداردهی اولیه فیلد شی و بلوک های اولیه سازی شی

شما می توانید چندین سازنده، مقداردهی اولیه فیلد شی و بلوک های اولیه سازی شی را در یک برنامه کاربردی ترکیب کنید. فهرست ۹ یک مثال ارائه می دهد.

class MCOFIOIB
{
   MCOFIOIB()
   {
      System.out.println("MCOFIOIB() called");
   }

   int x = 5;
   {
      x += 6;
   }

   int i;

   MCOFIOIB(int i)
   {
      this.i = i;
      System.out.println("MCOFIOIB(i) called: i = " + i);
   }

   {
      System.out.println("i = " + i);
      System.out.println("x = " + x);
   }

   public static void main(String[] args)
   {
      new MCOFIOIB();
      System.out.println();
      new MCOFIOIB(6);
   }
}

لیست ۹ یک جفت سازنده (MCOFIOIB() و MCOFIOIB(int i))، یک جفت فیلد شی (x) را اعلام می‌کند. و i)، و یک جفت بلوک مقداردهی اولیه شی. این فهرست را به صورت زیر جمع آوری کنید:

javac MCOFIOIB.java

سپس برنامه به دست آمده را اجرا کنید:

java MCOFIOIB

شما باید خروجی زیر را مشاهده کنید:

i = 0
x = 11
MCOFIOIB() called

i = 0
x = 11
MCOFIOIB(i) called: i = 6

این خروجی از ایجاد دو شی MCOFIOIB است. قسمت اول از new MCOFIOIB(); و قسمت دوم از new MCOFIOIB(6); سرچشمه می گیرد. هر قسمت نشان می دهد که مقداردهی اولیه فیلد شی و بلوک های اولیه سازی شی قبل از اجرای سازنده اجرا می شوند. علاوه بر این، نشان می دهد که مقداردهی اولیه فیلد شی و بلوک های اولیه سازی شی به ترتیب بالا به پایین اجرا می شوند. (x باید قبل از خروجی x = 11 به ۱۱ مقداردهی اولیه می شد.)

روش های

()

اگر بخواهید بایت کدی را که کامپایلر برای MCOFIOIB.class تولید می کند بررسی کنید، به جای سازنده، متدهای () را مشاهده خواهید کرد. JVM این روش ها را به جای سازنده ها فراخوانی می کند.

همچنین می‌توانید جداسازی جزئی زیر فیلدهای x و i را مشاهده کنید:

Field #1

۰۰۰۰۰۲۶d        Access Flags
۰۰۰۰۰۲۶f        Name                                  x
۰۰۰۰۰۲۷۱        Descriptor                            I
۰۰۰۰۰۲۷۳        Attributes Count                      0

Field #2

۰۰۰۰۰۲۷۵        Access Flags
۰۰۰۰۰۲۷۷        Name                                  i
۰۰۰۰۰۲۷۹        Descriptor                            I
۰۰۰۰۰۲۷b        Attributes Count                      0

در مرحله بعد، اطلاعات و دنباله بایت کد زیر را برای سازنده MCOFIOIB() مشاهده خواهید کرد:

 ۰        aload_0
 ۱        invokespecial java/lang/Object/()V
 ۴        aload_0
 ۵        iconst_5
 ۶        putfield MCOFIOIB/x I
 ۹        aload_0
۱۰        dup
۱۱        getfield MCOFIOIB/x I
۱۴        bipush 6
۱۶        iadd
۱۷        putfield MCOFIOIB/x I
۲۰        getstatic java/lang/System/out Ljava/io/PrintStream;
۲۳        new java/lang/StringBuilder
۲۶        dup
۲۷        invokespecial java/lang/StringBuilder/()V
۳۰        ldc "i = "
۳۲        invokevirtual java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder;
۳۵        aload_0
۳۶        getfield MCOFIOIB/i I
۳۹        invokevirtual java/lang/StringBuilder/append(I)Ljava/lang/StringBuilder;
۴۲        invokevirtual java/lang/StringBuilder/toString()Ljava/lang/String;
۴۵        invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V
۴۸        getstatic java/lang/System/out Ljava/io/PrintStream;
۵۱        new java/lang/StringBuilder
۵۴        dup
۵۵        invokespecial java/lang/StringBuilder/()V
۵۸        ldc "x = "
۶۰        invokevirtual java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder;
۶۳        aload_0
۶۴        getfield MCOFIOIB/x I
۶۷        invokevirtual java/lang/StringBuilder/append(I)Ljava/lang/StringBuilder;
۷۰        invokevirtual java/lang/StringBuilder/toString()Ljava/lang/String;
۷۳        invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V
۷۶        getstatic java/lang/System/out Ljava/io/PrintStream;
۷۹        ldc "MCOFIOIB() called"
۸۱        invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V
۸۴        return

توالی دستورالعمل از آفست ۰ تا آفست ۱ معادل فراخوانی سازنده بدون آرگومان سوپرکلاس Object است:

new Object();

در حال فراخوانی سازنده ها

وقتی کلاسی کلاس دیگری را گسترش نمی‌دهد، متد () با بایت کد شروع می‌شود تا سازنده Object() را فراخوانی کند. هنگامی که سازنده با super() شروع می شود، () با بایت کد شروع می شود تا سازنده superclass را فراخوانی کند. هنگامی که سازنده با this() (برای فراخوانی سازنده دیگری در همان کلاس) شروع می شود، () با دنباله بایت کد برای فراخوانی سازنده دیگر شروع می شود. حاوی کدی برای فراخوانی سازنده سوپرکلاس نیست.

توالی دستورالعمل از افست ۴ تا افست ۱۷ معادل بلوک اولیه سازی کلاس زیر است:

int x = 5;
{
   x += 6;
}

توالی دستورالعمل از offset 20 تا offset 73 دومین بلوک اولیه سازی شی را اجرا می کند:

{
   System.out.println("i = " + i);
   System.out.println("x = " + x);
}

توالی دستورالعمل از offset 76 تا offset 84 کد سازنده MCOFIOIB() را اجرا می‌کند و اجرا را به فراخوان سازنده برمی‌گرداند.

باز هم، نگران معنای بایت کد نباشید. نکته مهمی که باید به خاطر بسپارید ترتیب اولیه سازی است. وقتی MCOFIOIB() را فرا می خوانید، وظایف زیر انجام می شود:

  1. ابتدا سازنده noargument superclass فراخوانی می شود.
  2. راه‌اندازی‌کننده‌های فیلد شی و بلوک‌های اولیه‌سازی شی، سپس به ترتیب از بالا به پایین اجرا می‌شوند.
  3. کد سازنده آخرین بار اجرا می شود.

برای اختصار، دنباله بایت کد را برای سازنده MCOFIOIB(int i) ارائه نمی کنم. بسیار شبیه به MCOFIOIB() است. تنها تفاوت این است که کد نهایی که باید اجرا شود کد MCOFIOIB(int i) است و نه کد MCOFIOIB().

نتیجه گیری

در این آموزش جاوا، نحوه استفاده از مقداردهی اولیه‌های فیلد کلاس و بلوک‌های مقداردهی اولیه کلاس برای مقداردهی اولیه کلاس‌ها، و نحوه استفاده از سازنده‌ها، مقداردهی اولیه‌های فیلد شی و بلوک‌های مقداردهی اولیه برای اشیاء را یاد گرفته‌اید. در حالی که نسبتا ساده است، مقداردهی اولیه کلاس و شی حیاتی است: JVM باید کلاس ها و اشیاء را قبل از استفاده از آنها مقداردهی اولیه کند.

اکنون که می دانید مقداردهی اولیه چگونه کار می کند، تا حد زیادی کاوش خود را در مورد ویژگی های کلاس و زبان شی جاوا تکمیل کرده اید. آموزش بعدی این مجموعه به رابط‌ها می‌پردازد، موضوعی کمی پیشرفته‌تر برای توسعه‌دهندگان مبتدی جاوا.

بعدی: رابط ها در جاوا

برای درس بعدی خود آماده هستید؟ به: اینترفیس ها در جاوا بروید و نحوه تبدیل کلاس های ساده را بیاموزید به رابط های جاوا قابل استفاده مجدد.