문제

저는 .NET을 사용했고 지금은 Java를 사용하고 있습니다.

현재 잘못된 입력에 대해 방어적으로 API를 설계하는 데 큰 문제가 있습니다.다음 코드가 있다고 가정해 보겠습니다(충분히 가깝습니다).

public void setTokens(Node node, int newTokens) {
    tokens.put(node, newTokens);
}

그러나 이 코드는 다음 두 가지 이유로 실패할 수 있습니다.

  1. 사용자는 null 마디.
  2. 사용자가 잘못된 노드를 전달했습니다. 즉,그래프에 포함되지 않은 것.

.NET에서는 ArgumentNullException (대신 NullReferenceException!) 또는 ArgumentException 각각 문제가 되는 인수의 이름을 전달합니다(node)로서 string 논쟁.

Java에는 이에 상응하는 예외가 없는 것 같습니다.좀 더 구체적으로 설명하고 상황을 설명하는 데 가장 가까운 예외를 던지거나 특정 상황에 대한 예외 클래스를 직접 작성할 수도 있다는 것을 깨달았습니다.

이것이 최선의 방법입니까?아니면 다음과 유사한 범용 클래스가 있습니까? ArgumentException .NET에서?

확인하는 것이 의미가 있습니까? null 이 경우에는?어쨌든 코드는 실패하고 예외의 스택 추적에는 위의 메서드 호출이 포함됩니다.확인 중 null 중복되고 과도한 것 같습니다.물론 스택 추적은 다음과 같습니다. 약간 더 깨끗합니다(대상은 내부 검사가 아닌 위의 방법이므로 HashMap JRE 구현).그러나 이는 추가 비용으로 상쇄되어야 합니다. if 또한, 다음과 같은 진술을 해야 합니다. 절대 어쨌든 발생 – 결국 통과 null 위의 방법은 예상된 상황이 아니며 다소 어리석은 버그입니다.그것을 기대하는 것은 완전히 편집증적이며, 확인하지 않더라도 동일한 예외를 제외하고는 실패할 것입니다.

[댓글에서 지적했듯이, HashMap.put 실제로 허용 null 키의 값입니다.그래서 수표를 null 여기서 반드시 중복되는 것은 아닙니다.]

도움이 되었습니까?

해결책

그룹마다 기준이 다릅니다.

먼저, 당신이 차이점을 알고 있다고 가정합니다. RuntimeExceptions(선택 해제) 및 일반 Exceptions (선택), 그렇지 않은 경우 참조 이 질문과 답변.자신만의 예외를 작성하면 강제로 잡을 수 있지만 둘 다 NullPointerException 그리고 IllegalArgumentException 일부 서클에서는 눈살을 찌푸리는 RuntimeExceptions입니다.

둘째, 여러분과 마찬가지로 제가 함께 일했지만 적극적으로 어설션을 사용하지 않는 그룹이 있습니다. 그러나 여러분의 팀(또는 API 소비자)이 어설션을 사용하기로 결정한 경우 어설션은 정확하게 올바른 메커니즘처럼 들립니다.

내가 너라면 나는 사용할 것이다 NullPointerException.그 이유는 선례입니다.예를 들어 Sun의 Java API를 예로 들어 보겠습니다. java.util.TreeSet.이는 바로 이런 종류의 상황에 NPE를 사용하며 코드에서 방금 null을 사용한 것처럼 보이지만 이는 전적으로 적절합니다.

다른 사람들이 말했듯이 IllegalArgumentException 옵션이지만 NullPointerException이 더 전달력이 좋다고 생각합니다.

이 API가 외부 회사/팀에서 사용하도록 설계된 경우 나는 계속 사용할 것입니다. NullPointerException, 그러나 javadoc에 선언되어 있는지 확인하세요.내부용이라면 자신만의 예외 계층을 추가하는 것이 가치 있다고 판단할 수도 있지만, 개인적으로 나는 거대한 예외 계층을 추가하는 API를 발견했습니다. printStackTrace()d나 Logged는 노력낭비일 뿐입니다.

