วิธีการช่วยเหลือส่วนตัวควรจะคงที่หากพวกเขาสามารถคงที่


205

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

public class Example {
   private Something member;

   public double compute() {
       double total = 0;
       total += computeOne(member);
       total += computeMore(member);
       return total;         
   }

   private double computeOne(Something arg) { ... }
   private double computeMore(Something arg) {... } 
} 

มีเหตุผลใดที่ต้องระบุcomputeOneและใช้computeMoreเป็นวิธีการคงที่ - หรือเหตุผลเฉพาะใด ๆ ที่จะไม่ทำ?

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


3
โปรดดูเพิ่มเติมว่าเมื่อใดที่จะไม่ใช้คำหลักแบบคงที่ใน Java: stackoverflow.com/questions/1766715/…
Mark Butler

คำตอบ:


174

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


2
หนึ่งในกระทู้ที่ชื่นชอบฉันกำลังใช้ NetBeans และแสดงการเรียกใช้เมธอดแบบสแตติกพร้อมกับฟอนต์ตัวเอียง
skiabox

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

2
@ James หรือเพียงstatic(หากเราต้องการทดสอบเท่านั้น)
mrod

3
"จะไม่แก้ไขสถานะของวัตถุ" - คำอธิบายที่สมบูรณ์ของวิธีแยกความแตกต่างจากวิธีส่วนตัว
HopeKing

110

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

ฉันจะทำให้พวกเขาคงที่เนื่องจากฉันทำเช่นนั้นโดยทั่วไปถ้าเป็นไปได้ทั้งหมด แต่นั่นเป็นเพียงฉัน


แก้ไข:คำตอบนี้ยังคงลดลงอาจเป็นเพราะการยืนยันอย่างไม่มีเงื่อนไขเกี่ยวกับขนาด bytecode ดังนั้นฉันจะทำการทดสอบ

class TestBytecodeSize {
    private void doSomething(int arg) { }
    private static void doSomethingStatic(int arg) { }
    public static void main(String[] args) {
        // do it twice both ways
        doSomethingStatic(0);
        doSomethingStatic(0);
        TestBytecodeSize t = new TestBytecodeSize();
        t.doSomething(0);
        t.doSomething(0);
    }
}

Bytecode (ดึงข้อมูลด้วยjavap -c -private TestBytecodeSize):

Compiled from "TestBytecodeSize.java"
class TestBytecodeSize extends java.lang.Object{
TestBytecodeSize();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

private void doSomething(int);
  Code:
   0:   return

private static void doSomethingStatic(int);
  Code:
   0:   return

public static void main(java.lang.String[]);
  Code:
   0:   iconst_0
   1:   invokestatic    #2; //Method doSomethingStatic:(I)V
   4:   iconst_0
   5:   invokestatic    #2; //Method doSomethingStatic:(I)V
   8:   new     #3; //class TestBytecodeSize
   11:  dup
   12:  invokespecial   #4; //Method "<init>":()V
   15:  astore_1
   16:  aload_1
   17:  iconst_0
   18:  invokespecial   #5; //Method doSomething:(I)V
   21:  aload_1
   22:  iconst_0
   23:  invokespecial   #5; //Method doSomething:(I)V
   26:  return

}

อัญเชิญวิธีการคงใช้เวลาสอง bytecodes (byteops?): iconst_0(สำหรับอาร์กิวเมนต์) invokestaticและ
อัญเชิญวิธีการไม่คงต้องใช้เวลาสาม: aload_1(สำหรับTestBytecodeSizeวัตถุที่ผมคิดว่า) iconst_0(สำหรับอาร์กิวเมนต์) invokespecialและ (โปรดทราบว่าหากวิธีการเหล่านี้ไม่ได้เป็นวิธีส่วนตัวก็คงจะเป็นinvokevirtualแทนที่จะinvokespecialดูJLS .77.7 วิธีเรียกใช้ )

ตอนนี้อย่างที่ฉันพูดฉันไม่ได้คาดหวังว่าจะมีความแตกต่างอย่างมากในประสิทธิภาพการทำงานระหว่างสองสิ่งนี้นอกเหนือจากความจริงที่invokestaticต้องใช้รหัสน้อยกว่าหนึ่งรหัส invokestaticและinvokespecialทั้งคู่ควรจะเร็วกว่าเล็กน้อยinvokevirtualเนื่องจากทั้งคู่ใช้การรวมแบบคงที่แทนที่จะเป็นแบบไดนามิก แต่ฉันไม่รู้ว่าถ้าเร็วกว่าแบบอื่น ฉันไม่พบการอ้างอิงที่ดีใด ๆ บทความที่ใกล้เคียงที่สุดที่ฉันสามารถค้นหาได้คือบทความ JavaWorld 1997ซึ่งโดยทั่วไปจะปรับปรุงสิ่งที่ฉันเพิ่งพูดว่า:

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

