เรียกวิธีการทั่วไปแบบคงที่


106

ฉันเจอสถานการณ์ที่น่าสงสัยเกี่ยวกับวิธีการทั่วไปแบบคงที่ นี่คือรหัส:

class Foo<E>
{
    public static <E> Foo<E> createFoo()
    {
        // ...
    }
}

class Bar<E>
{
    private Foo<E> member;

    public Bar()
    {
        member = Foo.createFoo();
    }
}

ทำไมฉันไม่ต้องระบุอาร์กิวเมนต์ประเภทใด ๆ ในนิพจน์Foo.createFoo()? นี่เป็นการอนุมานประเภทหนึ่งหรือไม่? ถ้าฉันต้องการให้ชัดเจนเกี่ยวกับเรื่องนี้ฉันจะระบุประเภทอาร์กิวเมนต์ได้อย่างไร


7
ฉันอยากจะแนะนำให้คุณเปลี่ยนพารามิเตอร์ type E ของเมธอด createFoo เนื่องจากพารามิเตอร์ type E ของคลาส Foo แตกต่างจากพารามิเตอร์ type E ของ method createFoo ()
Gursel Koca

@GurselKoca เขาสามารถทำสมาชิก = Foo ได้อย่างชัดเจน <E> createFoo (); กำหนดให้เป็นเวลาเดียวกับเวลาคอมไพล์
George Xavier

คำตอบ:


183

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

Foo.<String>createFoo();

3
หรือในกรณีของฉัน: Foo.<E>createFoo();ขอบคุณ :)
fredoverflow

7
ทำไมถึงได้ผลโดยไม่ได้รับมอบหมาย? นั่นคือคำสั่ง Foo.createFoo();รวบรวมได้ดี ... ? นี่เป็นเพราะการลบประเภทหรือไม่?
fredoverflow

9
@FredOverflow โดยไม่มีการมอบหมายEคือ "อนุมาน" เป็นObject
แก้ไขไม่ได้

2
ตำแหน่งลิงค์ใหม่น่าจะเป็น: docs.oracle.com/javase/specs/jls/se8/html/…
Joanis

3
วิธีอื่นในการระบุประเภทEคือการกำหนดcreateFoo()ใช้อาร์กิวเมนต์ประเภทClass<E>(ดังนั้นจึงเป็นเช่นนั้นcreateFoo(Class<E> type)) และเรียกด้วยcreateFoo(String.class)
Gavin S.Yancey
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.