ทำไมวิธีหลักแบบคงที่ใน Java และ C # มากกว่าตัวสร้าง?


54

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


ความเป็นมาและรายละเอียดของการวิจัยก่อนหน้าของฉัน

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

  • จะมีความกำกวมหากคอนสตรัคเตอร์มากเกินไป - ในความเป็นจริง C # (เช่นเดียวกับ C และ C ++) ช่วยให้ลายเซ็นที่แตกต่างกันเพื่อMainให้มีความกำกวมที่อาจเกิดขึ้นเหมือนกันและมีการจัดการ
  • staticวิธีหมายถึงวัตถุที่ไม่สามารถ instantiated ก่อนเพื่อให้คำสั่งของ initialisation เป็นที่ชัดเจน - นี่เป็นเพียงความผิดจริงวัตถุบางอย่างจะถูกยกตัวอย่างก่อน (เช่นในตัวสร้างแบบคงที่)
  • ดังนั้นจึงสามารถเรียกใช้โดยรันไทม์โดยไม่ต้องสร้างอินสแตนซ์ของวัตถุหลัก - นี่ไม่ใช่คำตอบเลย

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

  • กรอบหลายคนไม่ใช้ชั้นเรียนเพื่อเป็นตัวแทนของการใช้งานและการก่อสร้างเป็นจุดเข้า ยกตัวอย่างเช่นกรอบใบสมัคร VB.NETใช้โต้ตอบเฉพาะหลัก (และตัวสร้างของมัน) เป็นจุดเริ่มต้นที่1

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

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

ฉันสนใจคำตอบที่ชัดเจนจากแหล่งข้อมูลหลักหรือแหล่งข้อมูลรองไม่ใช่เพียงการคาดเดา


1แม้ว่าจะมีการเรียกกลับ ( Startup) ซึ่งอาจดักจับสิ่งนี้


4
@mjfgates นอกจากนี้ฉันหวังว่าจะทำให้ชัดเจนว่านี่ไม่ใช่แค่ "ทำไมคนไม่ทำอย่างที่ฉันต้องการ" และฉันก็สนใจเหตุผลอย่างแท้จริง
Konrad Rudolph

2
สำหรับ Java ฉันคิดว่าเหตุผลนั้นง่าย: เมื่อพัฒนา Java พวกเขารู้ว่าคนส่วนใหญ่ที่เรียนรู้ภาษาจะรู้จัก C / C ++ ล่วงหน้า ดังนั้น Java ไม่เพียง แต่มีลักษณะเหมือน C / C ++ มากกว่าพูด smalltalk แต่ยังเข้ายึดถือ idiosynchrasies จาก C / C ++ (เพียงคิดว่าตัวอักษรจำนวนเต็มฐานแปด) เนื่องจาก c / c ++ ทั้งคู่ใช้วิธีการหลักการทำเช่นเดียวกันกับ java ทำให้รู้สึกจากมุมมองนั้น
Voo

5
@Jarrod คุณไม่ยุติธรรม ฉันคิดว่าฉันได้ทำให้มันค่อนข้างชัดเจนว่าไม่ได้เป็นคนพูดจาโผงผาง “ ไม่สร้างสรรค์”? งั้นเหรอ ฉันขออ้างอิงอย่างชัดเจนไม่ใช่แค่การพูดคุยอย่างบ้าคลั่ง คุณมีอิสระที่จะไม่เห็นด้วยว่านี่เป็นคำถามที่น่าสนใจ แต่ถ้าคำถามประเภทนี้คือ OT ที่นี่ฉันไม่เห็นว่า Programmers.SE มีจุดประสงค์อะไร
Konrad Rudolph

2
ที่เกี่ยวข้องการอภิปราย Meta
yannis

3
คำถาม: ถ้าเป็นแอปพลิเคชันวัตถุคุณไม่ต้องการสองสิ่ง 1) ตัวสร้าง 2) วิธีการบนวัตถุเพื่อเรียกใช้แอปพลิเคชันของคุณ ตัวสร้างต้องทำให้เสร็จสมบูรณ์สำหรับวัตถุให้ถูกต้องและทำให้สามารถเรียกใช้
Martin York

คำตอบ:


38

TL; DR

ใน Java เหตุผลpublic static void main(String[] args)ก็คือ

  1. ลูกห่านที่ต้องการ
  2. รหัสที่เขียนโดยคนที่มีประสบการณ์ใน C (ไม่ใช่ใน Java)
  3. จะถูกประหารโดยใครบางคนที่เคยใช้งานPostScriptบนNeWS

