ความแตกต่างระหว่าง <?> และ <? ขยาย Object> ใน Java Generics?


98

ฉันเคยเห็นตัวแทนที่ใช้มาก่อนเพื่อหมายถึงวัตถุใด ๆ - แต่เพิ่งเห็นการใช้:

<? extends Object>

เนื่องจากออบเจ็กต์ทั้งหมดขยาย Object จึงมีการใช้งานทั้งสองนี้เหมือนกัน


2
มันเป็นเรื่องเดียวกัน ดูstackoverflow.com/questions/2274720/…
แดน

3
@ Dan ถ้าคุณค้นหา "? expands Object" ในคำถามนั้นคุณไม่พบอะไรเลย ฉันกำลังอ่านคำตอบเพื่อดูว่าฉันสามารถสรุปอะไรได้บ้าง แต่ฉันไม่คิดว่าเป็นอย่างนั้น โดยเฉพาะไม่ได้พูดถึงยาชื่อสามัญ
orbfish

@ แดน - นั่นเป็นคำถามที่แตกต่างออกไป ฉันเคยเห็นคำถามนี้มาก่อนและฉันจำได้ว่าอย่างน้อยก็มีการกล่าวถึงความแตกต่างเล็กน้อย ให้ฉันดูว่าฉันจะหาได้ไหม ..
Paul Bellora

ยังไม่ใช่สิ่งนี้หากคุณพบ: stackoverflow.com/questions/678822/…
orbfish

1
ไปที่นี่: เป็นไปได้ที่จะซ้ำกันของอักขระตัวแทนที่ไม่ถูกผูกไว้ใน Java (มีคำตอบที่ไม่ถูกต้องโดย Kevin Bourrillion ไม่น้อยกว่านี้)
Paul Bellora

คำตอบ:


104

<?>และ<? extends Object>มีความหมายเหมือนกันตามที่คุณคาดหวัง

มีบางกรณีที่มียาสามัญที่extends Objectไม่ซ้ำซ้อนจริง ยกตัวอย่างเช่น<T extends Object & Foo>จะทำให้เกิดการTที่จะกลายเป็นObjectภายใต้การลบในขณะที่มี<T extends Foo>มันจะกลายเป็นFooภายใต้การลบออก (สิ่งนี้อาจมีความสำคัญหากคุณพยายามรักษาความเข้ากันได้กับ API รุ่นก่อนชื่อที่ใช้Object)

ที่มา: http://download.oracle.com/javase/tutorial/extra/generics/convert.html ; มันอธิบายว่าทำไมjava.util.Collectionsคลาสของ JDK จึงมีวิธีการที่มีลายเซ็นนี้:

public static <T extends Object & Comparable<? super T>> T max(
    Collection<? extends T> coll
)

4
ฉันไม่ชัดเจนว่าตัวอย่างเกี่ยวข้องกันอย่างไร? (เนื่องจากไม่ใช้ทั้ง <?> หรือ <? ขยายวัตถุ>)
orbfish

27
@orbfish: มันเกี่ยวข้องเฉพาะในที่ฉันคิดว่าคุณจะพบว่ามันน่าสนใจที่เป็นตัวอย่างที่extends Objectจริงเป็นความหมาย ถ้าผิดพลาดยังไงก็ขออภัยด้วย หวังว่าจะเป็นที่สนใจของคนอื่น ๆ ที่เจอคำถามของคุณอย่างน้อยที่สุด
ruakh

@ruakh - สนใจสัญลักษณ์แทนแบบมีขอบเขตมากกว่าพารามิเตอร์ประเภท แต่อย่างน้อยคุณก็ตอบ
orbfish

1
คุณควรระบุไว้ในโพสต์เดิมของคุณแล้ว ด้วยวิธีนี้คำตอบของเขาน่าจะเกี่ยวข้องกับคุณมากกว่า
liltitus27

19

แม้ว่า<?>ควรจะเป็นทางลัด<? extend object>แต่ก็มีความแตกต่างเล็กน้อยระหว่างสองอย่างนี้ <?>สามารถ reifiable ในขณะที่<? extend object>ไม่ได้ เหตุผลที่พวกเขาทำเช่นนี้คือทำให้ง่ายต่อการแยกแยะประเภทที่นำกลับมาใช้ใหม่ได้ สิ่งใดที่มีลักษณะเช่น<? extends something>, <T>, <Integer>มี nonreifiable

ตัวอย่างเช่นรหัสนี้จะใช้งานได้

List aList = new ArrayList<>();
boolean instanceTest = aList instanceof List<?>;

แต่สิ่งนี้ทำให้เกิดข้อผิดพลาด

List aList = new ArrayList<>();
boolean instancetest = aList instanceof List<? extends Object>;

สำหรับข้อมูลเพิ่มเติมโปรดอ่านข้อมูลทั่วไปและคอลเล็กชัน Java โดย Maurice Naftalin


List <?> สามารถ reifiable ได้อย่างไรถ้าคอมไพเลอร์จะแปลเป็น List <Object> ดังนั้นข้อมูลเกี่ยวกับประเภทของอะไร? หลงทาง?
Trismegistos

สิ่งที่ฉันเชื่อว่า <?> ได้รับการออกแบบมาเพื่อให้เข้ากันได้กับ API แบบเดิมมากกว่า เพื่อแยกความแตกต่างด้วย <Object> และ <? ขยาย Object> ซึ่งโพสต์โค้ด Java 5
Dennis C

9

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


<?>

"?"หมายถึงประเภทที่ไม่รู้จักซึ่งสามารถแสดงประเภทใดก็ได้ในรหัสสำหรับ ใช้สัญลักษณ์แทนนี้หากคุณไม่แน่ใจเกี่ยวกับประเภท

ArrayList<?> unknownList = new ArrayList<Number>(); //can accept of type Number
unknownList = new ArrayList<Float>(); //Float is of type Number

หมายเหตุ: <?>หมายถึงสิ่งใด ๆ ดังนั้นจึงสามารถยอมรับประเภทที่ไม่ได้รับมาจากObjectคลาส

<? extends Object>

<? extends Object>หมายความว่าคุณสามารถส่งผ่าน Object หรือคลาสย่อยที่ขยายObjectคลาสได้

ArrayList<? extends Number> numberList = new ArrayList<Number>(); //Number of subclass
numberList = new ArrayList<Integer>(); //Integer extends Number
numberList = new ArrayList<Float>(); // Float extends Number 

ป้อนคำอธิบายภาพที่นี่

T - ใช้เพื่อแสดงประเภท
E - ใช้เพื่อแสดงองค์ประกอบ
K - คีย์
V - ค่า
N - สำหรับตัวเลข
อ้างอิง:

ป้อนคำอธิบายภาพที่นี่


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