Void
프리미티브가 아닌 유형 을 반환하는 올바른 방법은 무엇입니까 ? 예 : 현재 아래와 같이 null을 사용하고 있습니다.
interface B<E>{ E method(); }
class A implements B<Void>{
public Void method(){
// do something
return null;
}
}
답변
Void 클래스는 Java 키워드 void를 나타내는 Class 객체에 대한 참조를 보유하는 인스턴스화 할 수없는 플레이스 홀더 클래스입니다.
따라서 다음 중 하나이면 충분합니다.
- 매개 변수화
Object
및 반환new Object()
또는null
- 매개 변수화
Void
및 반환null
NullObject
당신의 매개 변수화
이 메서드를 만들 수 없으며 void
다른 것은 무언가를 반환 합니다 . 그 무언가가 무시되었으므로 무엇이든 반환 할 수 있습니다.
답변
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이 아닌 반환 값을 얻을 수 있습니다. 이는 null
Eclipse @NonNull
및 @Nullable
주석 과 같이 반환 할 수 있거나 반환 할 수없는 시기를 감지하는 도구와 함께 사용할 때 특히 강력 합니다.
답변
유형으로 아무것도 필요하지 않으면 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
}
});
답변
이를 위해 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.
}
}
}
프로덕션에서는 그렇게하지 않을 것입니다.
답변
메서드가 아무것도 반환하지 않는다고 컴파일러에게 알려주는 제네릭 유형은 없습니다.
나는 규칙이 유형 매개 변수로 상속 할 때 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>();