http://i.stack.imgur.com/qcmzP.png

 
สำหรับ C # เหตุผลคล้ายคลึงกันในลักษณะทรานซิทจึงจะพูด นักออกแบบภาษายังคงคุ้นเคยกับไวยากรณ์จุดเข้าใช้งานโปรแกรมสำหรับโปรแกรมเมอร์ที่มาจาก Java ในฐานะที่เป็น C # สถาปนิกAnders Hejlsberg ทำให้มัน ,

... แนวทางของเรากับ C # เป็นเพียงการนำเสนอทางเลือก ... แก่โปรแกรมเมอร์ Java ...

 

รุ่นยาว

ขยายด้านบนและสำรองด้วยการอ้างอิงที่น่าเบื่อ

 

java Terminator เรียนรู้เกี่ยวกับ Baby!

VM Spec, 2.17.1 การเริ่มต้นเครื่องเสมือน

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

java Terminator Hasta la vista Baby!

จะเริ่มต้นเครื่องเสมือน Java โดยเรียกใช้เมธอด main ของคลาสTerminator(คลาสในแพ็กเกจที่ไม่มีชื่อ) และส่งผ่านอาร์เรย์ที่มีสี่สตริง "Hasta", "la", "vista" และ "Baby!" ...

... ดูเพิ่มเติม: ภาคผนวก: ฉันต้องการเสื้อผ้ารองเท้าบู๊ทและมอเตอร์ไซค์ของคุณ

  • การตีความของฉัน:
    การดำเนินการเป้าหมายสำหรับการใช้งานเช่นสคริปต์ทั่วไปในอินเตอร์เฟสบรรทัดคำสั่ง

 

ก้าวเท้าเลี่ยง

... ที่ช่วยหลีกเลี่ยงร่องรอยที่ผิดพลาดในการสืบสวนของเรา

VM Spec, 1.2 The Java Virtual Machine

เครื่องเสมือน Java ไม่รู้ภาษาการเขียนโปรแกรม Java ...

ฉันสังเกตเห็นข้างต้นเมื่อศึกษาบทก่อนหน้า - 1.1 ประวัติศาสตร์ซึ่งฉันคิดว่าอาจเป็นประโยชน์ (แต่กลับกลายเป็นว่าไร้ประโยชน์)

  • การตีความของฉัน:
    การประมวลผลถูกควบคุมโดยข้อมูลจำเพาะของ VM เพียงอย่างเดียวซึ่ง
    ประกาศอย่างชัดเจนว่าไม่มีส่วนเกี่ยวข้องกับภาษา Java
    => ตกลงเพื่อละเว้นJLSและภาษา Java ที่เกี่ยวข้องทั้งหมด

 

ลูกห่าน: ประนีประนอมระหว่าง C และภาษาสคริปต์ ...

ขึ้นอยู่กับข้างต้นผมเริ่มค้นหาเว็บสำหรับประวัติ JVM ไม่ได้ผลขยะมากเกินไป

แล้วฉันจะเล่าตำนานเกี่ยวกับกอสลิงและแคบลงค้นหาของฉันไปประวัติศาสตร์ลูกห่าน JVM

ยูเรก้า! JVM Spec มาเป็นอย่างไร

ในคำปราศรัยนี้จาก JVM Languages ​​Summit 2008, James Gosling พูดถึง ... การสร้างของ Java, ... การประนีประนอมระหว่างภาษา C และภาษาสคริปต์ ...

  • การตีความของฉัน:
    ประกาศอย่างชัดเจนว่าในขณะที่สร้าง
    C และการเขียนสคริปต์ได้รับการพิจารณาอิทธิพลที่สำคัญที่สุด
     
    เห็นแล้วพยักหน้าให้สคริปต์ใน VM Spec 2.17.1,
    อาร์กิวเมนต์บรรทัดคำสั่งพออธิบายString[] args
    แต่staticและmainไม่ได้มี แต่ต้องขุดต่อไป ...

หมายเหตุในขณะที่พิมพ์สิ่งนี้ - การเชื่อมต่อ C, การเขียนสคริปต์และ VM Spec 1.2 โดยไม่มีอะไรเลย - ฉันรู้สึกว่าคุ้นเคยกับบางสิ่งบางอย่าง ... การวางเชิงวัตถุนั้นผ่านไปอย่างช้าๆ จับมือฉันไว้ก่อนแล้วอย่าช้าลงเราใกล้จะถึงแล้ว

สไลด์ Keynote มีให้บริการออนไลน์: 20_Gosling_keynote.pdfค่อนข้างสะดวกสำหรับการคัดลอกประเด็นสำคัญ

    หน้า 3

        ประวัติศาสตร์ของ Java
        * อะไรที่ทำให้ฉันคิด

    หน้า 9

        ข่าว
        * ระบบหน้าต่างที่ขยายได้บนเครือข่าย
        * ระบบหน้าต่างอ้างอิงสคริปต์ ....
          PostScript (!!)

    หน้า 16

        เป้าหมายใหญ่ (แต่เงียบ):
          ฉันจะได้ใกล้ชิดแค่ไหน
          ความรู้สึก "การเขียนสคริปต์" ...

    หน้า 19

        แนวคิดดั้งเดิม
        * ทุกอย่างเกี่ยวกับการสร้าง
          เครือข่ายของสิ่งต่าง ๆ
          เตรียมการโดยสคริปต์
          ภาษา
        * (Unix shells, AppleScript, ... )

    หน้า 20

        A Wolf in Sheeps เครื่องแต่งกาย
        * C ไวยากรณ์เพื่อให้นักพัฒนา
          สบาย

A-Ha! ลองดูที่ไวยากรณ์ C ให้ละเอียดยิ่งขึ้น

ตัวอย่าง "สวัสดีโลก" ...

main()
{
    printf("hello, world\n");
}

... ฟังก์ชั่นชื่อ main กำลังถูกกำหนด หลักฟังก์ชั่นทำหน้าที่เป็นวัตถุประสงค์พิเศษในโปรแกรม C; สภาพแวดล้อมรันไทม์เรียกใช้ฟังก์ชันหลักเพื่อเริ่มการทำงานของโปรแกรม

... ฟังก์ชั่นหลักที่จริงมีสองข้อโต้แย้งint argcและchar *argv[]ตามลำดับซึ่งสามารถใช้ในการจัดการข้อโต้แย้งบรรทัดคำสั่ง ...

เราเข้าใกล้ไหม? พนันได้เลย. นอกจากนี้ยังมีมูลค่าต่อไปนี้ลิงค์ "หลัก" จากใบเสนอราคาด้านบน:

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

  • การตีความของฉัน:
    การจะมีความสะดวกสบายสำหรับนักพัฒนา C, mainจุดเข้าโปรแกรมจะต้องมี
    นอกจากนี้ตั้งแต่ Java ต้องใช้วิธีการใด ๆ ที่จะอยู่ในระดับClass.mainเป็น
    ที่ใกล้ที่สุดเท่าที่จะได้รับ: การภาวนาแบบคงที่ชื่อชั้นและเพียงแค่จุด
    ไม่มีการก่อสร้างโปรด - C รู้อะไรเช่นนั้น
     
    นอกจากนี้ยังสกรรมกริยานำไปใช้กับ C # คำนึงถึง
    ความคิดของการย้ายถิ่นง่ายที่จะได้จาก Java

ผู้อ่านที่คิดว่าจุดเข้าโปรแกรมที่คุ้นเคยนั้นไม่สำคัญโปรดเชิญให้ค้นหาและตรวจสอบคำถาม Stack Overflow ที่ผู้ที่มาจาก Java SE กำลังพยายามเขียนHello Worldสำหรับ Java ME MIDP หมายเหตุจุดเข้า MIDPไม่มีมิได้mainstatic

 

ข้อสรุป

บนพื้นฐานดังกล่าวข้างต้นผมจะบอกว่าstatic, mainและString[] argsอยู่ในช่วงเวลาของการ Java และ C # การสร้างทางเลือกที่เหมาะสมที่สุดในการกำหนดจุดเข้าโปรแกรม

 

ภาคผนวก: ฉันต้องการเสื้อผ้ารองเท้าบู๊ทและมอเตอร์ไซค์ของคุณ

ต้องยอมรับการอ่าน VM Spec 2.17.1นั้นสนุกมาก

... บรรทัดคำสั่ง

java Terminator Hasta la vista Baby!

จะเริ่มต้นเครื่องเสมือน Java โดยเรียกใช้เมธอด main ของคลาสTerminator(คลาสในแพ็กเกจที่ไม่มีชื่อ) และส่งผ่านอาร์เรย์ที่มีสี่สตริง "Hasta", "la", "vista" และ "Baby!"

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

ความพยายามเริ่มต้น ... พบว่าคลาสTerminatorไม่โหลด ...

หลังจากTerminatorโหลดแล้วจะต้องเริ่มต้นได้ก่อนที่จะสามารถเรียกใช้งานหลักและต้องเชื่อมโยงประเภท (คลาสหรืออินเทอร์เฟซ) ก่อนที่จะเริ่มต้นได้ การเชื่อมโยง (§2.17.3) เกี่ยวข้องกับการตรวจสอบการเตรียมการและ (ทางเลือก) การแก้ไข ...

การตรวจสอบ (§2.17.3) ตรวจสอบว่าการแสดงการโหลดTerminatorถูกสร้างขึ้นอย่างดี ...

ความละเอียด (.12.17.3) เป็นกระบวนการตรวจสอบการอ้างอิงสัญลักษณ์จากคลาสTerminator...

 
การอ้างอิงเชิงสัญลักษณ์จากTerminatoroh yeah


2
ด้วยเหตุผลบางอย่างฉันรู้สึกลำบากใจที่เชื่อว่า "ความทันสมัย" เป็นคำที่แท้จริง
someguy

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

16

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

หากคุณใส่ฟังก์ชั่นการใช้งานพื้นฐานไว้ภายใน Constructor แล้วไม่เคยใช้วัตถุที่ Constructor สร้างขึ้นในโค้ดภายนอกคุณจะละเมิดหลักการของ OOP โดยพื้นฐานแล้วการทำสิ่งที่แปลกจริงๆโดยไม่มีเหตุผลชัดเจน

ทำไมคุณถึงต้องการทำเช่นนั้น?


5
แต่ไม่ใช่ "แอปพลิเคชันอินสแตนซ์" วัตถุอย่างมีเหตุผลหรือไม่ ทำไมมันถึงไม่เหมาะสม? สำหรับการใช้วัตถุ - มันมีจุดประสงค์เดียว: แสดงถึงแอปพลิเคชันที่กำลังทำงาน ฟังSoC -y มากสำหรับฉัน “ ทำไมคุณต้องการทำเช่นนั้น?” - ฉันแค่สนใจเหตุผลในการตัดสินใจเพราะฉันคิดว่ามันขัดแย้งกับความคิดที่เหลือ
Konrad Rudolph

7
@KonradRudolph: คอนสตรัคเช่นตัวรับทรัพย์สินเป็นที่คาดกันว่าจะเสร็จสมบูรณ์ในเวลาที่ จำกัด โดยไม่ต้องรอเหตุการณ์แบบอะซิงโครนัส (เช่นการป้อนข้อมูลของผู้ใช้) ที่จะเกิดขึ้น เป็นไปได้ที่จะมี Constructor ที่เปิดตัวเธรดแอปพลิเคชันหลัก แต่เพิ่มระดับความซับซ้อนซึ่งอาจไม่จำเป็นสำหรับแอปพลิเคชันทั้งหมด การขอให้แอปพลิเคชันคอนโซลที่พิมพ์ "Hello world" ไปยังเอาต์พุตมาตรฐานควรวางไข่เธรดพิเศษจะไม่ทำงาน การใช้Mainวิธีการทำงานได้ดีสำหรับกรณีง่าย ๆ และไม่ใช่ปัญหาในกรณีที่ยากกว่าดังนั้นทำไมไม่
supercat

9

สำหรับ Java ฉันคิดว่าเหตุผลนั้นง่าย: เมื่อพัฒนา Java ผู้พัฒนารู้ว่าคนส่วนใหญ่ที่เรียนรู้ภาษาจะรู้จัก C / C ++ ล่วงหน้า

ดังนั้น Java ไม่เพียง แต่มีลักษณะเหมือน C / C ++ มากกว่าพูด smalltalk แต่ยังเข้ายึดถือ idiosynchrasies จาก C / C ++ (เพียงคิดว่าตัวอักษรจำนวนเต็มฐานแปด) เนื่องจาก c / c ++ ทั้งคู่ใช้วิธีการหลักการทำเช่นเดียวกันกับ java ทำให้รู้สึกจากมุมมองนั้น

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


2
หากกำลังมองหาเช่นเดียวกับ C ++ เป็นสิ่งสำคัญมากสำหรับ Java, ทำไมพวกเขาตัวอย่างเช่นการเปลี่ยนแปลง:ไปextends? และpublic static void main(String [ ] args)ในชั้นเรียนนั้นค่อนข้างแตกต่างจากint main(int argc, char **argv)นอกห้องเรียน
svick

2
ความเป็นไปได้ @svick One: Java นำเสนออินเตอร์เฟสและชัดเจนว่าพวกเขาต้องการแยกสองแนวคิด (สืบทอดอินเตอร์เฟส / คลาส) - ด้วย "คีย์เวิร์ด" เพียงคำเดียวที่ไม่ทำงาน และ "ค่อนข้างแตกต่าง"? มันเป็นแผนที่ที่ใกล้ที่สุดเท่าที่จะเป็นไปได้และจนถึงตอนนี้ฉันไม่เคยเห็นโปรแกรมเมอร์ c ++ มีปัญหาในการทำความเข้าใจว่าวิธีหลักคงที่คือจุดเริ่มต้น ตรงกันข้ามกับการมีคลาสที่เรียกว่า Application หรือสิ่งที่ใช้ Constructor เป็นสิ่งที่ดูแปลกสำหรับโปรแกรมเมอร์ c ++ ส่วนใหญ่
Voo

@svick int เป็น c เพื่อถือเป็นโมฆะใน java ต้องใช้วิธีสร้างโค้ดส่งคืนจากแอปพลิเคชัน - ใน java จะเป็น 0 ยกเว้นว่ามีการเรียกใช้ System.exit (int) การเปลี่ยนแปลงของพารามิเตอร์เกี่ยวข้องกับวิธีการส่งผ่านอาร์เรย์ของสตริงในแต่ละภาษา ทุกอย่างใน java อยู่ในคลาส - ไม่มีตัวเลือกให้ใช้ที่อื่น เปลี่ยน:ไปextendsเป็นเรื่องของไวยากรณ์และเป็นหลักเดียวกัน ทุกสิ่งทุกอย่างถูกกำหนดโดยภาษา

@MichaelT แต่ทั้งหมดนั้นเป็นการตัดสินใจออกแบบที่ทำให้ Java แตกต่างจาก C ++ ดังนั้นทำไมการทำให้ Java เหมือนกับ C ++ มีความสำคัญในกรณีของmain()เมื่อมันเห็นได้ชัดว่าไม่สำคัญพอในกรณีอื่น ๆ
svick

@svick ยกเว้นว่ามันโอเคอย่างสมบูรณ์แบบที่จะไม่ส่งคืนสิ่งใดจากหลักใน C เช่นกันและสิ่งเล็กน้อยเช่นนี้ก็แทบจะไม่ทำให้ใครสับสนเลย จุดนี้ไม่ใช่การสร้าง c ++ และความผิดพลาดทั้งหมด แต่เพียงเพื่อทำให้โปรแกรมเมอร์ทำงานที่บ้านมากขึ้น คุณคิดว่าโปรแกรมเมอร์ C ++ จะอ่านเวลาได้ง่ายขึ้น: Java หรือรหัส object-c คุณคิดว่าอะไรจะดูชัดเจนกว่าสำหรับโปรแกรมเมอร์ C ++ ซึ่งเป็นวิธีหลักหรือตัวสร้างของบางคลาสเป็นจุดเริ่มต้น?
Voo

6

มีฟังก์ชั่นหลักมากมายอยู่ที่นั่นแค่วิ่งวนวนไม่สิ้นสุด คอนสตรัคทำงานด้วยวิธีนี้ (กับวัตถุที่ไม่เคยถูกสร้างขึ้นมา) เป็นสิ่งที่แปลกสำหรับฉัน

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

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

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

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


1
ฉันจะบอกว่าปัญหาไม่ได้มีฟังก์ชั่นชั้นหนึ่ง การผสานหลัก () ภายในวัตถุ (ที่ไม่ได้สร้างอินสแตนซ์ก่อนที่จะเรียกหลัก) เป็นรูปแบบการต่อต้านเล็กน้อย บางทีพวกเขาควรจะมีวัตถุ "แอปพลิเคชัน" ที่ได้รับการสร้างและเรียกใช้วิธีการที่ไม่คงที่ main () จากนั้นคุณสามารถใส่การเริ่มต้นเริ่มต้นในตัวสร้างและมันจะรู้สึกดีกว่าการมีวิธีคงที่ = level main () fn ก็ดีเช่นกัน หลักคงเป็นบิตของ kludge ทั้งหมดในทุก
gbjbaanb

3

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


