ความแตกต่างระหว่างคงที่และสุดท้าย?


174

ฉันสับสนระหว่างstaticและfinalคำหลักในjava Java

แตกต่างกันอย่างไร

คำตอบ:


238

คำหลักคงที่สามารถใช้ใน 4 สถานการณ์

  • ตัวแปรสแตติก
  • วิธีการคงที่
  • บล็อกคงของรหัส
  • คลาสที่ซ้อนกันแบบคงที่

ลองดูที่ตัวแปรสแตติกและเมธอดแบบสแตติกก่อน

ตัวแปรแบบคงที่

  • มันเป็นตัวแปรที่เป็นของชั้นเรียนและไม่ให้วัตถุ (เช่น)
  • ตัวแปรสแตติกจะเริ่มต้นได้เพียงครั้งเดียวเมื่อเริ่มต้นการดำเนินการ ตัวแปรเหล่านี้จะเริ่มต้นก่อนที่จะเริ่มต้นของตัวแปรอินสแตนซ์ใด ๆ
  • สำเนาเดียวที่จะแบ่งปันโดยอินสแตนซ์ทั้งหมดของชั้นเรียน
  • ตัวแปรสแตติกสามารถเข้าถึงได้โดยตรงโดยชื่อคลาสและไม่ต้องการวัตถุใด ๆ
  • ไวยากรณ์: Class.variable

วิธีการคงที่

  • มันเป็นวิธีการที่เป็นของชั้นเรียนและไม่ให้วัตถุ (เช่น)
  • วิธีการคงที่สามารถเข้าถึงข้อมูลคงที่เท่านั้น มันไม่สามารถเข้าถึงข้อมูลที่ไม่คงที่ (ตัวแปรอินสแตนซ์) เว้นแต่จะมี / สร้างอินสแตนซ์ของคลาส
  • วิธีการคงที่สามารถเรียกวิธีการคงที่อื่น ๆ เท่านั้นและไม่สามารถเรียกวิธีการที่ไม่คงที่จากมันเว้นแต่ว่ามันจะมี / สร้างอินสแตนซ์ของชั้นเรียน
  • วิธีการคงที่สามารถเข้าถึงได้โดยตรงโดยชื่อชั้นและไม่ต้องการวัตถุใด ๆ
  • ไวยากรณ์: Class.methodName()
  • วิธีการคงที่ไม่สามารถอ้างถึงthisหรือsuperคำหลักในอย่างไรก็ตาม

ชั้นคงที่

Java ยังมี "คลาสที่ซ้อนกันแบบคงที่" คลาสที่ซ้อนแบบคงที่เป็นเพียงคลาสที่ไม่มีการอ้างอิงถึงอินสแตนซ์ของคลาสภายนอก

คลาสที่ซ้อนกันแบบคงที่สามารถมีวิธีการอินสแตนซ์และวิธีการแบบคงที่

ไม่มีสิ่งเช่นระดับคงที่ระดับสูงสุดใน Java

หมายเหตุด้านข้าง:

วิธีการหลักคือstaticเนื่องจากมันจะต้องสามารถเข้าถึงได้สำหรับแอปพลิเคชันในการทำงานก่อนที่จะเริ่มการอินสแตนซ์ใด ๆ

final คีย์เวิร์ดถูกใช้ในหลาย ๆ บริบทเพื่อกำหนดเอนทิตีซึ่งไม่สามารถเปลี่ยนแปลงได้ในภายหลัง

  • finalชั้นไม่สามารถ subclassed สิ่งนี้ทำเพื่อเหตุผลด้านความปลอดภัยและประสิทธิภาพ ดังนั้นหลายห้องสมุดมาตรฐาน Java ชั้นเรียนfinalเช่นและjava.lang.System java.lang.Stringวิธีการทั้งหมดในชั้นเรียนโดยปริยายfinalfinal

  • finalวิธีการไม่สามารถแทนที่โดย subclasses สิ่งนี้ใช้เพื่อป้องกันพฤติกรรมที่ไม่คาดคิดจากคลาสย่อยที่เปลี่ยนวิธีการที่อาจมีความสำคัญต่อฟังก์ชันหรือความสอดคล้องของคลาส

  • finalตัวแปรเท่านั้นที่สามารถเริ่มต้นได้ครั้งเดียวทั้งผ่านการเริ่มต้นหรือคำสั่งมอบหมาย ไม่จำเป็นต้องเริ่มต้นที่จุดประกาศ: สิ่งนี้เรียกว่าblank finalตัวแปร ตัวแปรอินสแตนซ์สุดท้ายที่ว่างเปล่าของคลาสจะต้องกำหนดอย่างแน่นอนในตอนท้ายของตัวสร้างทุกคลาสที่มีการประกาศ ในทำนองเดียวกันตัวแปรคงที่สุดท้ายที่ว่างเปล่าจะต้องได้รับมอบหมายอย่างแน่นอนในการเริ่มต้นคงที่ของชั้นเรียนที่มีการประกาศ; มิฉะนั้นจะเกิดข้อผิดพลาดในการคอมไพล์ในทั้งสองกรณี

หมายเหตุ: หากตัวแปรเป็นการอ้างอิงนั่นหมายความว่าตัวแปรนั้นไม่สามารถถูกโยงใหม่เพื่ออ้างอิงวัตถุอื่นได้ แต่วัตถุที่อ้างถึงยังคงไม่แน่นอนถ้าเริ่มต้นไม่แน่นอน

เมื่อคลาสภายในที่ไม่ระบุชื่อถูกกำหนดไว้ภายในเนื้อความของเมธอดตัวแปรทั้งหมดที่ประกาศfinalในขอบเขตของเมธอดนั้นสามารถเข้าถึงได้จากภายในคลาสภายใน เมื่อได้รับมอบหมายแล้วค่าของตัวแปรสุดท้ายจะไม่สามารถเปลี่ยนแปลงได้


5
(ฉันไม่ได้ลงคะแนนคุณ) การชี้แจงเพิ่มเติมบางอย่าง: "วิธีการแบบคงที่สามารถเข้าถึงข้อมูลแบบคงที่เท่านั้นมันไม่สามารถเข้าถึงข้อมูลแบบไม่คงที่ (ตัวแปรอินสแตนซ์)" - จนกว่ามันจะมี / สร้างอินสแตนซ์ของชั้นเรียน "วิธีการแบบคงที่สามารถเรียกวิธีการแบบคงที่อื่นเท่านั้นและไม่สามารถเรียกวิธีการแบบไม่คงที่จากนั้น" - เว้นแต่ว่ามันจะมี / สร้างตัวอย่างของชั้นเรียน
xagyg

1
ในวิธีการคงที่คำอธิบายไวยากรณ์คุณพูดผิดฉันคิดว่า อาจเป็นClass.methodName()
Mdhar9e

เราสามารถมีคลาสที่คงที่ได้เช่นกัน ทำการแก้ไขในคำตอบของคุณ ขอบคุณ :)
Madhusudan

ในฐานะของ Java 8 คลาสนิรนาม (และแลมบ์ดา) สามารถเข้าถึงตัวแปรสุดท้ายได้อย่างมีประสิทธิภาพและไม่ จำกัด คำหลักสุดท้าย
akhil_mittal

38

คงหมายถึงมันเป็นของชั้นไม่ได้เป็นเช่นนี้หมายถึงว่ามีเพียงหนึ่งสำเนาของตัวแปร / วิธีการที่ใช้ร่วมกันระหว่างทุกกรณีโดยเฉพาะอย่างยิ่งระดับ

public class MyClass {
    public static int myVariable = 0; 
}

//Now in some other code creating two instances of MyClass
//and altering the variable will affect all instances

MyClass instance1 = new MyClass();
MyClass instance2 = new MyClass();

MyClass.myVariable = 5;  //This change is reflected in both instances

ขั้นสุดท้ายไม่เกี่ยวข้องทั้งหมดเป็นวิธีการกำหนดค่าเริ่มต้นครั้งเดียวเท่านั้น คุณสามารถเริ่มต้นเมื่อกำหนดตัวแปรหรือภายในนวกรรมิกไม่มีที่อื่น

หมายเหตุหมายเหตุเกี่ยวกับวิธีการขั้นสุดท้ายและชั้นเรียนสุดท้ายนี้เป็นวิธีการที่ระบุอย่างชัดเจนว่าวิธีการหรือชั้นเรียนไม่สามารถแทนที่ / ขยายตามลำดับ

Extra Reading ดังนั้นในหัวข้อของสแตติกเรากำลังพูดถึงการใช้งานอื่น ๆ ที่มันอาจมีบางครั้งมันถูกใช้ในบล็อกคงที่ เมื่อใช้ตัวแปรแบบคงที่บางครั้งจำเป็นต้องตั้งค่าตัวแปรเหล่านี้ก่อนใช้คลาส แต่น่าเสียดายที่คุณไม่ได้รับตัวสร้าง นี่คือที่ที่คำหลักคงที่เข้ามา

public class MyClass {

    public static List<String> cars = new ArrayList<String>();

    static {
        cars.add("Ferrari");
        cars.add("Scoda");
    }

}

public class TestClass {

    public static void main(String args[]) {
        System.out.println(MyClass.cars.get(0));  //This will print Ferrari
    }
}

คุณต้องไม่สับสนกับ initializer บล็อคที่เรียกว่า Constructor ต่อ instance


การป้อนข้อมูลต่อไปนี้ให้โดยคุณสามารถที่จะล้างความสับสนขอบคุณทั้งหมด ...final is entirely unrelated, it is a way of defining a once only initialization. You can either initialize when defining the variable or within the constructor, nowhere else.
Prashant thakre

2
เรียบง่ายและชัดเจนตามที่ควรจะเป็น คำตอบที่ได้รับการยอมรับเป็นเพียง .... verbose

22

ทั้งสองไม่เหมือนกันจริงๆ staticสาขาเป็นสาขาที่ไม่ได้เป็นเช่นใด ๆ โดยเฉพาะอย่างยิ่งของชั้น

class C {
    public static int n = 42;
}

ที่นี่staticฟิลด์nไม่ได้เชื่อมโยงกับอินสแตนซ์ใด ๆ โดยเฉพาะCแต่กับคลาสทั้งหมดโดยทั่วไป (ซึ่งเป็นเหตุผลที่C.nสามารถใช้เพื่อเข้าถึงได้) คุณยังสามารถใช้อินสแตนซ์ของCการเข้าถึงได้nหรือไม่ ใช่ - แต่ไม่ถือว่าเป็นแนวปฏิบัติที่ดีโดยเฉพาะ

final ในทางกลับกันบ่งชี้ว่าตัวแปรเฉพาะไม่สามารถเปลี่ยนแปลงได้หลังจากที่เริ่มต้นแล้ว

class C {
    public final int n = 42;
}

ที่นี่จะไม่สามารถกำหนดเพราะมันเป็นn finalความแตกต่างอีกอย่างหนึ่งคือตัวแปรใด ๆ ที่สามารถประกาศfinalได้ในขณะที่ตัวแปรทุกตัวไม่สามารถประกาศคงที่ได้

นอกจากนี้คลาสสามารถประกาศfinalซึ่งบ่งชี้ว่าพวกเขาไม่สามารถขยาย:

final class C {}

class B extends C {}  // error!

ในทำนองเดียวกันสามารถประกาศวิธีสุดท้ายเพื่อบ่งชี้ว่าพวกเขาไม่สามารถoverridenโดยชั้นขยาย:

class C {
    public final void foo() {}
}

class B extends C {
    public void foo() {}  // error!
}

ขอบคุณสำหรับอินพุต รหัสแสดงข้อผิดพลาด: class C {public static int n = 42; } มันบอกว่าเขตข้อมูลไม่สามารถประกาศคงที่ในประเภทที่ไม่คงที่ ทำไมฉันถึงประกาศหรือทำ Cn ไม่ได้?
TechnoCorner

@TechnoCorner เฉพาะคลาสระดับบนสุด ( publicคลาสที่เป็นไปได้ที่กำหนดไฟล์) หรือstaticคลาสภายในสามารถกำหนดstaticตัวแปรได้ คลาสภายในอื่น ๆ เป็นอินสแตนซ์ของคลาสภายนอกและไม่มีตัวแปรแบบสแตติก
zapl

17

สุดท้าย -

1) เมื่อเราใช้คำสำคัญ " สุดท้าย " กับตัวแปรค่าของตัวแปรนั้นจะยังคงที่ (หรือ) เมื่อเราประกาศตัวแปรเป็นครั้งสุดท้ายค่าค่าของตัวแปรนั้นจะไม่สามารถเปลี่ยนแปลงได้

2) มันจะมีประโยชน์เมื่อค่าตัวแปรไม่เปลี่ยนแปลงในช่วงเวลาชีวิตของโปรแกรม

คงที่ -

1) เมื่อเราใช้คำสำคัญ " คงที่ " กับตัวแปรก็หมายความว่ามันเป็นของชั้นเรียน
2) เมื่อเราใช้คำสำคัญ " คงที่ " กับวิธีการมันหมายถึงวิธีการที่สามารถเข้าถึงได้โดยไม่ต้องสร้างตัวอย่างของชั้นเรียน


12

static หมายความว่ามีตัวแปรเพียงหนึ่งสำเนาในหน่วยความจำที่แบ่งใช้โดยอินสแตนซ์ทั้งหมดของคลาส

finalคำหลักก็หมายความว่าค่าที่ไม่สามารถเปลี่ยนแปลงได้ โดยไม่ต้องfinalวัตถุใด ๆ สามารถเปลี่ยนค่าของตัวแปร


3

คงที่และครั้งสุดท้ายมีความแตกต่างใหญ่:

ตัวแปรหรือคลาสแบบสแตติกจะพร้อมใช้งานจาก (สวยมาก) ทุกที่ สุดท้ายเป็นเพียงคำหลักที่หมายความว่าตัวแปรไม่สามารถเปลี่ยนแปลงได้ ดังนั้นถ้ามี:

public class Test{    
   public final int first = 10;
   public static int second = 20;

   public Test(){
     second = second + 1
     first = first + 1;
   }
}

โปรแกรมจะทำงานจนกว่าจะพยายามเปลี่ยนจำนวนเต็ม "แรก" ซึ่งจะทำให้เกิดข้อผิดพลาด นอกคลาสนี้คุณจะสามารถเข้าถึงตัวแปร "แรก" เท่านั้นหากคุณสร้างอินสแตนซ์ของคลาส ตรงกันข้ามกับ "ที่สอง" ซึ่งมีอยู่ตลอดเวลา


3

คิดว่าวัตถุเช่นลำโพง ถ้าลำโพงเป็นคลาสมันจะมีตัวแปรต่าง ๆ เช่นระดับเสียงแหลมเสียงเบสสี ฯลฯ คุณกำหนดฟิลด์เหล่านี้ทั้งหมดในขณะที่กำหนดคลาสลำโพง ตัวอย่างเช่นคุณประกาศฟิลด์สีด้วยตัวแก้ไขแบบคงที่ซึ่งหมายความว่าคุณกำลังบอกคอมไพเลอร์ว่ามีสำเนาของตัวแปรนี้อยู่หนึ่งชุดโดยไม่คำนึงว่ากี่ครั้งที่คลาสจะถูกสร้างอินสแตนซ์

ภาษณ์

static final String color = "Black"; 

จะทำให้แน่ใจว่าเมื่อใดก็ตามที่คลาสนี้ถูกสร้างอินสแตนซ์ค่าของฟิลด์สีจะเป็น "สีดำ" ยกเว้นว่ามันจะไม่เปลี่ยนแปลง

public class Speaker {

static String color = "Black";

}

public class Sample {

public static void main(String args[]) {
    System.out.println(Speaker.color); //will provide output as "Black"
            Speaker.color = "white";
    System.out.println(Speaker.color);  //will provide output as "White"
}}

หมายเหตุ: ตอนนี้เมื่อคุณเปลี่ยนสีของลำโพงเป็นครั้งสุดท้ายรหัสนี้จะไม่ดำเนินการเพราะคำหลักสุดท้ายทำให้แน่ใจว่าค่าของสนามไม่เปลี่ยนแปลง

public class Speaker {

static final String color = "Black";

}

public class Sample {

public static void main(String args[]) {
    System.out.println(Speaker.color); //should provide output as "Black"
            Speaker.color = "white"; //Error because the value of color is fixed.  
    System.out.println(Speaker.color); //Code won't execute.
}}

คุณสามารถคัดลอก / วางรหัสนี้ลงในโปรแกรมจำลองของคุณโดยตรงและลอง


2

ความแตกต่างได้ง่าย

Final : หมายความว่า Value ของตัวแปรเป็น Final และจะไม่เปลี่ยนแปลงทุกที่ หากคุณบอกว่า final x = 5 หมายความว่า x ไม่สามารถเปลี่ยนแปลงค่าของมันได้ถือเป็นที่สิ้นสุดสำหรับทุกคน

คงที่: หมายความว่ามันมีเพียงวัตถุเดียว สมมติว่าคุณมี x = 5 ในหน่วยความจำมี x = 5 และมีอยู่ในคลาส ถ้าคุณสร้างวัตถุหรืออินสแตนซ์ของคลาสซึ่งหมายความว่ามีกล่องเฉพาะที่แสดงถึงคลาสนั้นและตัวแปรและวิธีการ และถ้าคุณสร้างวัตถุหรืออินสแตนซ์อื่นของคลาสนั้นหมายความว่ามีกล่องสองกล่องของคลาสเดียวกันนั้นซึ่งมี x ที่แตกต่างกันในหน่วยความจำ และถ้าคุณเรียกทั้งสองในตำแหน่งที่แตกต่างกันและเปลี่ยนค่าของพวกเขาแล้วค่าของพวกเขาจะแตกต่างกัน กล่อง 1 มี x ซึ่งมี x = 5 และกล่อง 2 มี x = 6 แต่ถ้าคุณสร้าง x แบบคงที่หมายความว่าไม่สามารถสร้างได้อีก คุณสามารถสร้างวัตถุของคลาส แต่วัตถุนั้นจะไม่มี x ที่แตกต่างกันในพวกเขา ถ้า x เป็นค่าคงที่จากนั้นกล่อง 1 และกล่อง 2 ทั้งสองจะมีค่า x เท่ากันซึ่งมีค่าเป็น 5 ใช่ฉันสามารถเปลี่ยนค่าของสแตติกได้ทุกที่ที่ไม่ใช่ค่าสุดท้าย ดังนั้นถ้าฉันบอกว่ากล่องที่ 1 มี x และฉันเปลี่ยนค่าเป็น x = 5 และหลังจากนั้นฉันทำอีกกล่องซึ่งก็คือ box2 และฉันเปลี่ยนค่าของ box2 x เป็น x = 6 ดังนั้นเมื่อ X เป็นค่าคงที่ทั้งสองกล่องจะมีค่า x เท่ากัน และกล่องทั้งสองจะให้ค่าของกล่องเป็น 6 เพราะ box2 เขียนทับค่า 5 ถึง 6

