Java: เมื่อใดจะใช้วิธีการคงที่


911

ฉันสงสัยว่าจะใช้วิธีการคงที่เมื่อใด พูดถ้าฉันมีคลาสที่มี getters และ setters ไม่กี่วิธีหรือสองและฉันต้องการวิธีเหล่านั้นเท่านั้นที่จะสามารถเรียกใช้บนวัตถุตัวอย่างของชั้นเรียน นี่หมายความว่าฉันควรใช้วิธีการคงที่หรือไม่?

เช่น

Obj x = new Obj();
x.someMethod

หรือ

Obj.someMethod

(นี่เป็นวิธีที่คงที่หรือไม่)

ฉันค่อนข้างสับสน!

คำตอบ:


1458

หนึ่งกฎของหัวแม่มือ: ถามตัวเองว่า "มันสมเหตุสมผลไหมที่จะเรียกวิธีนี้แม้ว่าจะยังไม่มีการสร้างวัตถุหรือยัง?" ถ้าเป็นเช่นนั้นแน่นอนควรจะคงที่

ดังนั้นในชั้นเรียนCarคุณอาจมีวิธีการ:

double convertMpgToKpl(double mpg)

... ซึ่งคงที่เพราะอาจต้องการทราบว่า 35mpg แปลงเป็นอย่างไรแม้ว่าจะไม่มีใครสร้างCarมา แต่วิธีนี้ (ซึ่งกำหนดประสิทธิภาพของสิ่งใดสิ่งหนึ่งCar):

void setMileage(double mpg)

... ไม่สามารถอยู่นิ่งได้เนื่องจากไม่สามารถเรียกวิธีการก่อนที่จะCarมีการสร้าง

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

Car theMoreEfficientOf( Car c1, Car c2 )

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


325
ตัวอย่างที่ดีที่นี่ ฉันจะเพิ่มอย่างไรก็ตาม "คงที่" มักจะมีค่าเมื่อคุณรู้ว่าบางสิ่งจะไม่เปลี่ยนแปลงไปตามอินสแตนซ์ หากเป็นกรณีนี้ฉันจะพิจารณา "หลักการความรับผิดชอบเดี่ยว" ซึ่งหมายถึงคลาสควรมีความรับผิดชอบเดียวและด้วยเหตุผลเดียวเท่านั้นที่จะเปลี่ยน ฉันรู้สึกว่าควรพิจารณาย้ายฟังก์ชัน "ConvertMpgToKpl (double mpg)" และวิธีการที่คล้ายกันไปยังคลาสของตนเอง วัตถุประสงค์ของวัตถุรถยนต์คืออนุญาตให้มีการสร้างอินสแตนซ์ของรถยนต์ไม่ใช่การเปรียบเทียบระหว่างพวกเขา สิ่งเหล่านั้นควรอยู่นอกคลาส
Zack Jannsen

34
ฉันคิดว่าฉันต้องการวิธีการCar#isMoreEfficientThan(Car)มากกว่า มันมีข้อดีคือรถคันไหนที่คุณจะกลับมาเสมอ มันชัดเจนโดยชื่อเรื่องของวิธีการที่คืนค่ากลับมา
Cruncher

5
ฉันจะต้องระมัดระวังเกี่ยวกับการสร้างวิธีการคงที่ที่ใช้ทรัพยากรภายนอกบางอย่าง (ระบบแฟ้มฐานข้อมูล ฯลฯ ) ประเภทนี้คงทำให้น่ากลัวในการทดสอบวิธีการบริโภค ฉันพยายามเก็บสถิติไว้ในขอบเขตของ "ยูทิลิตี้" เป็นการส่วนตัว
เซท M.

7
ในความเป็นจริงก็ควรจะนำมาใช้เป็นเครื่องมือเปรียบเทียบ
Dogweather

3
@ B1KMusic แน่นอน สิ่งที่ฉันหมายถึงโดย "รถคันไหนกลับมาเสมอ" คือ "แผนที่จริงที่เรียกบนรถและแผนที่เท็จไปยังรถที่ผ่าน" มันไม่มีความคลุมเครือ
Cruncher

538

กำหนดวิธีการคงที่ในสถานการณ์ต่อไปนี้เท่านั้น:

  1. หากคุณกำลังเขียนคลาสยูทิลิตี้และพวกเขาไม่ควรจะเปลี่ยน
  2. หากวิธีนี้ไม่ได้ใช้ตัวแปรอินสแตนซ์ใด ๆ
  3. หากการดำเนินการใด ๆ ไม่ได้ขึ้นอยู่กับการสร้างอินสแตนซ์
  4. หากมีรหัสบางอย่างที่สามารถใช้ร่วมกันโดยวิธีการทุกตัวอย่างแยกรหัสที่เป็นวิธีคงที่
  5. หากคุณแน่ใจว่าคำจำกัดความของวิธีการนั้นจะไม่มีการเปลี่ยนแปลงหรือลบล้าง ในฐานะที่เป็นวิธีการคงที่ไม่สามารถแทนที่

45
จุดที่ดี แต่เป็นข้อกำหนดถ้าคุณต้องการทำให้วิธีการคงที่ไม่ใช่เหตุผลที่จะทำให้
tetsuo

4
@ โมฮัดเกี่ยวกับข้อกำหนดที่ 5: เมื่อใดที่คุณจะมั่นใจได้ 100% ว่าวิธีการจะไม่เปลี่ยนแปลงหรือถูกแทนที่? ไม่ได้มีปัจจัยที่ไม่รู้จักเสมอที่คุณไม่สามารถนำมาพิจารณาในขณะที่คุณเขียนวิธีการคงที่ของคุณ?
PixelPlex

8
"คลาสยูทิลิตี้" นั้นยากมากที่จะให้เหตุผลเกี่ยวกับสิ่งที่เลวร้ายคือไม่ช้าก็เร็วทุกอย่างจะเริ่ม 'ดูเหมือน' ยูทิลิตี้ (ใช่ฉันหมายถึงแพคเกจ "util" ที่ป่องๆไม่สามารถแตะต้องและทดสอบไม่ดี) และกรณีทดสอบของคุณจะต้องใช้งานมากขึ้น (เพื่อจำลอง utils คงที่คือ HARD) ชอบวัตถุก่อน
Sergio

2
@ โมห์คำตอบนี้เป็นสิ่งที่ฉันกำลังมองหา ฉันประสบปัญหามากมายโดยใช้วิธีการคงที่ในการทำมัลติเธรด คุณช่วยอธิบายรายละเอียดคะแนน 2 และ 3 เพิ่มเติมได้ (ตัวอย่างเช่น 100 นิ้วหัวแม่มือสำหรับคุณ)
Prakash Pandey

ฉันคิดว่า "คลาสคงที่" ควรจะคิดค้นถ้าคุณจะใช้ตัวแปรและวิธีการคงที่
Robert Rocha

182

มีเหตุผลบางอย่างที่ถูกต้องในการใช้วิธีการคงที่:

  • ประสิทธิภาพการทำงาน : หากคุณต้องการให้โค้ดทำงานและไม่ต้องการสร้างอินสแตนซ์ของออบเจ็กต์พิเศษให้ทำเช่นนั้นผลักมันเป็นวิธีการคงที่ JVM ยังสามารถเพิ่มประสิทธิภาพวิธีการแบบคงที่ได้อีกมากมาย (ฉันคิดว่าฉันเคยอ่าน James Gosling ประกาศว่าคุณไม่ต้องการคำแนะนำที่กำหนดเองใน JVM เนื่องจากวิธีการแบบคงที่จะเร็วมาก แต่ไม่สามารถหาแหล่งที่มาได้ - ดังนั้น มันอาจเป็นเท็จอย่างสมบูรณ์) ใช่มันเป็นการเพิ่มประสิทธิภาพแบบไมโครและอาจไม่จำเป็น และเราโปรแกรมเมอร์ไม่เคยทำสิ่งที่ไม่จำเป็นเพราะมันเจ๋งใช่มั้ย

  • การปฏิบัติจริง : แทนการโทรการnew Util().method(arg)โทรUtil.method(arg)หรือmethod(arg)การนำเข้าแบบสแตติก ง่ายกว่าสั้นกว่า

  • การเพิ่มเมธอด : คุณต้องการให้คลาส String มีremoveSpecialChars()วิธีอินสแตนซ์ แต่ไม่มี (และไม่ควรเนื่องจากอักขระพิเศษของโปรเจ็กต์ของคุณอาจแตกต่างจากโปรเจ็กต์อื่น) และคุณไม่สามารถเพิ่มได้ (ตั้งแต่ Java ค่อนข้างมีสติ) ดังนั้นคุณสร้างระดับยูทิลิตี้และเรียกแทนremoveSpecialChars(s) s.removeSpecialChars()หวาน.

  • ความบริสุทธิ์ : ใช้ความระมัดระวังบางอย่างวิธีการคงที่ของคุณจะเป็นฟังก์ชั่นบริสุทธิ์นั่นคือสิ่งเดียวที่มันขึ้นอยู่กับพารามิเตอร์ของมัน Data in, data out ง่ายต่อการอ่านและแก้ปัญหาเนื่องจากคุณไม่มีปัญหาเรื่องมรดกที่ต้องกังวล คุณสามารถทำได้ด้วยวิธีการเช่นกัน แต่คอมไพเลอร์จะช่วยคุณมากขึ้นด้วยวิธีการคงที่ (โดยไม่อนุญาตให้อ้างอิงถึงคุณลักษณะของอินสแตนซ์วิธีการเอาชนะเป็นต้น)

คุณจะต้องสร้างวิธีการแบบคงที่หากคุณต้องการสร้างซิงเกิลตัน แต่ ... ไม่ ฉันหมายความว่าคิดสองครั้ง

ที่สำคัญกว่านั้นทำไมคุณไม่ต้องการสร้างวิธีการแบบคงที่? โดยทั่วไปความแตกต่างออกไปจากหน้าต่าง คุณจะไม่สามารถที่จะแทนที่วิธีการที่มิได้ประกาศในอินเตอร์เฟซ (Pre-Java 8) ใช้ความยืดหยุ่นมากมายจากการออกแบบของคุณ นอกจากนี้หากคุณต้องการสถานะคุณจะจบลงด้วยข้อบกพร่องมากมายที่เกิดขึ้นพร้อมกันและ / หรือคอขวดหากคุณไม่ระวัง


1
มีเหตุผลที่ดีมากมายที่ระบุไว้ที่นี่เมื่อสแตติกมีประโยชน์ อีกอย่างหนึ่งที่ฉันคิดได้ก็คือการเขียนการทดสอบหน่วยสำหรับวิธีการดังกล่าวเป็นเพียงวิธีธรรมดา ๆ เท่านั้น
4997

@tetsuo ขอบคุณ! คำอธิบายของคุณชัดเจนมากและเหตุผลที่ให้นั้นสมเหตุสมผลและสมเหตุสมผล
Deniss M.

3
และเราโปรแกรมเมอร์ไม่เคยทำสิ่งที่ไม่จำเป็นเพราะมันเจ๋งใช่มั้ย +1
Scaramouche

ที่กล่าวว่าวิธีการแบบคงที่จะกลายเป็นฟังก์ชั่นที่มีชื่อเต็มstackoverflow.com/questions/155609/…
Ivanzinho

ฉันเห็นด้วยกับประสิทธิภาพและการปฏิบัติจริง แต่ไม่ใช่ความบริสุทธิ์ วิธีการคงที่สามารถแก้ไขสมาชิกคงที่ของชั้นเรียน (ซึ่งอาจเป็นส่วนตัว) สิ่งนี้มีประโยชน์ ตัวอย่างเช่นคุณอาจมีวิธีเช่น "static synchron int allocateID () {return idNext ++;}" ในความเป็นจริงวิธีการคงที่สามารถเป็นเพียงบริสุทธิ์หรือไม่บริสุทธิ์เป็นวิธีการไม่คงที่ในแง่ของผลข้างเคียง
Adam Gawne-Cain

42

หลังจากอ่านบทความของ Misko ฉันเชื่อว่าวิธีการคงที่ไม่ดีจากมุมมองการทดสอบ คุณควรมีโรงงานแทน (อาจใช้เครื่องมือฉีดพึ่งพาเช่นGuice )

ฉันจะมั่นใจได้อย่างไรว่าฉันมีเพียงบางอย่างเท่านั้น

มีเพียงสิ่งเดียวเท่านั้นปัญหาของ“ ฉันจะแน่ใจได้อย่างไรว่าฉันมีเพียงบางสิ่งเท่านั้น” ได้รับการหลีกเลี่ยงอย่างดี คุณสร้างอินสแตนซ์เดียวของ ApplicationFactory ในหลักของคุณและเป็นผลให้คุณสร้างอินสแตนซ์เดียวของอินสแตนซ์เดียวทั้งหมดของคุณ

ปัญหาพื้นฐานเกี่ยวกับวิธีการคงที่คือพวกเขาเป็นรหัสขั้นตอน

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


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

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

4
@ อัลเฟรด: โปรดดูPowerMockซึ่งมีความสามารถในการจำลองวิธีการคงที่ การใช้ PowerMock มีบางสถานการณ์ที่คุณพบว่าการพึ่งพาเมธอดซึ่งไม่สามารถเยาะเย้ยได้
Carles Sala

7
คุณสามารถทดสอบหน่วยสถิตยศาสตร์โดยใช้ PowerMock ได้ แต่ในไม่ช้าคุณจะพบว่าพื้นที่ของ Permgen หมด (ทำอย่างนั้นมีเสื้อยืด) และยังน่ารังเกียจอยู่ เว้นแต่คุณจะรู้ (อิงจากประสบการณ์ของคุณเองอย่างน้อยหนึ่งทศวรรษในภาษา OO จริงไม่ใช่การโยกย้ายจาก C) ดังนั้นอย่าทำเช่นนั้น รหัสที่แย่ที่สุดที่ฉันเคยเห็นอย่างจริงจังมาจากการใช้งานของนักพัฒนาที่ฝังตัวและในกรณีส่วนใหญ่เราติดอยู่กับมันตลอดไปและการเพิ่มรหัสเพิ่มเติมเพียงแค่ล็อคเราไว้ในหินใหญ่ก้อนเดียวที่ไม่เปลี่ยนแปลง การมีเพศสัมพันธ์แบบหลวม: ไม่ทดสอบได้: แทบจะแก้ไขไม่ได้: ไม่เคย หลีกเลี่ยง!
user1016765

14
ฉันสามารถเข้าใจความยากลำบากในการทดสอบวิธีการคงที่ที่ขึ้นอยู่กับสถานะคงที่ แต่เมื่อคุณกำลังทดสอบวิธีสแตติกแบบไร้รัฐเช่นMath.abs()หรือArrays.sort()แม้กระทั่งวิธีการที่คุณสามารถผ่านการอ้างอิงทั้งหมดลงไปได้ฉันไม่เห็นว่าจะขัดขวางการทดสอบหน่วยได้อย่างไร ฉันจะบอกว่ากฎง่ายๆคือถ้าคุณเคยมีเหตุผลที่จะล้อเลียนตรรกะของกระบวนการใด ๆ แล้วอย่าวางไว้ในวิธีการคงที่ ฉันไม่เคยมีเหตุผลที่จะเยาะเย้ยออกหรือArrays.sort() Math.abs()
Andy

36

staticวิธีการเป็นหนึ่งในประเภทของวิธีการซึ่งไม่จำเป็นต้องวัตถุใด ๆ ที่จะเริ่มต้นให้มันถูกเรียกว่า คุณสังเกตเห็นว่าstaticมีการใช้งานในmainฟังก์ชั่นใน Java? การทำงานของโปรแกรมเริ่มต้นจากที่นั่นโดยไม่มีวัตถุถูกสร้างขึ้น

ลองพิจารณาตัวอย่างต่อไปนี้:

 class Languages 
 {
     public static void main(String[] args) 
     {
         display();
     }

     static void display() 
     {
         System.out.println("Java is my favorite programming language.");
     }
  }

คำตอบที่ดีที่สุดจริง
Yahya

20

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


12

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


1
คุณควรใช้วิธีการคงที่หากไม่ต้องการการเปลี่ยนแปลงสถานะของวัตถุ
MastAvalons

11

หากคุณใช้คำหลักคงที่กับวิธีการใด ๆ ก็จะเรียกว่าวิธีการคงที่

  1. วิธีการคงที่เป็นของชั้นเรียนมากกว่าวัตถุของชั้นเรียน
  2. เมธอดสแตติกเรียกใช้โดยไม่จำเป็นต้องสร้างอินสแตนซ์ของคลาส
  3. วิธีการคงที่สามารถเข้าถึงข้อมูลสมาชิกคงที่และสามารถเปลี่ยนค่าของมัน
  4. วิธีการคงที่สามารถเข้าถึงได้เพียงแค่ใช้ชื่อของชื่อคงคลาสจุด . . ตัวอย่าง: Student9.change ();
  5. ถ้าคุณต้องการใช้ฟิลด์ที่ไม่คงที่ของคลาสคุณต้องใช้วิธีที่ไม่คงที่

// โปรแกรมเปลี่ยนคุณสมบัติทั่วไปของวัตถุทั้งหมด (ฟิลด์สแตติก)

class Student9{  
 int rollno;  
 String name;  
 static String college = "ITS";  

 static void change(){  
 college = "BBDIT";  
 }  

 Student9(int r, String n){  
 rollno = r;  
 name = n;  
 }  

 void display (){System.out.println(rollno+" "+name+" "+college);}  

public static void main(String args[]){  
Student9.change();  

Student9 s1 = new Student9 (111,"Indian");  
Student9 s2 = new Student9 (222,"American");  
Student9 s3 = new Student9 (333,"China");  

s1.display();  
s2.display();  
s3.display();  
}  }

O / P: 111 Indian BBDIT 222 American BBDIT 333 China BBDIT


10

วิธีการแบบสแตติกไม่เกี่ยวข้องกับอินสแตนซ์ดังนั้นจึงไม่สามารถเข้าถึงฟิลด์ที่ไม่คงที่ในคลาสได้

คุณจะใช้วิธีการคงที่ถ้าวิธีการไม่ใช้เขตข้อมูลใด ๆ (หรือเฉพาะเขตข้อมูลแบบคงที่) ของคลาส

หากมีการใช้ฟิลด์ที่ไม่คงที่ของคลาสคุณต้องใช้วิธีการที่ไม่คงที่


1
คำตอบที่ชัดเจนสั้นและง่าย
Josi

8

ควรเรียกใช้วิธีการคงที่ในคลาสวิธีการอินสแตนซ์ควรถูกเรียกใช้บนอินสแตนซ์ของคลาส แต่นั่นหมายความว่าในความเป็นจริง นี่คือตัวอย่างที่มีประโยชน์:

คลาสรถยนต์อาจมีวิธีอินสแตนซ์ชื่อ Accelerate () คุณสามารถเร่งรถได้ถ้ารถมีอยู่จริง (สร้างขึ้น) และดังนั้นจึงเป็นวิธีการอินสแตนซ์

คลาสรถยนต์อาจมีวิธีนับที่เรียกว่า GetCarCount () นี่จะคืนจำนวนรถยนต์ทั้งหมดที่สร้าง (หรือสร้าง) หากไม่มีการสร้างรถยนต์วิธีนี้จะคืนค่า 0 แต่ควรจะสามารถเรียกได้ดังนั้นจึงต้องเป็นวิธีคงที่


6

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


การรักษาสถานะในตัวแปรแบบคงที่เป็นสิ่งที่ไม่ดีที่ต้องทำด้วยเหตุผลหลายประการเช่นความปลอดภัยหลายเธรดการดีบักการห่อหุ้มข้อมูล .. ฯลฯ วิธีการแบบคงที่จะตกลงถ้าพวกเขามีฟังก์ชั่นที่บริสุทธิ์ ตัวอย่างที่ดีคือคลาสยูทิลิตี้สำหรับการคำนวณทางคณิตศาสตร์
Vladimir Demirev

5

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


29
สิ่งนี้ไม่ได้ให้เหตุผลใด ๆ สำหรับการออกแบบโปรแกรม
adamjmarkham

4

คงที่: Obj.someMethod

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


4

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


1
เย้! ดูที่ฉันมาในขณะที่คำถาม Google noobie googling! มันเป็นโลกใบเล็ก :-)
Deepak

1
@Deepak โลกใบเล็กแน่นอน :)
Vaishak Suresh

4

วิธีการคงที่และตัวแปรเป็นรุ่นควบคุมของฟังก์ชั่น 'ทั่วโลก' และตัวแปรใน Java วิธีการใดที่สามารถเข้าถึงได้เช่นclassname.methodName()หรือclassInstanceName.methodName()วิธีการคงที่และตัวแปรสามารถเข้าถึงได้โดยใช้ชื่อคลาสเช่นเดียวกับอินสแตนซ์ของชั้นเรียน

ไม่สามารถประกาศคลาสเป็นแบบสแตติก (เนื่องจากไม่มีเหตุผลหากคลาสถูกประกาศสู่สาธารณะสามารถเข้าถึงได้จากทุกที่) คลาสภายในสามารถประกาศสแตติกได้


3

วิธีการคงที่สามารถใช้ถ้า

  • หนึ่งไม่ต้องการที่จะดำเนินการกับอินสแตนซ์ (วิธีการยูทิลิตี้)

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

    1. new ABCClass(double farenheit).convertFarenheitToCelcium() 
    2. ABCClass.convertFarenheitToCelcium(double farenheit)

    อดีตสร้างรอยระดับใหม่สำหรับทุกวิธีวิงวอนประสิทธิภาพการปฏิบัติ ตัวอย่างคือคลาส StringUtils ของ Math และ Apache-Commons

    Math.random()
    Math.sqrt(double)
    Math.min(int, int)
    StringUtils.isEmpty(String)
    StringUtils.isBlank(String)
  • หนึ่งต้องการใช้เป็นฟังก์ชั่นที่เรียบง่าย อินพุตถูกส่งผ่านอย่างชัดเจนและรับข้อมูลผลลัพธ์เป็นค่าส่งคืน การสืบทอดการสัญชาตญาณของวัตถุไม่เข้ามาในรูปภาพ กระชับอ่านง่าย

หมายเหตุ : มีคนเพียงไม่กี่คนที่โต้แย้งกับความสามารถในการทดสอบวิธีการคงที่ แต่วิธีการทดสอบแบบสถิตก็สามารถทดสอบได้เช่นกัน! ด้วย jMockit เราสามารถเยาะเย้ยวิธีการคงที่ การตรวจสอบได้ ตัวอย่างด้านล่าง:

new MockUp<ClassName>() {
    @Mock
    public int doSomething(Input input1, Input input2){
        return returnValue;
    }
};

3

วิธีการคงที่เป็นวิธีการใน Java ที่สามารถเรียกได้โดยไม่ต้องสร้างวัตถุของชั้นเรียน มันเป็นของชั้นเรียน

เราใช้วิธีการคงที่เมื่อเราไม่จำเป็นต้องเรียกใช้วิธีการโดยใช้อินสแตนซ์


2

ฉันสงสัยว่าจะใช้วิธีการคงที่เมื่อใด

  1. การใช้งานทั่วไปสำหรับstaticวิธีการคือการเข้าถึงstaticเขตข้อมูล
  2. แต่คุณสามารถมีstaticวิธีได้โดยไม่ต้องอ้างอิงstaticตัวแปร วิธีการช่วยเหลือที่ไม่มีstaticตัวแปรอ้างอิงสามารถพบได้ในบางคลาส Java เช่นjava.lang.Math

    public static int min(int a, int b) {
        return (a <= b) ? a : b;
    }
  3. กรณีการใช้งานอื่น ๆ ฉันคิดว่าวิธีการเหล่านี้รวมกับsynchronizedวิธีการคือการดำเนินการล็อคระดับชั้นเรียนในสภาพแวดล้อมแบบมัลติเธรด

พูดถ้าฉันมีคลาสที่มี getters และ setters ไม่กี่วิธีหรือสองและฉันต้องการวิธีเหล่านั้นเท่านั้นที่จะสามารถเรียกใช้บนวัตถุตัวอย่างของชั้นเรียน นี่หมายความว่าฉันควรใช้วิธีการคงที่หรือไม่?

หากคุณต้องการเข้าถึงวิธีการในวัตถุตัวอย่างของชั้นเรียนวิธีการของคุณควรจะไม่คงที่

หน้าเอกสารของ Oracle ให้รายละเอียดเพิ่มเติม

ไม่อนุญาตให้ใช้การรวมกันของอินสแตนซ์และตัวแปรคลาสและวิธีการทั้งหมด:

  1. วิธีการอินสแตนซ์สามารถเข้าถึงตัวแปรอินสแตนซ์และวิธีการอินสแตนซ์โดยตรง
  2. วิธีการอินสแตนซ์สามารถเข้าถึงตัวแปรคลาสและเมธอดคลาสได้โดยตรง
  3. วิธีการเรียนสามารถเข้าถึงตัวแปรระดับและวิธีการเรียนโดยตรง
  4. วิธีการเรียนไม่สามารถเข้าถึงตัวแปรอินสแตนซ์หรือวิธีการอินสแตนซ์โดยตรง - พวกเขาจะต้องใช้การอ้างอิงวัตถุ นอกจากนี้วิธีการเรียนไม่สามารถใช้คำหลักนี้เนื่องจากไม่มีอินสแตนซ์สำหรับการอ้างอิง

เราไม่สามารถเข้าถึงฟิลด์สแตติกด้วยวิธีปกติได้หรือไม่ นี่A common use for static methods is to access static fields.ไม่ใช่ข้อโต้แย้ง
parsecer

2

วิธีการคงที่มีวัตถุประสงค์หลักสองประการ:

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

1

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

การตั้งค่าคราส


0

เมื่อใดก็ตามที่คุณไม่ต้องการสร้างวัตถุเพื่อเรียกใช้เมธอดในโค้ดของคุณเพียงแค่ประกาศเมธอดนั้นเป็นแบบสแตติก เนื่องจากเมธอดสแตติกไม่ต้องการอินสแตนซ์ที่จะเรียกด้วย แต่การดักจับที่นี่ไม่ใช่วิธีสแตติกทั้งหมดถูกเรียกโดย JVM โดยอัตโนมัติ สิทธิพิเศษนี้จะได้รับความเพลิดเพลินจากเมธอด main () "public static void main [String ... args]" ใน java เพราะที่ Runtime นี่เป็นวิธีที่ Signature เป็นโมฆะ "static" public [] ที่ถูกค้นหาโดย JVM เป็นจุดเริ่มต้น เริ่มการทำงานของรหัส

ตัวอย่าง:

public class Demo
{
   public static void main(String... args) 
   {
      Demo d = new Demo();

      System.out.println("This static method is executed by JVM");

     //Now to call the static method Displ() you can use the below methods:
           Displ(); //By method name itself    
      Demo.Displ(); //By using class name//Recommended
         d.Displ(); //By using instance //Not recommended
   }

   public static void Displ()
   {
      System.out.println("This static method needs to be called explicitly");
   }
} 

เอาต์พุต: - วิธีสแตติกนี้ดำเนินการโดย JVM วิธีสแตติกนี้ต้องถูกเรียกอย่างชัดเจนวิธีสแตติกนี้ต้องถูกเรียกอย่างชัดเจนวิธีสแตติกนี้ต้องถูกเรียกอย่างชัดเจน

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