IT이야기

"객체를 찾을 수 없음"을 의미하는 표준 Java 예외 클래스

cyworld 2021. 10. 10. 13:59
반응형

"객체를 찾을 수 없음"을 의미하는 표준 Java 예외 클래스가 있습니까?


다음 일반 형식의 함수를 고려하십시오.

Foo findFoo(Collection<Foo> foos, otherarguments)
throws ObjectNotFoundException {
    for(Foo foo : foos){
        if(/* foo meets some condition*/){
            return foo;
        }
    }
    throw new ObjectNotFoundException();
}

예를 들어 구체적인 경우는 다음과 같습니다.

User findUserByName(Collection<User> users, String name)
throws ObjectNotFoundException {
    for(User user : users){
        if(user.getName().equals(name)){
            return user;
        }
    }
    throw new ObjectNotFoundException();
}

이러한 함수는 개체를 찾을 수 없는 경우 예외를 throw합니다. 이 목적을 위해 사용자 정의 예외 클래스를 만들 수 ObjectNotFoundException있지만( 예제에서 ) 기존 클래스를 사용하는 것을 선호합니다. 그러나 표준 Java 라이브러리에서 이러한 의미의 예외 클래스를 찾을 수 없습니다. 여기에 사용할 수 있는 표준 예외가 있는지 알고 있습니까?


여기에 사용할 수 있는 표준 예외가 있는지 알고 있습니까?

사용할 있는 몇 가지 예외가 있지만 (예: NoSuchElementException또는 IllegalArgumentException) 그 대답은 실제로 전달하려는 의미에 따라 다릅니다.

  • NoSuchElementException 시퀀스 또는 열거를 단계별로 실행할 때 사용되는 경향이 있습니다. 여기에서 여기에 있는 것은 조회입니다.

  • IllegalArgumentException 인수에 오류가 있음을 암시하는 경향이 있지만 이 경우 호출자의 가정이 올바르지 않거나 응용 프로그램 논리에 특정한 것일 수 있습니다.

  • 사용자 정의 예외를 사용하면 (javadocs에서) 예외가 의미하는 바를 정확히 말할 수 있습니다. 적절한 경우 ... 확인 하도록 선언할 수도 있습니다 .

(그러나 사용하고 싶지는 않습니다 UnknownUserException. 그것은 끔찍하게 잘못된 것입니다. javadoc을 읽어보세요!)


null특히 조회 실패가 애플리케이션에서 상당히 일반적인(예외적이지 않은) 이벤트일 가능성이 있는 경우 반환을 고려할 가치가 있습니다 . 그러나 반환의 단점은 null호출자가 null예기치 않은 NullPointerExceptions 를 확인 하거나 위험을 감수 해야 한다는 것 입니다. 사실, 나는 null예외를 남용하는 것보다 을 과도하게 사용하는 것이 더 나쁘다고 주장하고 싶습니다 . 전자는 신뢰할 수 없는 응용 프로그램을 초래할 수 있는 반면 후자는 성능에 "단" 나쁩니다.

Java 8 Optional이상의 경우 반환하는 것이 null.


이런 점에서 독단적인 관점을 넘어 실제 상황이 요구하는 바를 바탕으로 판단하는 것이 중요합니다.


예외적인 행동을 표시하기 위해 예외가 생성됩니다. 제 생각에는 개체를 찾을 수 없는 상황이 예외적인 것은 아닙니다. 사용자를 찾을 수 없는 경우 null을 반환하도록 메서드를 다시 작성합니다.

User findUserByName(Collection<User> users, String name) {
   for(User user : users){
       if(user.getName().equals(name)){
           return user;
      }
    }
  return null; 
}

이것은 많은 Java 컬렉션의 표준 동작입니다. 예를 들어 http://docs.oracle.com/javase/7/docs/api/java/util/Map.html#get(java.lang.Object) 은 지정된 키가 있는 항목이 파일에 없을 때 null을 반환합니다. 지도.

프로그램 논리에서 예외에 의존하는 것을 피해야 합니다.


IllegalArgumentException 때때로 여기에서 사용되지만 자신의 예외를 사용하는 것은 완벽합니다.

제쳐두고 Map을 String name키와 User으로 사용하는 것이 좋습니다 . 그러면 컬렉션을 반복할 필요가 없으며 컬렉션에 같은 이름을 가진 두 명의 사용자가 있는 것을 방지할 수 있습니다. 지도를 사용하고 싶지 않다면 적어도 다음과 NullPointerException같이 방어하십시오 .

User findUserByName(Collection<User> users, String name) throws ObjectNotFoundException
{
  if (name == null)
  {
    throw new IllegalArgumentException("name parameter must not be null");
  }
  if (users == null)
  {
    throw new IllegalArgumentException("Collection of users must not be null");
  }
  for(User user : users)
  {
    if(name.equals(user.getName()))
    {
      return user;
    }
  }
  throw new ObjectNotFoundException("Unable to locate user with name: " + name);
}

메서드의 문서화된 인터페이스 계약에 따라 다릅니다.

메서드 문서에 name인수 기존 사용자의 이름과 일치 해야 한다고 명시되어 IllegalArgumentException있으면 이름을 찾을 수 없으면 throw 하는 것이 적절 합니다. 사용자.

If your method doesn't say that the name must correspond to an existing user, then passing an unknown name is not an error and you shouldn't throw an exception at all. Returning null would be appropriate in this situation.

Note that your findUserByName method is basically reinventing the Map.get method, which returns null if the specified key isn't found.


With Java 8, I would recommend using an Optional for this use case.

Optional<User> findUserByName(Collection<User> users, String name){
    Optional<User> value = users
        .stream()
        .filter(a -> a.equals(name))
        .findFirst();
}

This also makes it very clear to the caller that the optional can be empty if the value is not found. If you really want to throw an exception, you can use orElseThrows in Optional to achieve it.

ReferenceURL : https://stackoverflow.com/questions/24760314/is-there-a-standard-java-exception-class-that-means-the-object-was-not-found

반응형