결국 가장 중요한 것은 코드가 명확하게 전달된다는 것입니다.로컬 예외 계층 구조는 로컬 전문 용어와 같습니다. 즉, 내부자에게 정보를 추가하지만 외부자를 당황하게 할 수 있습니다.

null에 대한 확인과 관련하여 나는 그것이 의미가 있다고 주장합니다.첫째, 예외를 생성할 때 무엇이 ​​null인지(예: 노드 또는 토큰)에 대한 메시지를 추가할 수 있어 도움이 됩니다.둘째, 앞으로는 Map 다음을 허용하는 구현 null, 그러면 오류 확인이 손실됩니다.비용은 거의 들지 않으므로 프로파일러가 내부 루프 문제라고 말하지 않는 한 걱정하지 않을 것입니다.

다른 팁

표준 Java 예외는입니다 IllegalArgumentException. 일부는 던질 것입니다 NullPointerException 논쟁이 널이지만 나에게 NPE는 "누군가가 망쳐 놓았다"는 의미를 가지고 있으며, 당신은 당신의 API의 고객이 당신이 무엇을하고 있는지 모른다고 생각하기를 원하지 않습니다.

공개 API의 경우 인수를 확인하고 조기 및 깨끗하게 실패하십시오. 시간/비용은 간신히 중요합니다.

Java에서는 일반적으로 불법 행위를 던질 것입니다

좋은 Java 코드를 작성하는 방법에 대한 가이드를 원한다면 책을 강력히 추천 할 수 있습니다. 효과적인 자바 Joshua Bloch.

이것이 적절한 용도 일 수있는 것 같습니다. 주장하다:

public void setTokens(Node node, int newTokens) {
    assert node != null;
    tokens.put(node, newTokens);
}

귀하의 접근 방식은 전적으로 기능이 귀하의 기능이 발신자에게 제공하는 계약에 달려 있습니다. 노드가 NULL이 아닌 전제 조건입니까?

그것이 계약 위반이기 때문에 노드가 null이면 예외를 던져야합니다. 그렇지 않은 경우 기능이 널 노드를 조용히 처리하고 적절하게 응답해야합니다.

나는 방법의 계약과 발신자가 얼마나 잘 알려져 있는지에 달려 있다고 생각합니다.

과정의 어느 시점에서 발신자는 메소드를 호출하기 전에 노드를 검증하기 위해 조치를 취할 수 있습니다. 발신자를 알고이 노드가 항상 검증된다는 것을 알고 있다면 좋은 데이터를 얻을 수 있다고 가정해도 괜찮습니다. 본질적으로 책임은 발신자에게 있습니다.

그러나 예를 들어, 분산 된 타사 라이브러리를 제공하는 경우 Nulls 등에 대한 노드를 검증해야합니다 ...

불법 행위 예고는 Java 표준이지만 runtimeexception이기도합니다. 따라서 발신자가 예외를 처리하도록 강요하려면 확인 예외, 아마도 당신이 만든 사용자 정의 예외를 제공해야합니다.

개인적으로 나는 NullPointerExceptions가 우연히만 발생하기를 원하므로 불법 인수 값이 통과되었음을 나타내는 데 다른 것을 사용해야합니다. 이것에 대해 불법 행위 지출은 괜찮습니다.

if (arg1 == null) {
 throw new IllegalArgumentException("arg1 == null");
}

이것은 코드를 읽는 사람들뿐만 아니라 아침 3시에 지원 전화를받는 가난한 영혼에 충분해야합니다.

(그리고 항상 예외에 대한 설명 텍스트를 제공하면 슬픈 날에 감사 할 것입니다).

다른 것과 마찬가지로 : java.lang.illegalargumentexception. NULL 노드 확인에 대해 노드 생성에서 잘못된 입력을 확인하는 것은 어떻습니까?

아무도 기쁘게 할 필요가 없으므로 지금은 표준 코드로서 내가하는 일은

void method(String s) 

if((s != null) && (s instanceof String) && (s.length() > 0x0000))
{

나에게 많은 수면을 취합니다.

다른 사람들은 동의하지 않을 것입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top