แต่มีหลายสิ่งเปลี่ยนไปตั้งแต่ปี 1997

สรุปแล้ว ... ฉันเดาว่าฉันยังคงยึดติดกับสิ่งที่ฉันพูดไว้ก่อนหน้านี้ ความเร็วไม่ควรเป็นเหตุผลในการเลือกอย่างใดอย่างหนึ่งเนื่องจากมันจะเป็นการเพิ่มประสิทธิภาพขนาดเล็กที่ดีที่สุด


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

ขอบคุณ (แม้ว่าฉันจะลบได้และได้รับตราในขณะที่มันอยู่ที่ -3: D)
Michael Myers

2
คอมไพเลอร์ของ JIT จะทำการอินไลน์และปรับให้เหมาะสมดังนั้นปริมาณของคำสั่ง bytecode จึงมีความเกี่ยวข้องกับความรวดเร็วของมัน
Esko Luontola

3
นั่นเป็นเหตุผลที่ฉันพูดว่า "ฉันไม่คิดว่ามันจะสร้างความแตกต่างของความเร็ว (และถ้าเป็นเช่นนั้นมันอาจจะเล็กเกินไปที่จะสร้างความแตกต่างโดยรวม)"
Michael Myers

7
ก่อนที่จะมีส่วนร่วมในการเพิ่มประสิทธิภาพขนาดเล็กใด ๆ ของประเภทนั้นคุณควรพิจารณาผลกระทบของการรวบรวมจุดร้อน ที่บรรทัดด้านล่าง: เขียนรหัสของคุณสำหรับการอ่านโดยมนุษย์และปล่อยให้การปรับให้เหมาะสมกับคอมไพเลอร์
Ichthyo

18

ความชอบส่วนตัวของฉันคือการประกาศให้พวกเขาคงที่เนื่องจากเป็นธงที่ชัดเจนว่าพวกเขาไร้สัญชาติ


18

คำตอบคือ ... มันขึ้นอยู่กับ

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

ตัวอย่างเช่น

public class Example {
   private Something member;

   public double compute() {
       double total = 0;
       total += computeOne();
       total += computeMore();
       return total;         
   }

   private double computeOne() { /* Process member here */ }
   private double computeMore() { /* Process member here */ } 
}

5
+1: แม้ว่าตัวอย่างจะไม่ดี แต่วิธีการที่มากเกินไปที่จะคงที่นั้นเป็นกลิ่นที่ไม่ดี โดยวิธีการคงที่เป็นจริงฟังก์ชั่นพวกเขาไม่ได้อยู่ที่ OO ทั้งหมด พวกเขาอาจเป็นวิธีการในชั้นเรียนอื่นหรือคุณอาจจะขาดเรียนที่ฟังก์ชั่นนี้อาจเป็นของวิธีการ
Bill K

11

เหตุผลหนึ่งที่คุณอาจต้องการที่จะประกาศวิธีการช่วยเหลือแบบคงที่คือถ้าคุณต้องการที่จะเรียกพวกเขาในตัวสร้างชั้นเรียน "ก่อน" หรือthis superตัวอย่างเช่น:

public class MyClass extends SomeOtherClass { 
    public MyClass(String arg) {
       super(recoverInt(arg));
    }

    private static int recoverInt(String arg) {
       return Integer.parseInt(arg.substring(arg.length() - 1));
    }
}

นี่เป็นตัวอย่างเล็กน้อยที่คาดการณ์ไว้ แต่recoverIntไม่สามารถใช้วิธีการอินสแตนซ์ในกรณีนี้ได้อย่างชัดเจน


คุณสามารถเรียกใช้เมธอดอินสแตนซ์ใน Constructor ได้ แต่หากคุณมอบหมายให้ Constructor อื่นด้วย super (... ) หรือ This (... ) คุณจะไม่สามารถเรียกเมธอดอินสแตนซ์ได้จนกว่าหลังจากการมอบหมาย (แต่สถิตอยู่ ตกลงตามที่คุณชี้ให้เห็น)
กีบ

10

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

สำหรับวิธีที่มีสิทธิ์การเข้าถึงที่แตกต่างกันฉันคิดว่ามีข้อโต้แย้งหลักสองประการ:

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

นอกจากนั้นความแตกต่างนั้นค่อนข้างเล็กและฉันสงสัยอย่างมากว่าตัวชี้พิเศษที่ส่งผ่านไปยังวิธีการแบบอินสแตนซ์นี้สร้างความแตกต่างอย่างมีนัยสำคัญ


4
ข้อดีของการไม่ทำให้เป็นแบบสแตติกคือบางคนสามารถ subclass และแทนที่ลักษณะการทำงานของเมธอด
Clint Miller

7
Clint เป็นวิธีการแบบส่วนตัวเพื่อให้คุณไม่สามารถแทนที่วิธีการได้
Bhushan Bhangale

สำหรับวิธีการส่วนตัวฉันไม่คิดว่ามันจะสร้างความแตกต่างได้มากนัก อย่างไรก็ตามสำหรับวิธีการสาธารณะฉันเห็นด้วยกับสิ่งที่คุณกำลังพูด
Axelle Ziegler

8

คำตอบที่ถูกต้องคือ:

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


5

หรือมีสาเหตุใดที่ทำให้ [ประกาศเป็นแบบคงที่] ไม่ได้?

ใช่.

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

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

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

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

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

ดูวิดีโอที่เกี่ยวข้องได้ที่นี่: วิธีการออกแบบ API ที่ดีและทำไมจึงสำคัญ

แม้ว่าจะไม่เกี่ยวข้องโดยตรงกับการอภิปรายวิธี "static vs instance" แต่มันก็แตะที่ประเด็นที่น่าสนใจในการออกแบบ API


1
เห็นด้วยอย่างสมบูรณ์ ฉันมักจะพยายามหลีกเลี่ยงสถิตยศาสตร์และเอกชนพร้อมกันด้วยเหตุผลนี้ ฉันคิดว่าคำตอบอื่น ๆ ส่วนใหญ่พลาดจุด
Clint Miller

22
เรากำลังพูดถึงผู้ช่วยส่วนตัวซึ่งหมายความว่าพวกเขาไม่ได้เป็นส่วนหนึ่งของ API สาธารณะของชั้นเรียน นั่นหมายความว่าไม่มีอะไรเลยที่จะป้องกันไม่ให้คุณมีการนำไปใช้ที่แตกต่างกันในภายหลังทำให้พวกเขาไม่คงที่หรือเปลี่ยนแปลงอื่น
Jonik

อ่าาาาา ... นั่นเป็นจุดที่ดีนะ ยังคงสร้างนิสัยที่ดีควรมีเหตุผลเพียงพอ (ผู้กระทำการพูดของหลักสูตร)
OscarRyz

2
ไม่เห็นด้วยอย่างสมบูรณ์ ไม่มีเหตุผลที่ดีที่คุณต้องการเปลี่ยนวิธีการส่วนตัวโดยไม่ต้องเปลี่ยนคลาสที่กำหนดไว้ วิธีเดียวที่จะทำสิ่งที่คุณแนะนำคือการจัดการด้วยรหัสไบต์
Peter Lawrey

2
สิ่งที่คุณแนะนำอาจสมเหตุสมผลถ้าวิธีนั้นไม่เป็นส่วนตัว แต่ถึงกระนั้นฉันก็ขอแนะนำให้คุณออกแบบตามความต้องการในปัจจุบันมากกว่าการออกแบบตามความต้องการในจินตนาการ
Peter Lawrey

5

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


2
คุณไม่ควรเขียนการทดสอบสำหรับวิธีการส่วนตัว ดูที่นี่ ไม่จำเป็นต้องทดสอบวิธีการส่วนตัวไม่ว่าจะเป็นแบบคงที่หรือไม่ก็ตาม
BW

@BW นั่นเป็นเรื่องส่วนตัวมาก มีเหตุผลที่ถูกต้องมากมายในการทดสอบวิธีการส่วนตัว
ruohola

4

หากวิธีการนั้นเป็นเพียงแค่รูทีนย่อยที่จะไม่ใช้ข้อมูลสถานะล่วงหน้าให้ประกาศว่าคงที่

วิธีนี้ช่วยให้สามารถใช้ในวิธีการคงที่อื่น ๆ หรือในการเริ่มต้นคลาสเช่น:

public class Example {
   //...

   //Only possible if computeOne is static
   public final static double COMPUTED_ONE = computeOne(new Something("1"));

   //...
}

3

คำถามแบบคงที่ / ไม่คงที่ลงมาที่ "ฉันจะต้องใช้วัตถุของชั้นนี้จริง ๆ " หรือไม่

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

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


3

การตั้งค่าของฉันในกรณีเช่นนี้คือการสร้างcomputeOneและcomputeMoreวิธีการคงที่ เหตุผล: การห่อหุ้ม รหัสน้อยลงซึ่งมีการเข้าถึงการใช้งานในชั้นเรียนของคุณดีกว่า

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


3

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

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

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


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

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

3

จากประสบการณ์ที่ฉันจะระบุว่าวิธีการส่วนตัวดังกล่าวมีแนวโน้มที่จะเป็นสากลและนำมาใช้ใหม่

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

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


2

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


คำตอบเล็ก ๆ น้อย ๆ นี้ซึ่งถูกฝังอยู่ใต้ภาระของคำตอบอื่น ๆ นั้นสัมผัสกับสาระสำคัญของเรื่อง: ฟังก์ชั่นระดับชั้นกับฟังก์ชั่นระดับวัตถุ
eljenso

ขอบคุณเอลฉันซาบซึ้งจริงๆ ฉันจะไม่คิดคะแนนเสียงน้อยขึ้นทั้ง :)
notnot

ฉันให้ +1 ในเวลาที่ฉันเขียนความคิดเห็น
eljenso

1
ฉันไม่เห็นด้วย. ความชัดเจนของรหัสยังมีความสำคัญสำหรับวิธีการส่วนตัว มันอาจจะมีความสำคัญน้อยกว่า แต่ก็ยังมีบางสิ่งที่ต้องพยายาม
LegendLength

1

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


ดูคำตอบของฉันด้านล่าง (ฉันเพิ่มการวิเคราะห์หลังจากที่มันอยู่ที่ -3 แล้วดังนั้นจึงมองไม่เห็นมาก)
Michael Myers

1

อย่างที่หลายคนบอกว่าทำให้มันคงที่ ! นี่คือกฎของหัวแม่มือที่ฉันปฏิบัติตาม: หากคุณคิดว่าวิธีนี้เป็นเพียงฟังก์ชันทางคณิตศาสตร์นั่นคือไร้สัญชาติไม่เกี่ยวข้องกับตัวแปรอินสแตนซ์ใด ๆ (=> ไม่มี vars สีฟ้า [ใน eclipse] ในวิธีการ) และผลลัพธ์ของ วิธีการจะเหมือนกันสำหรับจำนวนการโทร 'n' (ด้วยพารามิเตอร์เดียวกันของหลักสูตร) ​​จากนั้นทำเครื่องหมายวิธีนั้นเป็น STATIC

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


1

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

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


-1: SO ไม่ใช่ฟอรัมการส่งข้อความ คุณจะทำได้ดีขึ้นโดยการถามคำถามที่เหมาะสม
Stu Thompson

1
ฉันต้องการที่จะมีวิธีการช่วยเหลือพร้อมกับชั้นเรียนที่พวกเขาถูกผูกไว้ / เกี่ยวข้องกับการเป็นแบบคงที่ ยิ่งกว่านั้นฉันสามารถเปิดเผยบางอย่างเป็นสาธารณะถ้าพวกเขาควรใช้ภายนอก วิธีนี้จะเป็นการง่ายกว่าที่จะรักษา API สำหรับคลาสนั้นถ้าควรจะเปิดเผยต่อสาธารณะและใช้อย่างหนาแน่น
Ivaylo Slavov

1
class Whatever {

    public static varType myVar = initializeClassVariable();

    private static varType initializeClassVariable() {

        //initialization code goes here
    }
}

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


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

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


0

ฉันจะประกาศให้พวกเขาเป็นแบบคงที่เพื่อตั้งค่าสถานะพวกเขาเป็นไร้สัญชาติ

Java ไม่มีกลไกที่ดีกว่าสำหรับการดำเนินการย่อยที่ไม่ได้ถูกส่งออกดังนั้นฉันคิดว่าสแตติกส่วนตัวเป็นที่ยอมรับ

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