1
นี้กับผมน่าจะเป็นเหตุผลที่น่าสนใจมากที่สุดในขณะที่มันยังช่วยให้คะแนนหลายรายการในระหว่างการพัฒนาสำหรับการทดสอบการกำหนดค่าที่แตกต่างกัน ฯลฯ
cgull

0

คุณต้องเริ่มต้นที่ไหนสักแห่ง หลักคงที่คือสภาพแวดล้อมการดำเนินการที่ง่ายที่สุดที่คุณสามารถทำได้ - ไม่ต้องมีอินสแตนซ์ของสิ่งใด (นอก JVM และพารามิเตอร์สตริงแบบง่าย) - ดังนั้นจึงสามารถ "ขึ้นมา" ด้วยความยุ่งยากน้อยที่สุด (และมีโอกาสน้อย ข้อผิดพลาดในการเข้ารหัสป้องกันการเริ่มต้น ฯลฯ ) และสามารถทำสิ่งต่าง ๆ ได้ง่ายโดยไม่ต้องมีการตั้งค่าอื่น ๆ อีกมากมาย

เป็นแอปพลิเคชันของ KISS

[และแน่นอนเหตุผลหลักคือทำไมไม่]


3
อย่างที่ฉันพูดไปฉันไม่เชื่ออย่างนั้น วัตถุจะได้รับอินสแตนซ์ก่อนและรหัสจะถูกดำเนินการก่อน มันต้องมีใบเสนอราคาจากหนึ่งในนักพัฒนาดั้งเดิมเพื่อโน้มน้าวฉันว่านี่คือเหตุผล
Konrad Rudolph

2
จำนวนงานที่จำเป็นในการสร้างอินสแตนซ์ของคลาสจากรหัส C นั้นค่อนข้างเหมือนกันกับการเรียกใช้เมธอดแบบสแตติก .. คุณต้องทำการตรวจสอบแบบเดียวกัน (คลาสนั้นมีอยู่หรือไม่? สบายดีแล้วไปข้างหน้า)
Voo

ไม่จำเป็นต้องสร้างวัตถุผู้ใช้ ตัวสร้างวัตถุไม่ได้ถูกดำเนินการ API นั้นง่ายมาก และมันง่ายที่สุดที่จะเข้าใจ
Daniel R Hicks

0

เพื่อความเข้าใจของฉันเหตุผลหลักนั้นง่าย Sun เป็น บริษัท Unix ที่ขายเครื่องจักร Unix และ Unix เป็นสิ่งที่ C "main (args)" แบบแผนสำหรับการเรียกใช้ไบนารีถูกออกแบบมาสำหรับ

นอกจากนี้ Java ได้รับการออกแบบอย่างชัดเจนเพื่อให้ง่ายต่อการรับโปรแกรมเมอร์ C และ C ++ ดังนั้นจึงไม่มีเหตุผลที่ดีที่ไม่ใช่เพียงแค่เลือกการประชุม C เท่านั้น

วิธีการที่เลือกซึ่งทุกคลาสสามารถมีวิธีการเรียกใช้มีความยืดหยุ่นโดยเฉพาะอย่างยิ่งเมื่อรวมกับMain-Classบรรทัดในไฟล์ MANIFEST.MF ใน jar ที่รันได้


แน่นอนว่าไฟล์ jar ไม่ได้ถูกประดิษฐ์จนกระทั่งในภายหลัง
Daniel R Hicks

-1

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

ยิ่งไปกว่านั้นคอนสตรัคเตอร์ไม่ใช่จุดเริ่มต้นไม่ว่าด้วยวิธีใด

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


1
ฉันคิดว่าคุณผิดที่นั่น มันเป็นไปได้ที่จะมีขั้นตอนมากกว่าหนึ่งด้วยเหตุนี้วัตถุมากกว่าหนึ่ง อนึ่งนี่เป็นการเทียบเท่ากับอินสแตนซ์ของRunnableวัตถุที่มีหลายเธรด
Konrad Rudolph

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

1
อย่างที่ฉันพูดไว้ด้านล่างคำตอบของใครบางคนนี่ไม่เกี่ยวข้องกัน สิ่งที่เกี่ยวข้องคือความสอดคล้องเชิงตรรกะ เหตุผลกระบวนการถูกแสดงเป็นวัตถุโดยตัวเรียกใช้งาน (OS, JVM, อะไรก็ตาม) และถูกกำหนดค่าเริ่มต้น
Konrad Rudolph

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