ส่งคืนวัตถุ Void


113

อะไรคือวิธีที่ถูกต้องในการส่งคืนVoidประเภทเมื่อไม่ใช่แบบดั้งเดิม เช่น. ปัจจุบันฉันใช้ null ดังต่อไปนี้

interface B<E>{ E method(); }

class A implements B<Void>{

    public Void method(){
        // do something
        return null;
    }
}

1
ฉันกำลังเขียนล่ามสำหรับรูปแบบไฟล์โดยใช้รูปแบบล่าม แต่นิพจน์บางรายการไม่มีค่าส่งคืน
Robert

2
ไม่มีวิธีใดที่จะสร้างอินสแตนซ์ประเภท Void ได้ดังนั้นหากคุณต้องคืนค่าบางอย่างในประเภทนั้นจริงๆ null คือทางเลือกเดียวของคุณ อย่างไรก็ตามคุณอาจไม่ต้องการค่าที่ส่งคืนสำหรับสิ่งใด ๆ ดังนั้น null ควรจะใช้ได้
Jorn

ใช่ว่าเป็นตรรกะของฉันมากเกินไป - เพียงแค่สงสัยว่าถ้ามีวิธีที่ความหมายมากขึ้น
โรเบิร์ต

1
ฉันจะเขียนโค้ดให้เหมือนกับตัวอย่างของคุณ นั่นเป็นแนวทางที่ดี
David Roussel

คำตอบ:


134

คลาส Void เป็นคลาสตัวยึดที่ไม่คงที่เพื่อเก็บการอ้างอิงไปยังอ็อบเจ็กต์คลาสที่เป็นตัวแทนของคีย์เวิร์ด Java เป็นโมฆะ

ดังนั้นสิ่งต่อไปนี้จะเพียงพอ:

  • การกำหนดพารามิเตอร์ด้วยObjectและส่งคืนnew Object()หรือnull
  • การกำหนดพารามิเตอร์ด้วยVoidและการส่งคืนnull
  • การกำหนดพารามิเตอร์ด้วยNullObjectของคุณ

คุณไม่สามารถทำให้วิธีนี้voidและสิ่งอื่น ๆ ผลตอบแทนบางสิ่งบางอย่าง เนื่องจากสิ่งนั้นถูกละเว้นคุณสามารถส่งคืนทุกอย่างได้


2
แล้วอะไรคือวิธีที่ถูกต้องโดยทั่วไปเพื่อให้ได้ผลตอบแทนประเภทโมฆะ?
Robert

1
หากคุณต้องการคืนค่าโมฆะเป็นโมฆะคุณต้องโยนมันในบางกรณี: (Void) null
Patrick Favre

return (Void)null;
Alex R

โมฆะ (โมฆะ) โมฆะสามารถแตกต่างจากโมฆะได้หรือไม่?
Orangle

13

Java 8 ได้เปิดตัวคลาสใหม่Optional<T>ที่สามารถใช้ได้ในกรณีเช่นนี้ ในการใช้งานคุณต้องแก้ไขโค้ดของคุณเล็กน้อยดังนี้:

interface B<E>{ Optional<E> method(); }

class A implements B<Void>{

    public Optional<Void> method(){
        // do something
        return Optional.empty();
    }
}

สิ่งนี้ช่วยให้คุณมั่นใจได้ว่าคุณจะได้รับค่าตอบแทนที่ไม่เป็นค่าว่างจากวิธีการของคุณเสมอแม้ว่าจะไม่มีสิ่งใดที่จะส่งคืน ซึ่งมีประสิทธิภาพเป็นพิเศษเมื่อใช้ร่วมกับเครื่องมือที่ตรวจจับว่าเมื่อnullใดที่สามารถส่งคืนได้หรือไม่ได้เช่น Eclipse @NonNullและ@Nullableคำอธิบายประกอบ


5
ความเห็นของฉันคือมันไปในทิศทางที่ไม่ถูกต้อง จะเป็นการดีกว่าที่จะส่งคืนประเภทที่มีข้อ จำกัด มากกว่าซึ่งสื่อความหมายได้ชัดเจนกว่ามาก การมีบางสิ่งที่ส่งคืนค่า an Optional<Void>นั้นไม่จำเป็นด้วยเหตุผลเดียวกับที่คุณให้คุณจะได้รับOptional<Void>สิ่งนั้นว่างเปล่าเสมอดังนั้นวิธีการอื่น ๆ ทั้งหมดจึงไม่มีจุดหมาย นี่คือสิ่งที่ตรงกันข้ามกับเหตุผลที่ควรใช้ค่าที่เป็นทางเลือก คุณใช้มันเพราะมันอาจมีหรือไม่มีค่าก็ได้ นอกจากนี้คอมไพลเลอร์ไม่สามารถบังคับใช้ว่าmethod()ดำเนินการอย่างถูกต้อง return Optional.of(null)นี้จะล้มเหลวที่รันไทม์:
steinybot

3

หากคุณไม่ต้องการอะไรเป็นประเภทของคุณคุณสามารถใช้โมฆะได้ สามารถใช้สำหรับการใช้งานฟังก์ชันหรือการดำเนินการ จากนั้นคุณสามารถทำสิ่งนี้:

interface Action<T> {
    public T execute();
}

abstract class VoidAction implements Action<Void> {
    public Void execute() {
        executeInternal();
        return null;
    }

    abstract void executeInternal();
}

หรือคุณสามารถละเว้นคลาสนามธรรมและทำ return null ในทุกการกระทำที่ไม่ต้องการค่าตอบแทนด้วยตัวคุณเอง

จากนั้นคุณสามารถใช้การกระทำเหล่านั้นดังนี้:

กำหนดวิธีการ

private static <T> T executeAction(Action<T> action) {
    return action.execute();
}

เรียกได้ว่าชอบ

String result = executeAction(new Action<String>() {
    @Override
    public String execute() {
        //code here
        return "Return me!";
    }
});

หรือสำหรับการกระทำที่เป็นโมฆะ (โปรดทราบว่าคุณไม่ได้กำหนดผลลัพธ์ให้กับสิ่งใดเลย)

executeAction(new VoidAction() {
    @Override
    public void executeInternal() {
        //code here
    }
});

2
สิ่งนี้แตกต่างจากที่ฉันมีอยู่แล้วอย่างไร? มันยังคงส่งคืนค่าว่างเหมือนที่ฉันแนะนำ
Robert

ทำไมต้องคืนอะไรอีก ประเด็นที่ฉันพยายามทำคือคุณไม่ต้องการมูลค่าคืนดังนั้นจึงไม่สำคัญว่าคุณจะคืนอะไร ฉันพยายามชี้แจงด้วยการแก้ไขของฉัน
Jorn

1

เพื่อประโยชน์ของมันแน่นอนว่ามีความเป็นไปได้ที่จะสร้างVoidอินสแตนซ์โดยใช้การสะท้อน:

interface B<E>{ E method(); }

class A implements B<Void>{

    public Void method(){
        // do something

        try {
            Constructor<Void> voidConstructor = Void.class.getDeclaredConstructor();
            voidConstructor.setAccessible(true);
            return voidConstructor.newInstance();
        } catch (Exception ex) {
            // Rethrow, or return null, or whatever.
        }
    }
}

คุณอาจจะไม่ทำเช่นนั้นในการผลิต


0

ไม่มีประเภททั่วไปที่จะบอกคอมไพเลอร์ว่าเมธอดไม่คืนค่าอะไรเลย

ฉันเชื่อว่าหลักการคือการใช้ Object เมื่อสืบทอดเป็นพารามิเตอร์ประเภท

หรือ

เผยแพร่พารามิเตอร์ type ขึ้นจากนั้นให้ผู้ใช้ในคลาสของคุณสร้างอินสแตนซ์โดยใช้ Object และกำหนดอ็อบเจ็กต์ให้กับตัวแปรที่พิมพ์โดยใช้ type-wildcard ?:

interface B<E>{ E method(); }

class A<T> implements B<T>{

    public T method(){
        // do something
        return null;
    }
}

A<?> a = new A<Object>();

1
นี่คือแบบแผนสำหรับการตั้งค่าประเภทการส่งคืนเป็นโมฆะด้วยยาชื่อสามัญ - มันดูไม่เป็นโมฆะสำหรับฉันใช่ไหม
Robert

ฉันเชื่อว่านี่คือหนทางที่จะไป ผู้ใช้ระดับใด ๆจะไม่สามารถที่จะทำให้การใช้งานของค่าที่ส่งกลับใดA<?>method()
Christopher Oezbek
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.