1. วิธีคงที่

นอกจากตัวแปรสแตติกแล้ว คลาสยังสามารถมีเมธอดสแตติกได้อีกด้วย

เมธอดปกติถูกผูกไว้กับอ็อบเจกต์ (อินสแตนซ์) ของคลาสและสามารถอ้างถึงตัวแปรธรรมดา (ไม่คงที่) ของคลาส (รวมถึงตัวแปรและเมธอดคงที่ ) เมธอดสแตติกถูกผูกไว้กับออบเจกต์สแตติกของคลาสและสามารถเข้าถึงตัวแปรสแตติกและ/หรือเมธอดสแตติกอื่นๆ ของคลาสเท่านั้น

ในการเรียกเมธอดธรรมดา (ไม่คงที่) ในคลาสคุณต้องสร้างอ็อบเจกต์ของคลาสก่อนแล้วจึงเรียกเมธอดบนอ็อบเจกต์ คุณไม่สามารถเรียกเมธอดธรรมดาในคลาสแทนที่จะเป็นอ็อบเจกต์

ตัวอย่าง:

คุณไม่สามารถเรียกใช้เมธอดแบบไม่คงที่ในคลาสได้!
public class DataInfo
{
   public int getValue()
   {
      return 100;
   }
}

public class Solution
{
   public static void main(String[] args)
   {
      System.out.println(DataInfo.getValue()); // This will generate an error!
   }
}

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

ในการประกาศเมธอดสแตติก คุณต้องเขียนสแตติกคีย์เวิร์ดก่อนส่วนหัวเมธอด ลักษณะทั่วไปของโครงสร้างนี้มีดังนี้:

static Type name(parameters)
{
   method code
}

ตัวอย่าง:

รหัส บันทึก
public class Solution
{
   public static void main(String args[])
   {
      test();
   }

   public static void test()
   {
      int d = 2/0;
   }
}


เครื่อง Java เรียกใช้mainเมธอดด้วยคำสั่งดังนี้Solution.main();



เมธอด สแตติกtest()ถูกเรียกในmain()เมธอด สแตติก

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

Type name = ClassName.methodName(arguments)

ตัวอย่าง:

รหัส วิธีคงที่
int x = Math.min(a, b);
int min(int a, int b)
Thread.sleep(200);
void sleep(long ms)
Path path = Path.of("c:\\readme.txt");
Path of(String str)


2. วิธีแบบคงที่และแบบธรรมดา (ไม่คงที่)

อะไรคือความแตกต่างระหว่างวิธีการแบบคงที่และแบบธรรมดา?

เมธอดธรรมดาถูกผูกไว้กับอ็อบเจกต์ธรรมดา (อินสแตนซ์ของคลาส) ในขณะที่เมธอดสแตติกไม่ได้ เมธอดธรรมดาสามารถเข้าถึงตัวแปรในอินสแตนซ์ของมันได้ แต่เมธอดสแตติกไม่สามารถทำได้: มันไม่มีอินสแตนซ์ที่เกี่ยวข้อง

ความแตกต่างระหว่างเมธอดทั้งสองประเภทแสดงไว้ในตารางต่อไปนี้:

ความสามารถ/คุณสมบัติ วิธีสามัญ วิธีคงที่
ผูกไว้กับอินสแตนซ์ของคลาส ใช่ เลขที่
สามารถเรียกใช้เมธอดสามัญของคลาสได้ ใช่ เลขที่
สามารถเรียกวิธีการแบบคงที่ของชั้นเรียน ใช่ ใช่
สามารถเข้าถึงตัวแปรธรรมดาของคลาสได้ ใช่ เลขที่
สามารถเข้าถึงตัวแปรคงที่ของคลาส ใช่ ใช่
สามารถเรียกใช้บนวัตถุ ใช่ ใช่
สามารถเรียกได้ในชั้นเรียน เลขที่ ใช่

เหตุใดจึงจำเป็นต้องใช้วิธีการดังกล่าวหากมีข้อจำกัดอย่างมาก คำตอบคือวิธีนี้ก็มีข้อดีเช่นกัน

ขั้นแรก คุณไม่จำเป็นต้องผ่านการอ้างอิงวัตถุใดๆ เพื่อเข้าถึงเมธอดและตัวแปรแบบสแตติก

ประการที่สอง บางครั้งคุณจำเป็นต้องมีเพียงอินสแตนซ์เดียวของตัวแปร ตัวอย่างเช่นSystem.out( ตัวแปรออกคงที่ของคลาสระบบ )

และอย่างที่สาม บางครั้งคุณต้องเรียกเมธอดก่อนที่จะสร้างออบเจกต์ด้วยซ้ำ ตัวอย่างเช่น เครื่อง Java เรียกใช้เมธอด main() เพื่อเริ่มการทำงานของโปรแกรมก่อนที่จะสร้างอินสแตนซ์ของคลาส

ผูกไว้กับอินสแตนซ์ของคลาส

เมื่อมีการเรียกใช้เมธอดธรรมดา อาร์กิวเมนต์ซึ่งเป็นอ็อบเจกต์ที่เมธอดนี้ถูกเรียกใช้จะถูกส่งผ่านไปยังเมธอดโดยปริยาย พารามิเตอร์นี้เรียกthisว่า พารามิเตอร์โดยปริยายนี้ (การอ้างอิงถึงวัตถุที่เรียกเมธอด) แยกเมธอดธรรมดาออกจากเมธอดสแตติก

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

สามารถเรียกใช้เมธอดสามัญของคลาสได้

เมธอดธรรมดาจะมีthisพารามิเตอร์โดยปริยายเสมอ ดังนั้นคุณจึงมีการอ้างอิงถึงอ็อบเจกต์ที่เรียกเมธอดนั้นเสมอ เมื่อใดก็ตามที่คุณเรียกเมธอดธรรมดาภายในเมธอดธรรมดาอื่นthisพารามิเตอร์โดยปริยายจะถูกใช้เพื่อทำการเรียกนั้น ตัวอย่าง

รหัส มันทำงานอย่างไร
int min(int a, int b)
{
   return a < b ? a : b;
}

int min(int a, int b, int c)
{
   int t = min(a, b);
   return min(t, c);
}
int min(int a, int b)
{
   return a < b ? a : b;
}

int min(int a, int b, int c)
{
   int t = this.min(a, b);
   return this.min(t, c);
}

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

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

เราจะเรียกมันว่าวัตถุอะไรดี? ท้ายที่สุด ยังไม่มีอินสแตนซ์ของคลาสของเราแม้แต่ตัวเดียว!

สามารถเรียกวิธีการแบบคงที่ของชั้นเรียน

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

สามารถเข้าถึงตัวแปรธรรมดาของคลาสได้

คุณสามารถเข้าถึงตัวแปรธรรมดาของคลาสได้จากเมธอดธรรมดา เนื่องจากสามารถรับการอ้างอิงถึงอินสแตนซ์ของคลาสได้อย่างง่ายดายผ่านพารามิเตอร์โดยthisปริยาย

เมธอดแบบสแตติกไม่ทราบว่าควรใช้อินสแตนซ์ของคลาสใดเพื่อรับค่าของตัวแปรธรรมดา และโดยทั่วไป เราสามารถมีสถานการณ์ที่เรียกเมธอดสแตติกได้อย่างง่ายดาย แต่ยังไม่มีการสร้างอินสแตนซ์ของคลาสเดียวในโปรแกรม

เป็นผลให้เมธอดสแตติกไม่สามารถเข้าถึงตัวแปรธรรมดาของคลาสได้

สมมติว่าเมธอดสแตติกเรียกเมธอดธรรมดา เมธอดธรรมดานั้นควรเรียกวัตถุใด

วิธีคงที่

ไม่มีใครรู้! นั่นเป็นเหตุผลที่คุณไม่สามารถเรียกเมธอดธรรมดาจากเมธอดแบบสแตติกโดยไม่ผ่านการอ้างอิงถึงวัตถุ!

สามารถเข้าถึงตัวแปรคงที่ของคลาส

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

สามารถเรียกใช้บนวัตถุ

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

รหัส วิธีที่คอมไพเลอร์เห็น
Thread th = Thread.current();
th.sleep(1000);
Thread th = Thread.current();
Thread.sleep(1000);
Integer i = 1;
int x = i.parseInt("12");
Integer i = 1;
int x = Integer.parseInt("12");
"".valueOf(12);
String.valueOf(12);

สามารถเรียกได้ในชั้นเรียน

คุณสามารถเรียกใช้เมธอดสแตติกในคลาสเท่านั้น ในการเรียกเมธอดธรรมดา คุณต้องอ้างอิงถึงอินสแตนซ์ของคลาส ดังนั้น คุณไม่สามารถเรียกใช้เมธอดธรรมดาโดยใช้โครงสร้างนี้:ClassName.methodName(arguments)