JavaRush /จาวาบล็อก /Random-TH /สุดท้ายเลย...
Алексей
ระดับ

สุดท้ายเลย...

เผยแพร่ในกลุ่ม
มีคีย์เวิร์ดในภาษา java - final. มันสามารถนำไปใช้กับคลาส, วิธีการ, ตัวแปร (รวมถึงอาร์กิวเมนต์ของวิธีการ) สุดท้ายนี้... - 1สำหรับคลาส หมายความว่าคลาสนั้นไม่สามารถมีคลาสย่อยได้ เช่น มรดกเป็นสิ่งต้องห้าม สิ่งนี้มีประโยชน์เมื่อสร้างimmutableวัตถุ (ไม่เปลี่ยนรูป) เช่นคลาสStringที่ประกาศเป็นfinal.
public final class String{
}

class SubString extends String{ //Compilation error
}
ควรสังเกตด้วยว่าไม่สามารถใช้ตัวดัดแปลงกับคลาสนามธรรมได้ (ด้วยคีย์เวิร์ดabstract) finalเพราะ สิ่งเหล่านี้เป็นแนวคิดที่ไม่เกิดร่วมกัน สำหรับเมธอดfinalหมายความว่าไม่สามารถแทนที่ในคลาสย่อยได้ สิ่งนี้มีประโยชน์เมื่อเราต้องการให้การใช้งานดั้งเดิมไม่ถูกแทนที่
public class SuperClass{
    public final void printReport(){
        System.out.println("Report");
    }
}

class SubClass extends SuperClass{
    public void printReport(){  //Compilation error
        System.out.println("MyReport");
    }
}
สำหรับตัวแปรประเภทดั้งเดิม หมายความว่าเมื่อกำหนดแล้ว จะไม่สามารถเปลี่ยนแปลงค่าได้ สำหรับตัวแปรอ้างอิง หมายความว่าเมื่อกำหนดวัตถุแล้ว การอ้างอิงไปยังวัตถุนั้นจะไม่สามารถเปลี่ยนแปลงได้ มันเป็นสิ่งสำคัญ! ลิงก์ไม่สามารถเปลี่ยนแปลงได้ แต่สถานะของออบเจ็กต์สามารถเปลี่ยนแปลงได้ ด้วย java 8 แนวคิดก็ปรากฏขึ้น - effectively final. ใช้ได้กับตัวแปรเท่านั้น (รวมถึงอาร์กิวเมนต์ของวิธีการ) ประเด็นก็คือ แม้ว่าจะไม่มีคีย์เวิร์ดที่ชัดเจนfinalแต่ค่าของตัวแปรจะไม่เปลี่ยนแปลงหลังจากการกำหนดค่าเริ่มต้น กล่าวอีกนัยหนึ่ง คุณสามารถแทนที่คำสำหรับตัวแปรดังกล่าวได้finalโดยไม่มีข้อผิดพลาดในการคอมไพล์ effectively finalสามารถใช้ตัวแปรภายในคลาสท้องถิ่น ( Local Inner Classes), คลาสที่ไม่ระบุชื่อ ( Anonymous Inner Classes), สตรีม (Stream API)
public void someMethod(){
    // In the example below, both a and b are effectively final, since the values ​​are set once:
    int a = 1;
    int b;
    if (a == 2) b = 3;
    else b = 4;
    // c is NOT effectively final because value changes
    int c = 10;
    c++;

    Stream.of(1, 2).forEach(s-> System.out.println(s + a)); //Ок
    Stream.of(1, 2).forEach(s-> System.out.println(s + c)); //Compilation error
}
เอาล่ะเรามาสัมภาษณ์กันสักหน่อย ท้ายที่สุดแล้ว เป้าหมายของการเรียนหลักสูตร JavaRush คือการเป็น Java Developer และรับงานที่น่าสนใจและรายได้ดี เอาล่ะ มาเริ่มกันเลย
  1. คุณจะพูดอะไรเกี่ยวกับอาร์เรย์เมื่อมีการประกาศfinal?

  2. เป็นที่ทราบกันดีว่าคลาสStringนั้นคือimmutableคลาสที่ถูกประกาศfinalค่าของสตริงจะถูกเก็บไว้ในอาร์เรย์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(โดยไม่เปลี่ยนการอ้างอิงถึงวัตถุ)? นี่เป็นคำถามสัมภาษณ์จริง และดังที่แบบฝึกหัดแสดงให้เห็น หลายคนตอบผิด การทำความเข้าใจการใช้คีย์เวิร์ดfinalโดยเฉพาะอย่างยิ่งสำหรับตัวแปรอ้างอิง เป็นสิ่งสำคัญมาก ในขณะที่คุณกำลังคิด พูดนอกเรื่องอย่างรวดเร็วกับทีม JavaRush โปรดเพิ่มบล็อกในโปรแกรมแก้ไขข้อความของคุณซึ่งจะช่วยให้คุณสามารถซ่อนเนื้อหาได้ และเมื่อคุณคลิกบล็อกดังกล่าว ก็จะแสดงเนื้อหานี้ คำตอบ:
  1. เพราะ อาร์เรย์คือวัตถุ ซึ่งfinalหมายความว่าหลังจากกำหนดการอ้างอิงให้กับวัตถุแล้ว จะไม่สามารถเปลี่ยนแปลงได้อีกต่อไป แต่สถานะของวัตถุสามารถเปลี่ยนแปลงได้

    final int[] array = {1,2,3,4,5};
    array[0] = 9;	//ok, because change the contents of the array - {9,2,3,4,5}
    array = new int[5]; //compile error
  2. ใช่คุณสามารถ. สิ่งสำคัญคือการเข้าใจการใช้คำหนามfinalกับวัตถุ ใช้ ReflectionAPI เพื่อแทนที่ค่า

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 value field in the String class
        Field field = value.getClass().getDeclaredField("value");
        //Let's change it
        field.setAccessible(true);
        //Set new value
        field.set(value, "JavaRush".toCharArray());

        System.out.println(value);

        /* Вывод:
         * Old value
         * JavaRush
         */
    }
}
โปรดทราบว่าหากเราพยายามเปลี่ยนตัวแปรสุดท้ายของประเภทดั้งเดิมด้วยวิธีนี้ จะไม่มีอะไรทำงาน ฉันขอแนะนำให้คุณโน้มน้าวตัวเองในสิ่งนี้: สร้างคลาส Java โดยมีfinal intฟิลด์และลองเปลี่ยนค่าผ่าน Reflection API โชคดีทุกคน!
ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION