เหตุใดบางคนจึงอ้างว่าการใช้งานทั่วไปของ Java ไม่ดี


115

บางครั้งฉันได้ยินมาว่าด้วย generics Java ไม่ถูกต้อง (อ้างอิงที่ใกล้ที่สุดที่นี่ )

ให้อภัยในความไม่มีประสบการณ์ของฉัน แต่อะไรจะทำให้พวกเขาดีขึ้น?


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

คำตอบ:


146

แย่:

  • ข้อมูลประเภทจะสูญหายไปในเวลาคอมไพล์ดังนั้นในเวลาดำเนินการคุณไม่สามารถบอกได้ว่า "หมายถึง" เป็นประเภทใด
  • ไม่สามารถใช้กับประเภทค่าได้ (นี่เป็นเรื่องใหญ่ - ใน. NET List<byte>ซึ่งได้รับการสนับสนุนจากbyte[]ตัวอย่างและไม่จำเป็นต้องมีการชกมวย)
  • ไวยากรณ์สำหรับการเรียกวิธีการทั่วไป sucks (IMO)
  • ไวยากรณ์สำหรับข้อ จำกัด อาจทำให้สับสนได้
  • โดยทั่วไปการใช้สัญลักษณ์แทนจะทำให้เกิดความสับสน
  • ข้อ จำกัด ต่าง ๆ เนื่องจากข้างต้น - การหล่อ ฯลฯ

ดี:

  • การใช้สัญลักษณ์แทนช่วยให้สามารถระบุความแปรปรวนร่วม / ความไม่ผันแปรได้ที่ด้านการโทรซึ่งมีความเรียบร้อยมากในหลาย ๆ สถานการณ์
  • ดีกว่าไม่มีอะไรเลย!

51
@ พอล: ฉันคิดว่าฉันน่าจะชอบการแตกชั่วคราว แต่หลังจากนั้น API ที่ดี หรือใช้เส้นทาง. NET และแนะนำประเภทคอลเลกชันใหม่ (.NET generics ใน 2.0 ไม่ทำลาย 1.1 แอพ)
Jon Skeet

6
ด้วยฐานรหัสที่มีอยู่มากฉันชอบความจริงที่ว่าฉันสามารถเริ่มเปลี่ยนลายเซ็นของวิธีการหนึ่งเพื่อใช้ชื่อสามัญโดยไม่ต้องเปลี่ยนทุกคนที่เรียกมัน
Paul Tomblin

38
แต่ข้อเสียนั้นใหญ่หลวงและถาวร มีการชนะระยะสั้นครั้งใหญ่และ IMO ที่ขาดทุนในระยะยาว
Jon Skeet

11
จอน - "ดีกว่าไม่มีอะไร" เป็นเรื่องส่วนตัว :)
MetroidFan2002

6
@ Rogerio: คุณอ้างว่ารายการ "ไม่ถูกต้อง" รายการแรกของฉันไม่ถูกต้อง รายการ "ไม่ถูกต้อง" รายการแรกของฉันบอกว่าข้อมูลสูญหายในเวลารวบรวม เพื่อให้ไม่ถูกต้องคุณต้องบอกว่าข้อมูลจะไม่สูญหายไปในเวลารวบรวม ... สำหรับนักพัฒนาคนอื่น ๆ ที่สับสนดูเหมือนคุณจะสับสนกับสิ่งที่ฉันพูด
Jon Skeet

26

ปัญหาที่ใหญ่ที่สุดคือ Java generics เป็นสิ่งเดียวในการคอมไพล์และคุณสามารถล้มล้างได้ในเวลาทำงาน C # ได้รับการยกย่องเนื่องจากมีการตรวจสอบเวลาทำงานมากกว่า มีการสนทนาที่ดีมากในโพสต์นี้และลิงก์ไปยังการสนทนาอื่น ๆ


นั่นไม่ใช่ปัญหาจริงๆไม่เคยมีไว้สำหรับรันไทม์ เหมือนกับที่คุณบอกว่าเรือมีปัญหาเพราะไม่สามารถปีนภูเขาได้ ในฐานะภาษา Java ทำสิ่งที่หลาย ๆ คนต้องการ: แสดงประเภทอย่างมีความหมาย สำหรับการละเมิดประเภทรันไทม์ผู้คนยังคงสามารถผ่านClassวัตถุไปรอบ ๆ ได้
Vincent Cantin

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

1
@ VincentCantin - มันเป็นปัญหาที่แน่นอนที่สุด ดังนั้นเราทุกคนบ่นเกี่ยวกับเรื่องนี้ ชื่อสามัญของ Java เป็นแบบครึ่งๆกลางๆ
Josh M.

17

ปัญหาหลักคือ Java ไม่มี generics ในรันไทม์ เป็นคุณสมบัติเวลาคอมไพล์

เมื่อคุณสร้างคลาสทั่วไปใน Java พวกเขาใช้เมธอดที่เรียกว่า "Type Erasure" เพื่อลบประเภททั่วไปทั้งหมดออกจากคลาสและแทนที่ด้วย Object generics รุ่นสูงไมล์คือคอมไพเลอร์เพียงแค่แทรก casts ไปยังประเภททั่วไปที่ระบุเมื่อใดก็ตามที่ปรากฏในเนื้อความของวิธีการ

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

ภาพรวมความแตกต่างที่ยอดเยี่ยมที่นี่: http://www.jprl.com/Blog/archive/development/2007/Aug-31.html


2
ฉันไม่แน่ใจว่าทำไมคุณถึงถูกโหวตไม่ลง จากสิ่งที่ฉันเข้าใจว่าคุณพูดถูกและลิงก์นั้นให้ข้อมูลมาก Up-ได้รับการโหวต
Jason Jackson

@ เจสันขอบคุณ มีการพิมพ์ผิดในเวอร์ชันต้นฉบับของฉันฉันเดาว่าฉันถูกลดคะแนนลง
JaredPar

3
ข้อผิดพลาดเนื่องจากคุณสามารถใช้การสะท้อนเพื่อดูประเภททั่วไปซึ่งเป็นลายเซ็นวิธีการทั่วไป คุณไม่สามารถใช้การสะท้อนเพื่อตรวจสอบข้อมูลทั่วไปที่เชื่อมโยงกับอินสแตนซ์พาราเมตริกได้ ตัวอย่างเช่นถ้าฉันมีคลาสที่มีเมธอด foo (List <String>) ฉันสามารถหา "String" แบบสะท้อนแสงได้
oxbow_lakes

มีบทความมากมายที่ระบุว่าการลบประเภททำให้ไม่สามารถค้นหาพารามิเตอร์ประเภทจริงได้ ให้พูดว่า: Object x = new X [Y] (); คุณสามารถแสดงวิธีการให้ x เพื่อค้นหาประเภท Y ได้อย่างไร
user48956

@oxbow_lakes - การต้องใช้การสะท้อนเพื่อค้นหาประเภททั่วไปนั้นเกือบจะแย่พอ ๆ กับที่ไม่สามารถทำได้ เช่นเป็นทางออกที่ไม่ดี
Josh M.

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

(1) นำไปสู่พฤติกรรมแปลก ๆ ตัวอย่างที่ดีที่สุดที่ฉันคิดได้คือ สมมติ:

public class MyClass<T> {
  T getStuff() { ... }
  List<String> getOtherStuff() { ... }
}

จากนั้นประกาศสองตัวแปร:

MyClass<T> m1 = ...
MyClass m2 = ...

โทรgetOtherStuff():

List<String> list1 = m1.getOtherStuff(); 
List<String> list2 = m2.getOtherStuff(); 

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

ฉันจะพูดถึงคำประกาศที่ฉันชอบจาก JDK:

public class Enum<T extends Enum<T>>

นอกเหนือจากการใช้สัญลักษณ์แทน (ซึ่งเป็นถุงผสม) ฉันคิดว่า. Net generics ดีกว่า


แต่คอมไพเลอร์จะบอกคุณโดยเฉพาะอย่างยิ่งกับตัวเลือกผ้าสำลีดิบ
Tom Hawtin - แทคไลน์

ขออภัยทำไมบรรทัดสุดท้ายจึงเกิดข้อผิดพลาดในการคอมไพล์ ฉันกำลังยุ่งกับมันใน Eclipse และไม่สามารถทำให้มันล้มเหลวที่นั่นได้ - ถ้าฉันเพิ่มสิ่งต่างๆให้เพียงพอสำหรับส่วนที่เหลือในการรวบรวม
oconnor0

public class Redundancy<R extends Redundancy<R>>;)
java.is.for.desktop

@ oconnor0 ไม่ใช่ความล้มเหลวในการรวบรวม แต่เป็นคำเตือนของคอมไพเลอร์โดยไม่มีเหตุผลชัดเจน:The expression of type List needs unchecked conversion to conform to List<String>
artbristol

Enum<T extends Enum<T>>อาจดูเหมือนแปลก / ซ้ำซ้อนในตอนแรก แต่ก็น่าสนใจจริงๆอย่างน้อยก็อยู่ในข้อ จำกัด ของ Java / มันเป็นชื่อสามัญ Enums มีคงvalues()วิธีการให้อาร์เรย์ขององค์ประกอบของพวกเขาพิมพ์เป็น enum ไม่และประเภทที่จะถูกกำหนดโดยพารามิเตอร์ทั่วไปซึ่งหมายความว่าคุณต้องการEnum Enum<T>แน่นอนว่าการพิมพ์เพียงทำให้รู้สึกในบริบทของชนิดนับและ enums ทั้งหมดเป็นคลาสย่อยดังนั้นคุณต้องการEnum Enum<T extends Enum>อย่างไรก็ตาม Java ไม่ชอบการผสมประเภทดิบกับ generics ดังนั้นEnum<T extends Enum<T>>เพื่อความสม่ำเสมอ
JAB

10

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

Map someMap;

ตอนนี้ฉันต้องประกาศเป็น

Map<String, List<String>> someMap;

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

Java มีชื่อเสียงที่ไม่ดีในการเป็นหนึ่งในภาษาที่ละเอียดที่สุดในการใช้งานทั่วไปและภาษาทั่วไปก็เพิ่มปัญหานั้น

แล้วคุณจะซื้ออะไรเพื่อความฟุ่มเฟื่อยที่มากเกินไป? คุณมีปัญหากี่ครั้งที่มีคนใส่จำนวนเต็มลงในคอลเลกชันที่ควรจะเก็บ Strings หรือที่ที่มีคนพยายามดึง String ออกจากคอลเลกชันของจำนวนเต็ม จากประสบการณ์ 10 ปีในการทำงานสร้างแอปพลิเคชัน Java เชิงพาณิชย์นี่ไม่เคยเป็นสาเหตุของข้อผิดพลาดขนาดใหญ่ ดังนั้นฉันไม่แน่ใจจริงๆว่าคุณได้รับอะไรจากการใช้คำฟุ่มเฟือยเพิ่มเติม มันทำให้ฉันกลายเป็นสัมภาระพิเศษของระบบราชการจริงๆ

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

List someList = someMap.get("some key");

ฉันต้องทำ

List someList = (List) someMap.get("some key");

เหตุผลก็คือ get () ส่งคืน Object ซึ่งเป็น supertype ของ List ดังนั้นจึงไม่สามารถทำการมอบหมายได้หากไม่มีตัวพิมพ์ ลองคิดดูอีกครั้งว่ากฎนั้นซื้อคุณได้มากแค่ไหน จากประสบการณ์ของฉันไม่มาก

ฉันคิดว่า Java น่าจะดีกว่าถ้า 1) ไม่ได้เพิ่ม generics แต่ 2) อนุญาตให้มีการส่งโดยนัยจาก supertype เป็น subtype แทน ปล่อยให้แคสต์ที่ไม่ถูกต้องถูกจับในรันไทม์ จากนั้นฉันก็มีความเรียบง่ายในการกำหนด

Map someMap;

และทำในภายหลัง

List someList = someMap.get("some key");

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


15
ขอโทษค่ะฉันไม่เห็นด้วยกับทุกสิ่งที่คุณพูด แต่ฉันจะไม่ลงคะแนนเพราะคุณเถียงได้ดี
Paul Tomblin

2
แน่นอนว่ามีตัวอย่างมากมายของระบบขนาดใหญ่ที่ประสบความสำเร็จในภาษาเช่น Python และ Ruby ที่ทำตามที่ฉันแนะนำในคำตอบของฉัน
Clint Miller

ฉันคิดว่าการคัดค้านทั้งหมดของฉันต่อความคิดประเภทนี้ไม่ใช่ว่าเป็นความคิดที่ไม่ดีต่อตัวเอง แต่เนื่องจากภาษาสมัยใหม่เช่น Python และ Ruby ทำให้ชีวิตง่ายขึ้นและง่ายขึ้นสำหรับนักพัฒนานักพัฒนาจึงพอใจทางสติปัญญาและในที่สุดก็ลดลง ความเข้าใจในรหัสของตนเอง
ด่านเต๋า

4
"แล้วคุณจะซื้ออะไรเพื่อความฟุ่มเฟื่อยแบบนั้นจริงๆล่ะ ... " มันบอกโปรแกรมเมอร์การบำรุงรักษาที่ไม่ดีว่าควรจะมีอะไรอยู่ในคอลเลกชันเหล่านั้น ฉันพบว่านี่เป็นปัญหาในการทำงานกับแอปพลิเคชัน Java เชิงพาณิชย์
richj

4
"กี่ครั้งแล้วที่คุณประสบปัญหาที่มีคนใส่ [x] ลงในคอลเล็กชันที่ควรจะเก็บ [y] s" - โอ้ที่รักฉันแพ้การนับ! แม้ว่าจะไม่มีข้อผิดพลาด แต่ก็เป็นตัวฆ่าที่สามารถอ่านได้ และการสแกนไฟล์จำนวนมากเพื่อค้นหาว่าวัตถุนั้นจะเป็นอย่างไร (หรือการดีบัก) ดึงฉันออกจากโซนได้จริงๆ คุณอาจชอบ Haskell - แม้จะพิมพ์หนัก แต่มีจุดด้อยน้อยกว่า (เพราะมีการอนุมานประเภท)
Martin Capodici

8

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


   public class MyClass {
     public T getStuff() {
       return new T();
     }
    }

--jeffk ++


6

