source

검색 메서드가 반환 값을 생성할 수 없는 경우 'null'을 반환해야 합니까? 아니면 예외를 발생시켜야 합니까?

factcode 2022. 8. 25. 23:48
반응형

검색 메서드가 반환 값을 생성할 수 없는 경우 'null'을 반환해야 합니까? 아니면 예외를 발생시켜야 합니까?

자바 언어를 사용하고 있습니다.물건을 찾으면 돌려주는 방법이 있어요.

찾을 수 없는 경우 다음을 수행해야 합니다.

  1. 반환 무효
  2. 예외를 두다
  3. 다른.

어떤 것이 가장 좋은 실천요법과 사자성어인가요?

항상 값을 찾을 것으로 예상되는 경우 값이 없으면 예외를 발생시킵니다.예외는 문제가 있었다는 것을 의미합니다.

값이 누락되거나 존재할 수 있으며 둘 다 응용 프로그램 로직에서 유효한 경우 null을 반환합니다.

더 중요:코드의 다른 부분은 어떻게 하나요?일관성이 중요합니다.

정말로 오류가 발생한 경우에만 예외를 발생시킵니다.개체가 존재하지 않는 것으로 예상되는 경우 null을 반환합니다.

그렇지 않으면 그것은 선호의 문제이다.

일반적으로 메서드가 항상 개체를 반환해야 하는 경우에는 예외로 합니다.가끔 null을 예상하고 특정 방법으로 처리하려면 null로 합니다.

무엇을 하든, 세 번째 옵션은 사용하지 말 것을 강력히 권장합니다."WTF"라는 문자열을 반환합니다.

null이 오류를 나타내지 않으면 null을 반환합니다.

null이 항상 오류일 경우 예외를 발생시킵니다.

null이 예외일 수 있는 경우 2개의 루틴을 코드화합니다.한 루틴은 예외를 발생시키고 다른 루틴은 출력 파라미터에서 개체를 반환하는 부울 테스트 루틴이며, 개체를 찾을 수 없는 경우 루틴은 false를 반환합니다.

Try 루틴을 오용하는 것은 어렵습니다.Null을 확인하는 것을 잊기 쉽습니다.

따라서 null이 오류일 때는 그냥 씁니다.

object o = FindObject();

null이 오류가 아닌 경우 다음과 같이 코드화할 수 있습니다.

if (TryFindObject(out object o)
  // Do something with o
else
  // o was not found

앞서 언급한 옵션을 요약하여 몇 가지 새로운 옵션을 추가하고자 합니다.

  1. 반환 무효
  2. 예외를 두다
  3. null 객체 패턴을 사용하다
  4. 발신자가 예외를 발생시킬지 여부를 선택할 수 있도록 메서드에 부울 파라미터를 지정합니다.
  5. 발신자가 값을 설정할 수 있도록 추가 파라미터를 지정합니다.이것에 의해, 값이 검출되지 않았을 경우에 반환되는 값이 설정됩니다.

또는 다음 옵션을 조합할 수 있습니다.

getter의 오버로드된 버전을 여러 개 제공하여 발신자가 어떤 방향으로 갈지 결정할 수 있도록 합니다.대부분의 경우 첫 번째 알고리즘에만 검색 알고리즘이 구현되어 있고 다른 하나는 첫 번째 알고리즘에 둘러싸여 있습니다.

Object findObjectOrNull(String key);
Object findObjectOrThrow(String key) throws SomeException;
Object findObjectOrCreate(String key, SomeClass dataNeededToCreateNewObject);
Object findObjectOrDefault(String key, Object defaultReturnValue);

하나의 구현만 제공하기로 선택한 경우에도 이와 같은 명명 규칙을 사용하여 계약을 명확히 할 수 있습니다.또한 다른 구현도 추가할 수 있습니다.

너무 많이 사용하는 것은 아니지만, 특히 수백 개의 다른 응용 프로그램에서 사용하는 도우미 클래스를 작성할 때 도움이 될 수 있습니다.오류 처리 규칙은 다양합니다.

null 객체 패턴을 사용하거나 예외를 발생시킵니다.

예외를 두는 장점:

  1. 발신자 코드의 제어 플로우가 깨끗해집니다.null을 체크하면 기본적으로 try/catch에 의해 처리되는 조건부 분기가 주입됩니다.null을 체크해도 무엇을 체크하고 있는지 알 수 없습니다.예상하고 있는 에러를 찾고 있기 때문에 null을 체크하고 있는 것입니까?아니면 다운체인으로 넘기지 않기 위해 null을 체크하고 있는 것입니까?
  2. "null"의 의미를 모호하게 하지 않습니다.null은 오류를 나타내는 것입니까, 아니면 값에 실제로 저장되어 있는 null입니까?그 결단의 근거가 되는 것이 딱 하나일 때는 말하기 어렵다.
  3. 응용 프로그램에서 메서드 동작 간의 일관성이 향상되었습니다.예외는 일반적으로 메서드 서명에 표시되므로 응용 프로그램의 메서드가 설명하는 에지 케이스와 응용 프로그램이 예측 가능한 방식으로 반응할 수 있는 정보를 더 잘 이해할 수 있습니다.

예에 대한 자세한 내용은http://http://metatations.com/2011/11/17/returning-null-vs-throwing-an-exception/ 를 참조해 주세요.

사용 중인 API와 일치해야 합니다.

"객체가 발견되지 않는 것은 예외적인 경우입니까?"라고 자문해 보십시오.프로그램의 통상적인 코스에서 발생할 것으로 예상되는 경우는, 예외적인 동작은 아니기 때문에, 예외를 발생시키지 않는 것이 좋습니다.

요약 버전: 예외는 프로그램에서 일반적인 제어 흐름을 처리하는 것이 아니라 예외 동작을 처리하는 데 사용합니다.

- 앨런. - 앨런.

언어와 코드가 촉진되는지 여부에 따라 달라집니다.LBIL(점프를 하기 전에 살펴보기) 또는 EAFP(허락보다 용서를 구하는 것이 쉽다)

LBIL에서 값을 확인해야 한다고 합니다(따라서 null을 반환합니다).
EAFP는 조작을 시도하여 실패 여부를 확인하도록 지시합니다(예외 발생).

위와 같은 의견에 동의하지만..예외/오류 조건에는 예외를 사용해야 하며, 체크 사용 시에는 늘을 반환하는 것이 가장 좋습니다.


Python EAFP © LBIL :
http://mail.python.org/pipermail/python-list/2003-May/205182.html (Web 아카이브)

예외는 계약에 의한 설계와 관련되어 있습니다.

오브젝트의 인터페이스는 실제로는2개의 오브젝트간의 계약입니다.발신자는 계약을 충족해야 합니다.그렇지 않으면 수신자가 예외로 실패하는 경우가 있습니다.두 가지 가능한 계약이 있습니다.

1) 메서드가 유효한 모든 입력입니다.이 경우 개체를 찾을 수 없을 때 null을 반환해야 합니다.

