มีคีย์เวิร์ดในภาษา 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