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

네, 그것도 제 논리였습니다. 더 의미론적인 방법이 있는지 궁금했습니다
Robert

1
나는 당신의 예처럼 그것을 코딩 할 것입니다. 그것은 훌륭한 접근 방식입니다.
David Roussel

답변:


134

Void 클래스는 Java 키워드 void를 나타내는 Class 객체에 대한 참조를 보유하는 인스턴스화 할 수없는 플레이스 홀더 클래스입니다.

따라서 다음 중 하나이면 충분합니다.

  • 매개 변수화 Object및 반환 new Object()또는null
  • 매개 변수화 Void및 반환null
  • NullObject당신의 매개 변수화

이 메서드를 만들 수 없으며 void다른 것은 무언가를 반환 합니다 . 그 무언가가 무시되었으므로 무엇이든 반환 할 수 있습니다.


2
그렇다면 void의 반환 유형을 달성하는 일반적으로 올바른 방법은 무엇입니까?
로버트

1
(무효) 널 (null) : 당신이 무효로 널 (null)을 반환 할 경우에 당신은 어떤 경우에 캐스팅 할 필요
패트릭 파브르

return (Void)null;
Alex R

(Void) null은 어떤 식 으로든 null과 구별 될 수 있습니까?
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이 아닌 반환 값을 얻을 수 있습니다. 이는 nullEclipse @NonNull@Nullable주석 과 같이 반환 할 수 있거나 반환 할 수없는 시기를 감지하는 도구와 함께 사용할 때 특히 강력 합니다.


5
내 의견은 이것이 잘못된 방향으로 가고 있다는 것입니다. 의미를 훨씬 더 명확하게 전달하는 훨씬 더 제한된 유형을 반환하는 것이 좋습니다. 를 반환하는 Optional<Void>것은 당신이주는 것과 같은 이유로 불필요합니다. 당신은 항상Optional<Void> 비어 있는 것을 얻습니다. 그래서 다른 모든 방법은 무의미합니다. 이것은 선택적 값을 사용해야하는 이유와 반대입니다. 값이있을 수도 있고 없을 수도 있기 때문에 사용합니다. 또한 컴파일러는 method()올바르게 구현 하도록 강제 할 수 없습니다 . 이것은 런타임에 실패합니다 : return Optional.of(null).
steinybot

3

유형으로 아무것도 필요하지 않으면 void를 사용할 수 있습니다. 이것은 기능 또는 작업을 구현하는 데 사용할 수 있습니다. 그런 다음 다음과 같이 할 수 있습니다.

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

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

    abstract void executeInternal();
}

또는 추상 클래스를 생략하고 직접 반환 값이 필요하지 않은 모든 작업에서 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
내가 이미 가지고있는 것과 어떻게 다른가요? 내가 제안한 것처럼 여전히 null을 반환합니다.
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
이것은 제네릭을 사용하여 반환 유형을 void로 설정하는 규칙입니까?
로버트

나는 이것이 갈 길이라고 믿는다. 클래스의 모든 사용자 A<?>는 반환 된 값을 사용할 수 없습니다 method().
Christopher Oezbek 2010 년
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.