CodeGym /وبلاگ جاوا /Random-FA /بیایید در مورد کلمه کلیدی نهایی در جاوا صحبت کنیم
John Squirrels
مرحله
San Francisco

بیایید در مورد کلمه کلیدی نهایی در جاوا صحبت کنیم

در گروه منتشر شد
جاوا این کلمه کلیدی را دارد - نهایی. می توان آن را برای کلاس ها، متدها، متغیرها (از جمله پارامترهای متد) اعمال کرد. برای یک کلاس، کلمه کلیدی نهایی به این معنی است که کلاس نمی تواند کلاس های فرعی داشته باشد، یعنی وراثت ممنوع است... این در هنگام ایجاد اشیاء تغییرناپذیر (غیر قابل تغییر) مفید است. به عنوان مثال، کلاس String به عنوان نهایی اعلام می شود.
public final class String {
}

class SubString extends String { // Compilation error
}
همچنین باید توجه داشته باشم که اصلاح کننده نهایی را نمی توان برای کلاس های انتزاعی (آنهایی که کلمه کلیدی انتزاعی دارند) اعمال کرد، زیرا اینها مفاهیم متقابل هستند. برای یک متد نهایی، تعدیل کننده به این معنی است که نمی توان روش را در زیر کلاس ها لغو کرد. این زمانی مفید است که بخواهیم از تغییر اجرای اصلی جلوگیری کنیم.
public class SuperClass {
    public final void printReport() {
        System.out.println("Report");
    }
}

class SubClass extends SuperClass {
    public void printReport() { //Compilation error
        System.out.println("MyReport");
    }
}
برای متغیرهایی از نوع اولیه، کلمه کلیدی نهایی به این معنی است که مقدار، پس از تخصیص، قابل تغییر نیست. برای متغیرهای مرجع، به این معنی است که پس از تخصیص یک شی، نمی توانید مرجع را به آن شی تغییر دهید. این مهم است! مرجع را نمی توان تغییر داد، اما وضعیت شی را می توان تغییر داد. جاوا 8 مفهوم جدیدی را معرفی کرد: به طور موثر نهایی. این فقط برای متغیرها (از جمله پارامترهای روش) اعمال می شود. نکته اصلی این است که با وجود عدم وجود کلمه کلیدی نهایی، مقدار متغیر پس از مقداردهی اولیه تغییر نمی کند. به عبارت دیگر، کلمه کلیدی نهایی را می توان برای چنین متغیری بدون خطای کامپایل اعمال کرد. به طور موثر متغیرهای نهایی را می توان در کلاس های محلی (کلاس های داخلی محلی)، کلاس های ناشناس (کلاس های داخلی ناشناس) و جریان ها (Stream API) استفاده کرد.
public void someMethod() {
    // In the example below, both a and b are effectively final, since they are assigned values only once:
    int a = 1;
    int b;
    if (a == 2) b = 3;
    else b = 4;
    // c is NOT effectively final since its value changes
    int c = 10;
    c++;

    Stream.of(1, 2).forEach(s-> System.out.println(s + a)); // OK
    Stream.of(1, 2).forEach(s-> System.out.println(s + c)); // Compilation error
}
حالا بیایید یک مصاحبه کوچک داشته باشیم. به هر حال، هدف از تکمیل دوره CodeGym این است که یک توسعه دهنده جاوا شوید و شغلی جالب و پردرآمد پیدا کنید. بنابراین، بیایید شروع کنیم.
  1. در مورد آرایه ای که نهایی اعلام می شود چه می توانیم بگوییم؟

  2. می دانیم که کلاس String تغییر ناپذیر است: کلاس نهایی اعلام می شود. یک مقدار رشته در یک آرایه char که با کلمه کلیدی final مشخص شده است ذخیره می شود.

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];
آیا می توانیم مقدار یک شی String را جایگزین کنیم (بدون تغییر مرجع به شی)؟ اینها سوالات واقعی مصاحبه هستند. و تمرین نشان می دهد که بسیاری از داوطلبان به آنها پاسخ صحیح نمی دهند. درک نحوه استفاده از کلمه کلیدی نهایی، به ویژه برای متغیرهای مرجع، بسیار مهم است. همانطور که در این مورد فکر می کنید، من یک درخواست کوچک از تیم CodeGym خواهم کرد. لطفاً به ویرایشگر متن این امکان را بدهید که بلوکی را اضافه کند که وقتی روی آن کلیک می کنید، محتوای آن نشان داده یا پنهان شود. پاسخ ها:
  1. یک آرایه یک شی است، بنابراین کلمه کلیدی نهایی به این معنی است که وقتی یک مرجع به آرایه اختصاص داده شد، مرجع قابل تغییر نیست. گفته می شود، شما می توانید وضعیت جسم را تغییر دهید.

    final int[] array = {1, 2, 3, 4, 5};
    array[0] = 9;	 // OK, because we're changing the contents of the array: {9, 2, 3, 4, 5}
    array = new int[5]; // Compilation error
  2. بله ما میتوانیم. نکته اصلی این است که بفهمیم کلمه کلیدی نهایی خاردار هنگام استفاده با اشیا به چه معناست. Reflection API را می توان برای جایگزینی مقادیر استفاده کرد.

import java.lang.reflect.Field;

class B {
    public static void main(String[] args) throws Exception {
        String value = "Old value";
        System.out.println(value);

        // Get the String class's value field
        Field field = value.getClass().getDeclaredField("value");
        // Make it mutable
        field.setAccessible(true);
        // Set a new value
        field.set(value, "CodeGym".toCharArray());

        System.out.println(value);

        /* Output:
         * Old value
         * CodeGym
         */
    }
}
لطفاً توجه داشته باشید که اگر سعی می کردیم متغیر نهایی یک نوع اولیه را به این روش تغییر دهیم، هیچ اتفاقی نمی افتاد. پیشنهاد می کنم خودتان را متقاعد کنید: برای مثال یک کلاس جاوا با فیلد int نهایی ایجاد کنید و سعی کنید مقدار آن را با استفاده از Reflection API تغییر دهید. همگی موفق باشید!
نظرات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION