ค่าคงที่

"Amigo คุณรู้หรือไม่ว่าใน Java ไม่สามารถเปลี่ยนตัวแปรทั้งหมดได้"

"ว่าไงคิม อันที่จริงคำว่า 'ตัวแปร' นั้นพูดถึงการเปลี่ยนแปลง"

"ไม่ต้องสงสัยเลยในเรื่องนั้น เช่นเดียวกับภาษาโปรแกรมอื่น ๆ อีกมากมาย Java มีค่าคงที่ นั่นคือตัวแปรที่ไม่สามารถเปลี่ยนค่าได้และคำว่า 'ค่าคงที่' นั้นหมายถึงค่าคงที่"

"และพวกเขามีไว้เพื่ออะไร"

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

"คุณหมายถึงชื่อ สีรถ หรือชื่อวันในสัปดาห์?"

"คุณมีความคิดที่ถูกต้อง สิ่งใดที่ไม่ควรเปลี่ยนแปลง"

"และค่าคงที่เหล่านี้มีลักษณะอย่างไรใน Java"

"Java มีคีย์เวิร์ดพิเศษสำหรับพวกเขา: finalการสร้างตัวแปรที่ไม่เปลี่ยนรูปมีลักษณะเหมือนกับการสร้างตัวแปรธรรมดา ข้อแตกต่างเพียงอย่างเดียวคือก่อนประเภทของตัวแปร คุณต้องเขียนคำ แบบfinalนี้:

final Type name = value;

"จะเกิดอะไรขึ้นถ้าคุณสร้างค่าคงที่แล้วลองกำหนดค่าอื่นให้กับค่านั้น"

"นั่นเป็นคำถามที่ถูกต้อง! และคำตอบที่ถูกต้องคือ: หากคุณพยายามกำหนดค่าอื่นให้กับตัวแปรfinalโปรแกรมของคุณก็จะคอมไพล์ไม่ได้"

"จะเป็นอย่างไรถ้าคุณประกาศfinalตัวแปรแต่ไม่ได้กำหนดค่าให้"

"ไม่มีประโยชน์ที่จะทำเช่นนี้ ดังนั้นจึงไม่ได้รับอนุญาตใน Java เช่นกัน ตัวแปรfinalต้องได้รับการเตรียมใช้งานเมื่อมีการประกาศ นั่นคือ คุณต้องกำหนดค่าให้กับตัวแปร มีข้อยกเว้นประการหนึ่งสำหรับกฎนี้: คุณสามารถย้ายการเริ่มต้นของ ตัวแปรคลาสคงที่ในคอนสตรัคเตอร์ แต่ คุณจะได้เรียนรู้เกี่ยวกับสิ่งนั้นในภายหลัง

"ที่กล่าวว่า ไม่ใช่ทุกอย่างที่เป็นfinalค่าคงที่ เพื่อลดจำนวนของคีย์เวิร์ด นักพัฒนา Java ใช้คำนี้finalมากกว่าการประกาศค่าคงที่ นอกจากfinalนี้ยังใช้กับเมธอดและแม้แต่คลาส เมธอดที่ประกาศเป็นfinalไม่สามารถแทนที่ได้ และคลาส แจ้งว่าfinalรับมรดกไม่ได้”

"เอ่อ... ถูกครอบงำ? สืบทอดมา? ตอนนี้ท่านกำลังพูดภาษาอะไรอยู่?"

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

"เอาล่ะfinalสามารถวางไว้หน้าตัวแปร คลาส และเมธอดได้ และคีย์เวิร์ดนี้ทำให้มันเปลี่ยนรูปไม่ได้ในความหมายบางอย่าง"

"ใช่ นอกจากนี้finalโมดิฟายเออร์อาจถูกเพิ่มก่อนตัวแปรใดๆ: ตัวแปรโลคัล พารามิเตอร์เมธอด ฟิลด์คลาส และตัวแปรคลาสสแตติก

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

"ฉันไม่ค่อยเข้าใจ"

"คุณจะเข้าใจในไม่ช้า นี่คือตัวอย่าง:

final int[] data = {1, 2, 3, 4, 5, 6};

data = {6, 7, 8, 9};

data[0] = 0;
data[1] = 0;
data[2] = 0;
เราสร้างอาร์เรย์

ไม่อนุญาต:ตัวแปรdataถูกประกาศเป็นfinal.

แต่คุณสามารถทำได้
และสิ่งนี้ด้วย

"เข้าใจแล้ว มันยุ่งยาก"

ค่าคงที่ทั่วโลก

"คุณคิดว่าค่าคงที่ทั่วโลกคืออะไร"

"ฉันเดาว่าค่าคงที่ทั่วโลกอาจเหมือนกับตัวแปรส่วนกลาง แต่มีค่าคงที่เท่านั้น"

"แน่นอน ถ้าคุณต้องการประกาศค่าคงที่ส่วนกลางในโปรแกรมของคุณ ให้สร้างตัวแปรคลาสแบบสแตติกและทำให้เป็นpublicและfinalมีลักษณะพิเศษสำหรับชื่อของตัวแปรดังกล่าว: พวกมันเขียนด้วยอักษรตัวใหญ่ทั้งหมด โดยมีเครื่องหมายขีดล่างใช้เพื่อ แยกคำ

ตัวอย่าง:

class Solution
{
   public static final String SOURCE_ROOT = "c:\\projects\\my\\";
   public static final int DISPLAY_WIDTH = 1024;
   public static final int DISPLAY_HEIGHT = 768;
}

เงาตัวแปร

"อย่างที่ฉันพูดไปก่อนหน้านี้ คุณไม่สามารถสร้างตัวแปรโลคัลหลายตัวด้วยชื่อเดียวกันในเมธอดเดียวได้ ในเมธอดต่างๆ คุณทำได้"

"ฉันรู้แล้ว!"

"แต่สิ่งที่คุณอาจไม่ทราบก็คือตัวแปรในคลาสและตัวแปรโลคัลในเมธอดอาจมีชื่อเหมือนกัน

ตัวอย่าง:

รหัส การมองเห็นที่เปลี่ยนแปลงได้
public class Solution
{
   public int count = 0;
   public int sum = 0;

   public void add(int data)
   {
     sum = sum + data;
     int sum = data * 2;
     count++;
   }
}

count, sum
count, sum
count, sum
count, sum
count, sum
count, sum, data
count, sum, data
count, sum, data
count, sum, data
count, sum

"ในaddเมธอด เราประกาศตัวแปรโลคัลชื่อsumจนกว่าจะสิ้นสุดเมธอด มันเงา (หรือมาสก์ ) sumตัวแปรอินสแตนซ์"

"อืม... ฉันจะบอกว่าในแง่หนึ่งนี่คือพฤติกรรมที่คาดหวัง"

"แต่นั่นไม่ใช่จุดสิ้นสุดของเรื่องราว ปรากฎว่าหากตัวแปรอินสแตนซ์ถูกเงาโดยตัวแปรโลคัล ก็ยังมีวิธีอ้างอิงถึงตัวแปรอินสแตนซ์ภายในเมธอด เราทำสิ่งนี้โดยเขียนคีย์เวิร์ดก่อนthisชื่อ :

this.name

"นี่คือตัวอย่างที่แก้ไขข้อขัดแย้งของชื่อได้สำเร็จ:

รหัส การมองเห็นที่เปลี่ยนแปลงได้
public class Solution
{
   public int count = 0;
   public int sum = 0;

   public void add(int data)
   {
     int sum = data * 2;
     this.sum = this.sum + data;
     count++;
   }
}

this.count, this.sum
this.count, this.sum
this.count, this.sum
this.count, this.sum
this.count, this.sum
this.count, this.sum, data
this.count, this.sum, data, sum
this.count, this.sum, data, sum
this.count, this.sum, data, sum
this.count, this.sum

ตัวแปรcountและsumมีอยู่ทุกที่โดยมีหรือไม่มีthisคำสำคัญ ในบรรทัดที่sumตัวแปรโลคัลแสดงsumตัวแปรอินสแตนซ์sumตัวแปรอินสแตนซ์สามารถเข้าถึงได้โดยใช้thisคำหลัก เท่านั้น

“แน่นอน ฉันจะต้องฝึกฝนสิ่งนี้”

“คุณจะจัดการ”

"จะเกิดอะไรขึ้นถ้าตัวแปรคลาสสแตติกถูกแชโดว์แทนที่จะเป็นเพียงตัวแปรอินสแตนซ์ (ไม่คงที่) คุณไม่สามารถเข้าถึงผ่านthis?"

"ใช่แล้ว คีย์เวิร์ดนี้ใช้ไม่ได้ คุณต้องอ้างถึงคีย์เวิร์ดนี้ผ่านชื่อคลาส:

ClassName.name

ตัวอย่าง:

รหัส การมองเห็นที่เปลี่ยนแปลงได้
public class Solution
{
   public static int count = 0;
   public static int sum = 0;

   public void add(int data)
   {
     int sum = data * 2;
     Solution.sum = Solution.sum + data;
     count++;
   }
}

Solution.count, Solution.sum
Solution.count, Solution.sum
Solution.count, Solution.sum
Solution.count, Solution.sum
Solution.count, Solution.sum
Solution.count, Solution.sum, data
Solution.count, Solution.sum, data, sum
Solution.count, Solution.sum, data, sum
Solution.count, Solution.sum, data, sum
Solution.count, Solution.sum

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

ตัวแปรภายในforลูป

"และอีกหนึ่งข้อเท็จจริงเล็กๆ น้อยๆ แต่น่าสนใจ นอกจากนี้ยังมีสถานที่ที่มีการประกาศตัวแปรด้วยวิธีพิเศษ — ฉันกำลังพูดถึงภายในลูfor " โดยปกติแล้วforการวนซ้ำจะมีcounterตัวแปรอยู่ในวงเล็บ และการมองเห็นของตัวแปรนี้จะเป็นอย่างไร? ท้ายที่สุดมันไม่ได้อยู่ในเนื้อหาของลูป มันเป็นวิธีการทั้งหมดหรือไม่? หรือไม่?"

"ฉันเคยได้ยินเรื่องนี้มาบ้างแล้ว ตามที่ฉันเข้าใจ ตัวแปรที่ประกาศในส่วนหัวของลูforจะมองเห็นได้เฉพาะในเนื้อหาของลูปและในส่วนหัวของforลูป "

"ทำได้ดีมาก Amigo แต่ถึงกระนั้น ลองดูตัวอย่างเพื่อเสริมเนื้อหานี้:

รหัส การมองเห็นที่เปลี่ยนแปลงได้
public static void main(String[] args)
{
   int a = 0;

   for (int i = 0; i < 10; i++)
   {
     System.out.println(i);
   }

   System.out.println("end");
}


a
a
a, i
a, i
a, i
a
a
a

"คุณกำลังบอกว่าในโค้ดของฉัน ฉันสามารถเขียนลูปหลายๆ ลูปซ้ำแล้วซ้ำเล่าด้วยตัวแปรตัวนับที่มีชื่อเดียวกันได้ และจะไม่มีปัญหาอะไรใช่ไหม"

"คงไม่มีปัญหา ดูนี่:

รหัส การมองเห็นที่เปลี่ยนแปลงได้
public static void main(String[] args)
{
   int a = 0;

   for (int i = 0; i < 10; i++)
   {
     System.out.println(i);
   }

   for (int i = 0; i < 10; i--)
   {
     System.out.println(i);
   }

   System.out.println("end");
}


a
a
a, i
a, i
a, i
a
a
a, i
a, i
a, i
a
a
a