Class <?> หมายความว่าอะไรใน Java


140

คำถามของฉันมีดังข้างต้น ขออภัยมันอาจจะซ้ำกัน แต่ฉันไม่พบตัวอย่าง<?>ในตอนท้าย

ทำไมคุณไม่ใช้Classเป็นพารามิเตอร์



คำตอบ:


114

Classเป็นคลาสที่ปรับพารามิเตอร์ได้ดังนั้นคุณสามารถใช้ไวยากรณ์Class<T>โดยที่Tเป็นประเภทได้ ด้วยการเขียนแสดงClass<?>ว่าคุณกำลังประกาศClassออบเจ็กต์ที่สามารถเป็นประเภทใดก็ได้ ( ?เป็นสัญลักษณ์แทน) Classประเภทคือประเภทที่มีเมตาข้อมูลเกี่ยวกับระดับหนึ่ง

เป็นแนวทางปฏิบัติที่ดีเสมอในการอ้างถึงประเภททั่วไปโดยการระบุประเภทเฉพาะของเขาโดยใช้Class<?>ว่าคุณปฏิบัติตามแนวทางปฏิบัตินี้ (คุณทราบว่าClassสามารถกำหนดพารามิเตอร์ได้) แต่คุณไม่ได้ จำกัด พารามิเตอร์ให้มีประเภทเฉพาะ

ข้อมูลอ้างอิงเกี่ยวกับ Generics และ Wildcards: http://docs.oracle.com/javase/tutorial/java/generics/wildcards.html

การอ้างอิงเกี่ยวกับClassวัตถุและการสะท้อน (คุณลักษณะของภาษา Java ที่ใช้ในการไตร่ตรองตัวเอง): https://www.oracle.com/technetwork/articles/java/javareflection-1536171.html


8
ประโยชน์ของการทำเช่นนี้เพียงแค่ใช้Classโดยไม่มีประเภทคืออะไร? ดูเหมือนจะเป็นตัวแทนของสิ่งเดียวกัน
ashes999

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

7
ไม่มีประโยชน์อื่นใดนอกจากคุณจะบอกคอมไพเลอร์ว่า "ฉันรู้ว่านี่เป็นคลาสทั่วไป แต่ฉันไม่รู้หรือสนใจเกี่ยวกับประเภทที่แท้จริงดังนั้นแทนที่จะให้ประเภทคอนกรีตฉันจะให้?สัญลักษณ์แทน" . หากคุณไม่ให้สัญลักษณ์แทนคอมไพลเลอร์จะถือว่าคุณลืมประเภทหรือไม่ทราบว่าคลาสเป็นแบบทั่วไปและจะเตือนคุณเกี่ยวกับเรื่องนี้
Kayaman

1
อะไรที่เทียบเท่ากับ KotlinClass<?>
Jack Guo

เพียงแค่Classไม่สามารถส่งผ่านไปยังอาร์กิวเมนต์ชนิดเป็น Class<?>ดังนั้นClass<?>มีความสะดวกมากขึ้นสำหรับทุกสถานการณ์
petertc

76

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

ไม่เป็นปัญหาเมื่อใช้กับClass. ทั้งสองบรรทัดทำงานและคอมไพล์:

Class anyType = String.class;
Class <?> theUnknownType = String.class;

แต่ - ถ้าเราเริ่มใช้กับคอลเลกชั่นเราจะเห็นข้อผิดพลาดในการคอมไพล์ไทม์แปลก ๆ

List<?> list = new ArrayList<Object>();  // ArrayList<?> is not allowed
list.add("a String");                    // doesn't compile ...

ของเราList<?>ไม่ใช่คอลเลกชันที่เหมาะสำหรับวัตถุทุกประเภท สามารถจัดเก็บได้เพียงประเภทเดียวเท่านั้น: "ประเภทที่ไม่รู้จัก" ลึกลับ ซึ่งไม่ใช่ประเภทจริงอย่างแน่นอน.


9

หมายความว่าการอ้างอิงคลาสของคุณสามารถถือการอ้างอิงถึงคลาสออบเจ็กต์ใดก็ได้

โดยพื้นฐานแล้วมันเหมือนกับ "Class" แต่คุณกำลังแสดงให้คนอื่น ๆ ที่อ่านโค้ดของคุณซึ่งคุณไม่ลืมเกี่ยวกับ generics คุณแค่ต้องการข้อมูลอ้างอิงที่สามารถเก็บวัตถุ Class ใดก็ได้

Bruce Eckel คิดใน Java:

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


1
คำพูดระบุว่า "Class <?> is recommended over plain Class" และ "The benefit of Class <?>" ดูเหมือนว่า blockquote จะไม่เห็นด้วยกับวงเล็บเหลี่ยม
ฆา

1
มันจำเป็นต้องหนี แก้ไขแล้ว: P
Sami Kuhmonen

5

มันเป็นตัวอักษรทั่วไป หมายความว่าคุณไม่ทราบประเภทของคลาสที่Classอินสแตนซ์นี้เป็นตัวแทน แต่คุณยังคงใช้เวอร์ชันทั่วไป

  • Class<Foo>ถ้าคุณรู้ว่าชั้นเรียนที่คุณต้องการใช้ ด้วยวิธีนี้คุณสามารถสร้างอินสแตนซ์ใหม่ตัวอย่างเช่นโดยไม่ต้องแคสต์:Foo foo = clazz.newInstance();
  • หากคุณไม่ใช้ยาชื่อสามัญเลยคุณจะได้รับคำเตือนอย่างน้อยที่สุด (และโดยทั่วไปไม่แนะนำให้ใช้ยาชื่อสามัญเพราะอาจนำไปสู่ผลข้างเคียงที่ตรวจพบได้ยาก)


3

นั่นหมายถึงคลาสที่มีประเภทอะไรก็ได้ (ไม่ทราบ)

คุณควรอ่านบทช่วยสอน java generics เพื่อทำความเข้าใจให้ดีขึ้น

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