2) 일부 입력만 유효합니다. 즉, 발견된 객체가 됩니다.이 경우 발신자가 입력이 올바른지 여부를 판단할 수 있는 두 번째 방법을 제공해야 합니다.예를들면

is_present(key)
find(key) throws Exception

두 번째 계약의 두 가지 방법을 모두 제공하는 경우에만 예외를 발생시킬 수 있습니다. 아무것도 발견되지 않았습니다.

저는 그냥 null을 반환하고 발신자가 적절하게 처리해 줄 것을 믿고 싶습니다.(더 좋은 단어가 없는 경우) 예외는 이 메서드가 개체를 반환한다는 것입니다.이 경우 실패는 예외적으로 던져야 하고 던져야 한다.

개체를 찾을 수 없다는 것이 무엇을 의미하느냐에 따라 다릅니다.

정상적인 상황이라면 무효로 돌려주세요.이것은, 가끔 일어날 수 있는 일이기 때문에, 발신자가 확인해 주세요.

에러인 경우는, 예외를 슬로우 합니다.발신자는, 누락된 오브젝트의 에러 상태를 어떻게 처리할지를 결정해야 합니다.

대부분의 사람들은 예외적인 일이 일어났을 때만 예외를 사용하는 것이 좋다고 생각하지만, 궁극적으로는 어느 쪽이든 효과가 있습니다.

여기 몇 가지 제안이 더 있습니다.

컬렉션을 반환하는 경우 null을 반환하지 않도록 하고 빈 컬렉션을 반환하여 먼저 null 검사 없이 열거를 쉽게 처리할 수 있도록 합니다.

여러명.NET API는 오브젝트를 찾을 수 없는 경우 발신자에게 정말 예외적인 상황인지 아닌지를 선택할 수 있는 throughedOnError 파라미터의 패턴을 사용합니다.Type.GetType이 그 예입니다.BCL의 또 다른 일반적인 패턴은 부울이 반환되고 값이 출력 파라미터를 통해 전달되는 TryGet 패턴입니다.

기본 또는 동작이 없는 버전인 경우에 따라서는 Null Object 패턴을 고려할 수도 있습니다.중요한 것은 코드 베이스 전체에 걸쳐 늘체크를 회피하는 것입니다.상세한 것에 대하여는, http://geekswithblogs.net/dsellers/archive/2006/09/08/90656.aspx 를 참조해 주세요.

일부 기능에서는 다음 파라미터를 추가합니다.

..., bool verify = true)

true는 throw를 의미하고 false는 일부 오류 반환 값을 반환합니다.이렇게 하면 이 기능을 사용하는 사용자는 두 가지 옵션을 모두 사용할 수 있습니다.오류 처리를 잊어버린 사용자를 위해 기본값은 true여야 합니다.

예외를 발생시키는 대신 null을 반환하고 API 설명서에 null 반환 값의 가능성을 명확하게 기록합니다.호출 코드가 API를 준수하지 않고 늘 대소문자를 체크하지 않으면 어떤 종류의 "늘 포인터 예외"가 발생할 수 있습니다.

C++에서는, 오브젝트를 찾는 방법을 설정하는 3개의 다른 맛을 생각할 수 있습니다.

옵션 A

Object *findObject(Key &key);

개체를 찾을 수 없으면 null을 반환합니다.단순하고 멋지군.난 이걸로 할래.다음 대체 접근법은 아웃패럴을 싫어하지 않는 사람들을 위한 것입니다.

옵션 B

void findObject(Key &key, Object &found);

개체를 수신할 변수에 대한 참조를 전달합니다.개체를 찾을 수 없을 때 메서드가 예외를 발생시켰습니다.이 규칙은 오브젝트가 실제로 발견되지 않을 것으로 예상되지 않는 경우에 더 적합할 수 있습니다.따라서 예기치 않은 경우라는 것을 나타내기 위해 예외를 두게 됩니다.

옵션 C

bool findObject(Key &key, Object &found);

개체를 찾을 수 없는 경우 메서드는 false를 반환합니다.옵션 A에 비해 이 방법의 장점은 에러 케이스를 1개의 명확한 순서로 확인할 수 있다는 것입니다.

if (!findObject(myKey, myObj)) { ...

어디 널 나는 분명히 가장 시도하십시오 메서드에 예외적인 행동으로 간주되지 않는 사건에만 불합리할 필요가 없거나"표정 당신이 뛰어넘기 전에"여기에 말했다"그 책을 읽"은 명백하다.

원래:

bool TryFindObject(RequestParam request, out ResponseParam response)

그리고 이는 사용자의 코드 역시 맑다는 것을 뜻한다.

...
if(TryFindObject(request, out response)
{
  handleSuccess(response)
}
else
{
  handleFailure()
}
...

에 대한 클라이언트 코드를 로드하고 이것이 일상적인 행위로 되어 있다고 깨달은 사이의 차이점을 아는 것, 중요한 일이면 그 다음에는 null을 반환하는 것이 가장 좋습니다.클라이언트 코드 뒤 거취를 결정할 수 있다.

보통 null을 반납해야 한다.이 코드에서는 메서드를 호출하는지 여부 또는 다른 무언가 시도할 예외를 throw 할지 결정해야 한다.

아니면 한 옵션 반납

클라이언트 부스 경우를 처리할 수 밖에 없는 선택권은 기본적으로 컨테이너 클래스.스칼라, API을 보는지 이 개념을 갖추고 있다.

그럼 또는에서 클라이언트 specifiecesallternative을 발견 개체가 반환 이 개쳄에 TgetOrElse(TvalueIfNull) 같은 방법을 가지고 있다.

null 돌아오는 것을 선호하시오,

호출자에게 확인하지 않고 이를 사용하여, 예외에 거기 어쨌든 일어난다.

가 실제로않는 .try/catch

불행히도 자바 개발 키트 일관성 없는 경우 리소스 컬렉션에 액세스 하는 기존의 열쇠고, 지도에서 값을 요청합니다 만약 그것이 존재하지 않는 경우 null을 예외 발견되지 않습니다.따라서 다음과 같이 당첨자 답변을 변경합니다. 발견된 값이 null일 수 있으면 예외를 발생시키고, 그렇지 않으면 null을 반환합니다.따라서 한 가지 예외를 제외하고 규칙을 따르십시오. 값을 찾을 수 없는 이유를 알고 싶다면 항상 예외를 발생시키거나, 그렇지 않으면..

오브젝트에 대한 참조를 반환하는 경우에는 NULL을 반환하는 것이 좋습니다.

단, 블러디한 모든 것을 반환하는 경우(C++에서 반환하는 경우: 'return &blah;'(또는 'blah'는 포인터)가 아니라 'return blah;'로 반환하는 경우)는 NULL을 반환할 수 없습니다.이는 'object' 유형이 아니기 때문입니다.이 경우 예외를 발생시키거나 성공 플래그가 세팅되지 않은 빈 객체를 반환하는 것이 문제에 접근하는 방법입니다.

예외 처리에서 오버헤드를 언급하는 사람은 없습니다.예외를 로드하고 처리하려면 추가 리소스가 필요합니다.따라서 이것이 진정한 앱 킬링이나 프로세스 정지 이벤트(앞으로 나아가는 것이 득보다 실이 된다)가 아닌 한, 통화 환경이 적절하다고 생각하는 값을 되돌리는 것을 선택합니다.

나는 여기서 합의된 것처럼 보이는 것에 동의한다('not found'가 정상적인 결과일 경우 null을 반환하고, 상황의 의미론에서 개체를 항상 찾을 것을 요구하는 경우 예외를 발생시킨다).

하지만 당신의 상황에 따라서는 세 번째 가능성이 있습니다.메서드는 "not found" 상태의 어떤 종류의 기본 개체를 반환할 수 있으며, 이를 통해 발신 코드는 늘 체크나 예외 캐치 없이 항상 유효한 개체를 수신할 수 있습니다.

null을 반환한다. 예외는 정확히 다음과 같습니다. 즉, 코드가 예상하지 못한 작업을 수행합니다.

예외는 예외여야 합니다.null을 반환하는 것이 유효한 경우 null을 반환합니다.

메서드가 컬렉션을 반환하는 경우 빈 컬렉션을 반환하십시오(위에서 설명한 것처럼).하지만 수집은 하지 마세요.EMTIFY_LIST 등! (Java의 경우)

메서드가 단일 개체를 검색하는 경우 몇 가지 옵션이 있습니다.

  1. 메서드가 항상 결과를 찾아야 하며 개체를 찾지 않는 것이 실제 예외인 경우 예외를 느려야 합니다(Java: please on exception).
  2. (Java 한정) 메서드가 체크된 예외를 발생시키는 것을 허용할 수 있는 경우 프로젝트 고유의 ObjectNotFoundException 등을 발생시킵니다.이 경우 예외 처리를 잊은 경우 컴파일러에 의해 메시지가 나타납니다.(Java에서 찾을 수 없는 것을 처리하는 것이 좋습니다.)
  3. 오브젝트가 발견되지 않고 메서드 이름이 findBookFor와 같은 경우 정말 괜찮다고 하면AuthorOrReturnNull(..)을 반환하면 null을 반환할 수 있습니다.이 경우 null 검사 없이 결과의 참조를 방지하는 정적 검사 또는 컴파일러 검사를 사용할 것을 강력히 권장합니다.Java의 경우, 예를 들어 다음과 같습니다.FindBugs(http://findbugs.sourceforge.net/manual/annotations.html)의 Default Annotation 또는 IntelliJ-Checking 참조).

null을 반환하기로 결정했을 경우 주의하십시오.프로젝트에서 유일한 프로그래머가 아닌 경우 Null Pointer를 사용할 수 있습니다.실행 시 예외(Java 또는 기타 언어)따라서 컴파일 시 체크되지 않은 null은 반환하지 마십시오.

예외를 발생시키는 라이브러리 또는 다른 클래스를 사용하는 경우 해당 클래스를 다시 던져야 합니다.여기 예가 있습니다.Example2.java는 라이브러리와 같고 Example.java는 해당 개체를 사용합니다.Main.java가 이 예외를 처리하는 예입니다.발신측 사용자에게 의미 있는 메시지와 (필요한 경우) 스택트레이스를 보여줘야 합니다.

Main.java

public class Main {
public static void main(String[] args) {
    Example example = new Example();

    try {
        Example2 obj = example.doExample();

        if(obj == null){
            System.out.println("Hey object is null!");
        }
    } catch (Exception e) {
        System.out.println("Congratulations, you caught the exception!");
        System.out.println("Here is stack trace:");
        e.printStackTrace();
    }
}
}

Example.java

/**
 * Example.java
 * @author Seval
 * @date 10/22/2014
 */
public class Example {
    /**
     * Returns Example2 object
     * If there is no Example2 object, throws exception
     * 
     * @return obj Example2
     * @throws Exception
     */
    public Example2 doExample() throws Exception {
        try {
            // Get the object
            Example2 obj = new Example2();

            return obj;

        } catch (Exception e) {
            // Log the exception and rethrow
            // Log.logException(e);
            throw e;
        }

    }
}

예2.java

 /**
 * Example2.java
 * @author Seval
 *
 */
public class Example2 {
    /**
     * Constructor of Example2
     * @throws Exception
     */
    public Example2() throws Exception{
        throw new Exception("Please set the \"obj\"");
    }

}

그것은 실제로 당신이 그 물체를 찾을지 아닌지에 달려있다.예를 들어 에러나 예외적인 것을 나타낼 때 예외를 사용해야 한다는 사고방식을 따르는 경우 다음과 같이 됩니다.

  • 개체를 찾았습니다. 개체를 반환합니다.
  • 개체를 찾을 수 없습니다. 예외 발생

그렇지 않으면 null을 반환합니다.

언급URL : https://stackoverflow.com/questions/175532/should-a-retrieval-method-return-null-or-throw-an-exception-when-it-cant-prod

반응형