การอ้างอิงเมธอดและ Generics ใน Java-8


11

ฉันกำลังประสบปัญหากับการอ้างอิงวิธีการรวมกับประเภททั่วไป

เรามีรหัสที่เราต้องเรียกใช้วิธีการโอเวอร์โหลด แต่มันล้มเหลวด้วยข้อผิดพลาด:

ไม่สามารถแก้ไขค่า m1 ()

ฉันทำให้ปัญหาของฉันง่ายขึ้นเพื่อทำให้ชัดเจนว่าปัญหาอยู่ที่ใด

รหัสต่อไปนี้ล้มเหลว:

public class Test {
    void test() {
        // Getting error here
        setValue(C1::m1, Integer.ONE);
    }

    <E extends I1, T> void setValue(BiConsumer<E, T> cons, T value) {
    }
}

interface I1 {
}

class C1 implements I1 {
    void m1(Integer value) {
    }

    void m1(int value) {
    }
}

ใครช่วยได้โปรดทำไมสิ่งนี้ถึงเป็นแบบนี้?

โปรดทราบว่าสิ่งนี้ไม่เกี่ยวข้องกับคำถามอ้างอิง Java 8 Method กับประเภททั่วไป


ไม่ถ้าฉันลบหนึ่งในวิธีที่มันใช้ได้ดีแล้ว
Joker

ขอบคุณสำหรับการเปิดคำถามนี้อีกครั้ง ... :)
โจ๊ก

คำตอบ:


7

ดูเหมือนว่ากฎการอนุมานประเภทไม่ได้ "ฉลาด" เพียงพอที่จะแก้ไขข้อขัดแย้งระหว่างการเลือกm1ตัวแปรที่เหมาะสมและสร้างพารามิเตอร์ประเภทอนุมานที่ถูกต้องไปยังการsetValueโทร ( BและBigDecimalตามลำดับ)

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

คุณสามารถแก้ไขปัญหานี้ได้โดยเพิ่มพยานประเภท (ระบุพารามิเตอร์ประเภทที่คุณต้องการโทรsetValueด้วย) ณ จุดที่คอมไพเลอร์จะเลือกm1วิธีที่ถูกต้อง:

this.<B,BigDecimal>setValue(B::m1, BigDecimal.ONE);

ดูเหมือนว่าฉันไม่ได้อยู่ในแนวเดียวกันกับdocs.oracle.com/javase/specs/jls/se8/html/ …
Joker
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.