ทั้งสุดท้ายและคงที่แตกต่างกันโดยสิ้นเชิง รอบชิงชนะเลิศซึ่งเป็นครั้งสุดท้ายไม่สามารถเปลี่ยนแปลงได้ คงที่ซึ่งจะยังคงเป็นหนึ่ง แต่สามารถเปลี่ยนแปลงได้

"นี่คือตัวอย่างโปรดจำไว้ว่าตัวแปรแบบสแตติกจะถูกเรียกโดยชื่อคลาสของพวกเขาเสมอเนื่องจากเป็นเพียงวัตถุเดียวสำหรับวัตถุทั้งหมดของคลาสนั้นดังนั้นคลาส A มี x = 5 ฉันสามารถโทรและเปลี่ยนโดย Ax = 6; "


1

คงที่เป็นสิ่งที่วัตถุใด ๆ ในชั้นเรียนสามารถเรียกว่าเป็นของประเภทวัตถุ

ตัวแปรสามารถสุดท้ายสำหรับทั้งชั้นเรียนและนั่นก็หมายความว่ามันไม่สามารถเปลี่ยนแปลงได้อีกต่อไป สามารถตั้งค่าได้เพียงครั้งเดียวและการพยายามตั้งค่าอีกครั้งจะทำให้เกิดข้อผิดพลาด มันมีประโยชน์ด้วยเหตุผลหลายประการบางทีคุณอาจต้องการประกาศค่าคงที่ซึ่งไม่สามารถเปลี่ยนแปลงได้

โค้ดตัวอย่างบางส่วน:

class someClass
{
   public static int count=0;
   public final String mName;

   someClass(String name)
   {
     mname=name;
     count=count+1;
   }

  public static void main(String args[])
  {
    someClass obj1=new someClass("obj1");
    System.out.println("count="+count+" name="+obj1.mName);
    someClass obj2=new someClass("obj2");
    System.out.println("count="+count+" name="+obj2.mName);
  }
}

Wikipedia มีรายการคำหลัก javaทั้งหมด


คุณหมายถึงอะไรสำหรับวัตถุเฉพาะ คุณช่วยอธิบายได้ไหม
TechnoCorner

0

ฉันจะไม่พยายามให้คำตอบที่สมบูรณ์ที่นี่ คำแนะนำของฉันจะเน้นที่การทำความเข้าใจว่าแต่ละคนทำอะไรแล้วควรกำจัดให้ชัดเจนว่าผลกระทบของพวกเขาแตกต่างไปจากเดิมอย่างสิ้นเชิงและทำไมบางครั้งใช้ร่วมกัน

staticสำหรับสมาชิกของคลาส (คุณลักษณะและวิธีการ) และจะต้องมีการทำความเข้าใจในทางตรงกันข้ามกับสมาชิกอินสแตนซ์ (ไม่คงที่) ฉันขอแนะนำให้อ่าน"การทำความเข้าใจอินสแตนซ์และสมาชิกคลาส"ในบทแนะนำ Java ฉันยังสามารถใช้ในstaticบล็อก แต่ฉันจะไม่ต้องกังวลเกี่ยวกับมันสำหรับการเริ่มต้น

finalมีความหมายที่แตกต่างกันหากนำไปใช้กับตัวแปรวิธีการเรียนหรือกรณีอื่น ๆ ที่นี่ฉันชอบคำอธิบายวิกิพีเดียดีกว่า


-1

ค่าตัวแปรแบบสแตติกสามารถเปลี่ยนแปลงได้แม้ว่าจะมีการคัดลอกตัวแปรหนึ่งชุดผ่านแอปพลิเคชันในขณะที่ค่าตัวแปรขั้นสุดท้ายสามารถเริ่มต้นได้ครั้งเดียวและไม่สามารถเปลี่ยนแปลงได้ตลอดทั้งแอปพลิเคชัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.