Java generics ได้รับการตรวจสอบความถูกต้องในเวลาคอมไพล์จากนั้นข้อมูลประเภททั้งหมดจะถูกลบออก (กระบวนการนี้เรียกว่าtype erasureดังนั้น generic List<Integer>จะถูกลดขนาดเป็นraw typeไม่ใช่ generic Listซึ่งสามารถมีอ็อบเจ็กต์ของคลาสที่กำหนดเองได้

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

ArrayList<Integer> li = new ArrayList<Integer>();
ArrayList<Float> lf = new ArrayList<Float>();
if(li.getClass() == lf.getClass()) // evaluates to true
  System.out.println("Equal");

5

ฉันหวังว่านี่จะเป็น wiki เพื่อที่ฉันจะได้เพิ่มให้คนอื่น ... แต่ ...

ปัญหา:

  • พิมพ์ Erasure (ไม่มีความพร้อมใช้งานรันไทม์)
  • ไม่รองรับประเภทดั้งเดิม
  • ความไม่ลงรอยกันกับคำอธิบายประกอบ (ทั้งคู่ถูกเพิ่มใน 1.5 ฉันยังไม่แน่ใจว่าทำไมคำอธิบายประกอบจึงไม่อนุญาตให้ใช้คำอธิบายประกอบนอกเหนือจากการเร่งคุณสมบัติ)
  • เข้ากันไม่ได้กับอาร์เรย์ (บางครั้งฉันอยากจะทำอะไรสักอย่างเช่น Class <หรือไม่ขยาย MyObject >[] แต่ฉันไม่ได้รับอนุญาต)
  • ไวยากรณ์และพฤติกรรมไวร์ดไวด์การ์ด
  • ข้อเท็จจริงที่ว่าการสนับสนุนทั่วไปไม่สอดคล้องกันในคลาส Java พวกเขาเพิ่มเข้าไปในวิธีการรวบรวมส่วนใหญ่ แต่ในบางครั้งคุณจะพบกับอินสแตนซ์ที่ไม่มีอยู่

5

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

สิ่งนี้รวบรวม:

List<Integer> x = Collections.emptyList();

แต่นี่เป็นข้อผิดพลาดทางไวยากรณ์:

foo(Collections.emptyList());

โดย foo ถูกกำหนดให้เป็น:

void foo(List<Integer> x) { /* method body not important */ }

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


3
การอนุมานที่ไม่สอดคล้องกันโดย javac เป็นเรื่องไร้สาระ
mP.

3
ฉันคิดว่าสาเหตุที่รูปแบบหลังถูกปฏิเสธเป็นเพราะอาจมี "foo" มากกว่าหนึ่งเวอร์ชันเนื่องจากวิธีการทำงานมากเกินไป
Jason Creighton

2
คำวิจารณ์นี้ใช้ไม่ได้อีกต่อไปเนื่องจาก Java 8 นำเสนอการอนุมานประเภทเป้าหมายที่ปรับปรุงแล้ว
oldrinb

4

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

มีบางคนที่รู้สึกเช่นกันว่าการใช้ภาษาทั่วไปของ Java ทำให้ความซับซ้อนของภาษาเพิ่มขึ้นจนถึงระดับที่ยอมรับไม่ได้ (ดู " Generics ถือว่าเป็นอันตราย " ของ Ken Arnold ) คำถามที่พบบ่อยเกี่ยวกับ Genericsของ Angelika Langer ให้ความคิดที่ดีว่าสิ่งที่ซับซ้อนจะกลายเป็นอย่างไร


3

Java ไม่บังคับใช้ Generics ในขณะดำเนินการเฉพาะในเวลาคอมไพล์

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


1
คอมไพเลอร์จะบอกคุณว่าคุณเมาแล้วถ้าคุณจัดการเรื่องนั้นได้
Tom Hawtin - แทคไลน์

@ ทอม - ไม่จำเป็น มีวิธีการหลอกคอมไพเลอร์
Paul Tomblin

2
คุณไม่ฟังสิ่งที่ผู้รวบรวมบอกคุณหรือไม่ ?? (ดูความคิดเห็นแรกของฉัน)
Tom Hawtin - แทคไลน์

1
@Tom ถ้าคุณมี ArrayList <String> และคุณส่งต่อไปยังวิธีการแบบเก่า (เช่นรหัสเดิมหรือของบุคคลที่สาม) ที่ใช้ List แบบธรรมดาวิธีนั้นจะสามารถเพิ่มอะไรก็ได้ที่ชอบในรายการนั้น หากบังคับใช้ขณะรันไทม์คุณจะได้รับข้อยกเว้น
Paul Tomblin

1
โมฆะคง addToList (รายการรายการ) {list.add (1); } รายการ <String> list = ArrayList ใหม่ <String> (); addToList (รายการ); ที่คอมไพล์และยังทำงานในรันไทม์ ครั้งเดียวที่คุณพบปัญหาคือเมื่อคุณลบออกจากรายการโดยคาดว่าจะมีสตริงและได้รับ int
Laplie Anderson

3

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


2

ถ้าคุณฟังJava Posse # 279 - บทสัมภาษณ์ของ Joe Darcy และ Alex Buckleyพวกเขาพูดถึงประเด็นนี้ นอกจากนี้ยังเชื่อมโยงไปยังบล็อกโพสต์ของ Neal Gafter ชื่อReified Generics สำหรับ Javaที่ระบุว่า:

หลายคนไม่พอใจกับข้อ จำกัด ที่เกิดจากวิธีใช้ generics ใน Java โดยเฉพาะอย่างยิ่งพวกเขาไม่พอใจที่ไม่ได้ reified พารามิเตอร์ประเภททั่วไป: ไม่พร้อมใช้งานในรันไทม์ Generics ถูกนำไปใช้โดยใช้การลบซึ่งพารามิเตอร์ประเภททั่วไปจะถูกลบออกเมื่อรันไทม์

บล็อกโพสต์นั้นอ้างถึงรายการที่เก่ากว่าส่วนPuzzling Through Erasure: answerซึ่งเน้นประเด็นเกี่ยวกับความเข้ากันได้ของการย้ายข้อมูลในข้อกำหนด

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

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