มีคีย์เวิร์ดในภาษา java -
สำหรับคลาส หมายความว่าคลาสนั้นไม่สามารถมีคลาสย่อยได้ เช่น มรดกเป็นสิ่งต้องห้าม สิ่งนี้มีประโยชน์เมื่อสร้าง
final
. มันสามารถนำไปใช้กับคลาส, วิธีการ, ตัวแปร (รวมถึงอาร์กิวเมนต์ของวิธีการ) 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 และรับงานที่น่าสนใจและรายได้ดี เอาล่ะ มาเริ่มกันเลย
-
คุณจะพูดอะไรเกี่ยวกับอาร์เรย์เมื่อมีการประกาศ
final
? -
เป็นที่ทราบกันดีว่าคลาส
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 โปรดเพิ่มบล็อกในโปรแกรมแก้ไขข้อความของคุณซึ่งจะช่วยให้คุณสามารถซ่อนเนื้อหาได้ และเมื่อคุณคลิกบล็อกดังกล่าว ก็จะแสดงเนื้อหานี้ คำตอบ:
-
เพราะ อาร์เรย์คือวัตถุ ซึ่ง
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
-
ใช่คุณสามารถ. สิ่งสำคัญคือการเข้าใจการใช้คำหนาม
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 โชคดีทุกคน!
GO TO FULL VERSION