Java의 True-way 솔루션 : 2 개 문자열에서 2 개의 숫자를 구문 분석 한 다음 합계를 반환합니다.


84

아주 어리석은 질문입니다. 주어진 코드 :

public static int sum(String a, String b) /* throws? WHAT? */ {
  int x = Integer.parseInt(a); // throws NumberFormatException
  int y = Integer.parseInt(b); // throws NumberFormatException
  return x + y;
}

좋은 Java인지 아닌지 말할 수 있습니까? 내가 말하는 NumberFormatException것은 확인되지 않은 예외입니다. 당신은 없는 의 일부로 지정 sum()서명. 또한 내가 이해하는 한, 검사되지 않은 예외의 개념은 프로그램의 구현이 잘못되었음을 알리는 것이며, 더 나아가 검사되지 않은 예외를 포착하는 것은 런타임에 잘못된 프로그램을 수정하는 것과 같기 때문에 나쁜 생각 입니다.

누군가 다음 사항을 명확히 하시겠습니까?

  1. NumberFormatException메소드 서명의 일부로 지정해야합니다 .
  2. 확인 된 예외 ( BadDataException)를 정의 NumberFormatException하고 메서드 내부를 처리 한 다음 BadDataException.
  3. 내 자신의 확인 된 예외 ( BadDataException)를 정의하고 정규 표현식과 같은 방식으로 두 문자열의 유효성을 검사하고 BadDataException일치하지 않으면 내 던져야 합니다.
  4. 당신의 생각은?

업데이트 :

어떤 이유로 사용해야하는 오픈 소스 프레임 워크가 아니라고 상상해보십시오. 메소드의 서명을보고 "좋아, 절대 던지지 않는다"라고 생각합니다. 그런 다음 언젠가 예외가 발생했습니다. 정상인가요?

업데이트 2 :

sum(String, String)디자인이 나쁘다는 의견이 있습니다 . 나는 절대적으로 동의하지만 우리가 좋은 디자인을 가지고 있다면 원래의 문제가 결코 나타나지 않을 것이라고 믿는 사람들을 위해 여기에 추가 질문이 있습니다.

문제 정의는 다음과 같습니다. 숫자가 Strings 로 저장되는 데이터 소스가 있습니다 . 이 소스는 XML 파일, 웹 페이지, 2 개의 편집 상자가있는 데스크톱 창 등이 될 수 있습니다.

당신의 목표는이 2를 취하고이를 Strings로 변환하고 int"합이 xxx"라는 메시지 상자를 표시 하는 논리를 구현하는 것 입니다.

이것을 설계 / 구현하기 위해 사용하는 접근 방식이 무엇이든 상관없이 다음과 같은 두 가지 내부 기능이 있습니다 .

  1. 당신이 변환 장소 Stringint
  2. 2 int초 를 추가하는 장소

내 원래 게시물의 주요 질문은 다음과 같습니다.

Integer.parseInt()올바른 문자열이 전달 될 것으로 예상 합니다 . 잘못된 문자열 을 전달할 때마다 프로그램 이 잘못 되었음을 의미합니다 ( " 사용자 가 바보입니다"가 아님). MUST 시맨틱 이있는 Integer.parseInt ()가 있고 다른 한편으로는 입력이 올바르지 않은 경우에 대해 확인해야하는 코드 조각을 구현 해야합니다 -SHOULD 시맨틱 .

그래서, 간단히 : 나는 구현 어떻게 SHOULD 의미를 난 단지 경우 MUST 라이브러리를 .


13
그것은 결코 어리석은 질문이 아닙니다. 실제로 그것은 꽤 좋은 것입니다! 어떤 옵션을 선택해야할지 잘 모르겠습니다.
martin 2011-08-25

1
업데이트에 대해 : 예, fail-fast 원칙에 따르면 이것이 반드시 나쁜 것은 아닙니다.
Johan Sjöberg 2011-08-25

1
나는 마틴의 말에 동의합니다. 가장 잘 이해되지 않는 Java 프로그래밍의 측면 중 하나이며 모범 사례가 필요합니다. 이것은 O'Reilly 외에 "이것이 어떻게 이루어져야하는지"라고 말하는 주제에 대한 페이지가 부족하여 볼 수 있습니다.
James P.

2
사실 이것은 훌륭한 질문입니다.
Chris Cudmore

1
좋은 질문입니다! 또한 몇 가지 훌륭한 답변을 제기했습니다. D
Kheldar 2011-08-25

답변:


35

이것은 좋은 질문입니다. 더 많은 사람들이 그런 생각을했으면 좋겠어요.

IMHO, 쓰레기 매개 변수를 전달받은 경우 확인되지 않은 예외를 던지는 것은 허용됩니다.

일반적으로 말하면 BadDataException예외를 사용하여 프로그램 흐름을 제어해서는 안되므로 던지지 않아야합니다. 예외는 예외입니다. 메서드 호출자 는 문자열이 숫자인지 아닌지 호출 하기 전에 알 수 있으므로 쓰레기 전달을 피할 수 있으므로 프로그래밍 오류 로 간주 될 수 있습니다. 즉, 확인되지 않은 예외를 throw해도 괜찮습니다.

선언과 관련하여 throws NumberFormatException-이것은 유용하지 않습니다. NumberFormatException이 선택 해제되어 있기 때문에 거의 알 수 없기 때문입니다. 그러나 IDE는이를 활용하고 try/catch올바르게 래핑 할 수 있습니다 . 좋은 옵션은 다음과 같이 javadoc도 사용하는 것입니다.

/**
 * Adds two string numbers
 * @param a
 * @param b
 * @return
 * @throws NumberFormatException if either of a or b is not an integer
 */
public static int sum(String a, String b) throws NumberFormatException {
    int x = Integer.parseInt(a); 
    int y = Integer.parseInt(b); 
    return x + y;
}

수정 됨 :
댓글 작성자가 유효한 점수를 얻었습니다. 이것이 어떻게 사용 될지와 앱의 전반적인 디자인을 고려해야합니다.

메서드가 모든 곳에서 사용되고 모든 호출자가 문제를 처리하는 것이 중요하다면 메서드는 확인 된 예외 (호출자가 문제를 처리하도록 강요)를 던지지 만 코드를 try/catch블록으로 복잡하게 만드는 것으로 선언합니다 .

반면에 우리가 신뢰하는 데이터에이 방법을 사용하는 경우, 폭발하지 않을 것으로 예상되고 본질적으로 불필요한 try/catch블록 의 코드 혼란을 피할 수 있으므로 위와 같이 선언하십시오 .


6
문제는 확인되지 않은 예외가 종종 무시되고 호출 스택에 침투하여 그 아래에 무엇이 있는지 알지 못하는 앱 부분에 혼란을 일으킬 수 있다는 것입니다. 문제는 실제로 입력이 유효한지 여부를 확인해야하는 코드 비트입니다.
G_H 2011-08-25

1
@G_H에 포인트가 있습니다. Java 자습서에서는 "클라이언트가 예외에서 복구 할 것으로 합리적으로 예상 할 수있는 경우 확인 된 예외로 만듭니다. 클라이언트가 예외에서 복구하기 위해 아무것도 할 수없는 경우 확인되지 않은 예외로 만듭니다"라고 말합니다. 문제는 어디에서 RuntimeException처리 해야 합니까? 호출자 여야합니까, 아니면 Exception이 떠오르도록 남겨 두어야합니까? 그렇다면 어떻게 처리해야합니까?
James P.

1
부분적으로 대답하기 위해 내가 본 두 가지 접근 방식이 있습니다. 첫 번째는 Exceptions하위 레이어에서 가로 채서 최종 사용자에게 더 의미있는 상위 수준의 예외로 래핑하는 것이고 두 번째는 초기화 할 수있는 포착되지 않은 예외 처리기를 사용하는 것입니다. 응용 프로그램 실행기.
James P.

2
javaDoc에 NumberFormatException이있는 IMHO가 훨씬 더 중요합니다. throws절에 넣는 것은 좋은 추가이지만 필수는 아닙니다.
Dorus

3
으로 "자신의 문자열이 숫자 나하지 않으면 그들이 그렇게 쓰레기에서이 피할 전달을 호출하기 전에 당신의 방법에 발신자를 알 수 있습니다" 그건 정말 사실이 아니다 :. 문자열이 int로 구문 분석되는지 확인하는 유일한 간단한 방법은 시도해 보는 것입니다. 일부 사전 확인을 원할 수도 있지만 정확한 확인은 상당히 PITA입니다.
maaartinus

49

제 생각에는 예외 논리를 가능한 한 많이 처리하는 것이 좋습니다. 따라서 나는 서명을 선호합니다

 public static int sum(int a, int b);

귀하의 메서드 서명으로 나는 아무것도 변경 하지 않을 것입니다. 당신은

  • 잘못된 값을 프로그래밍 방식으로 사용하여 대신 생산자 알고리즘의 유효성을 검사 할 수 있습니다.
  • 또는 예를 들어 사용자 입력에서 값을 전송합니다.이 경우 해당 모듈은 유효성 검사를 수행해야합니다.

따라서이 경우 예외 처리는 문서 문제가됩니다.


4
나는 이것을 좋아한다. 사용자가 계약을 따르도록하고 메서드가 한 가지 작업 만 수행하도록합니다.
Chris Cudmore

이 방법의 사용법이 a + b를 수행하는 사용자와 어떻게 다른지 이해하지 못합니다. 이 방법이 필요한 이유는 무엇입니까?
Swati

4
@Swati : 예를 들어 간단하게 보여줄 수있는 훌륭한 기술 이라고 생각합니다 . sum 메소드는 myVeryComplicatedMethodWhichComputesPhoneNumberOfMyIdealMatchGirl (int myID, int myLifeExpectancy) ...
Kheldar

3
여기에 완전히 동의합니다. sum두 개의 숫자를 예상 하는 함수는 두 개의 숫자를 가져와야합니다. 그것들을 얻는 방법은 sum기능 과 관련이 없습니다 . 논리를 올바르게 분리하십시오 . 그래서 저는 이것을 디자인 문제와 연관시키고 싶습니다.
c00kiemon5ter 2011-08-30

5

번호 4. 주어진대로이 메소드는 정수를 가져야하는 매개 변수로 문자열을 가져서는 안됩니다. 어떤 경우 (자바가 오버플로 대신 래핑되기 때문에) 예외가 발생할 가능성이 없습니다.

 x = sum(Integer.parseInt(a), Integer.parseInt(b))

무엇을 의미하는지에 대해 훨씬 더 명확합니다. x = sum(a, b)

가능한 한 소스 (입력)에 가깝게 예외가 발생하기를 원합니다.

옵션 1-3과 관련하여 호출자가 그렇지 않으면 코드가 실패 할 수 없다고 가정하기 때문에 예외를 정의하지 않습니다. 예외를 정의하여 방법에 고유 한 알려진 실패 조건에서 발생하는 일을 정의합니다. 즉, 다른 객체를 감싸는 래퍼 인 메서드가 있고 예외를 throw 한 다음 전달합니다. 예외가 메서드에 고유 한 경우에만 사용자 지정 예외를 throw해야합니다 (예에서 frex, 합계가 긍정적 인 결과 만 반환하도록되어있는 경우, 그 결과를 확인하고 예외를 던지는 것이 적절할 것입니다. 래핑하는 대신 오버플로 예외를 던지면 서명에 정의하거나 이름을 바꾸거나 먹지 않고이를 전달합니다.

질문 업데이트에 대한 응답으로 업데이트 :

간단히 말해서, MUST 라이브러리 만있는 경우 SHOULD 의미론을 어떻게 구현합니까?

이에 대한 해결책은 MUST 라이브러리를 래핑하고 SHOULD 값을 반환하는 것입니다. 이 경우 Integer를 반환하는 함수입니다. 문자열을 취하고 Integer 객체를 반환하는 함수를 작성하세요. 작동하거나 null을 반환합니다 (구아바의 Ints.tryParse처럼). 작업과 별도로 유효성 검사를 수행하십시오. 작업은 int를 취해야합니다. 잘못된 입력이있을 때 작업이 기본값으로 호출되는지 또는 다른 작업을 수행하는지 여부는 사양에 따라 달라집니다. 대부분의 경우 해당 결정을 내릴 장소가 작업에있을 가능성이 거의 없다는 것입니다. 방법.


여기서 당신의 생각은 무엇입니까? 난 경우에도 동일한 문제가 얻을 거 sum(int, int)하고 parseIntFromString(String). 동일한 기능을 얻으려면 두 경우 모두를 호출하고를 호출하는 코드를 parseIntFromString()1 개씩 작성해야 sum()합니다. 이 경우를 고려하십시오. 그것이 당신에게 의미가 있다면 나는 원래 문제의 관점과 차이가 없다고 생각합니다.
Andrey Agibalov 2011 년

@ loki2302 : 요점은 발신자가 숫자가 아닐 때 어떤 행동이 적절한 지 결정하는 것입니다. 또한 오류 검사를 수행하지 않으면 오류가 값이 할당 된 위치에 한 단계 더 가까워집니다. 디버깅 목적으로 할당에 가까울수록 디버깅이 쉬워집니다. 그리고 TDD를 수행하는 경우 호출자에 대한 적절한 단위 테스트 작성을 놓칠 가능성이 더 큽니다. 기본적으로 숫자로 간주되는 메서드 x에 제공된 문자열을 원하지 않는 경우 5 개의 클래스와 20 개의 메서드 호출이 숫자를 처리하려고 할 때 예외가 발생합니다.
jmoreno 2011-08-25

이해가 안 돼요. 인터페이스를 제공하는 int sum(String, String)것이 현실에서는 불가능 하다고 말하고 있습니까?
Andrey Agibalov

1
@ loki2302 : 표시된 코드를 감안할 때 가능하지만 나쁜 생각입니다. 문자열의 숫자가 "2", "two", "dos", "deux", "zwo"가 모두 동일하게 취급되는 단어 일 경우 해당 서명이 적절합니다. 그러나있는 그대로 메서드에는 두 개의 문자열이 주어지고이를 정수로 처리합니다. 왜 그렇게하고 싶습니까? 그것은 나쁜 생각입니다.
jmoreno

2
@ loki2302 : 쓰레기를 통과했을 때 확인되지 않은 예외를 던지는 것은 괜찮다는 대답을 받아 들였지만 강력한 형식의 언어의 요점은 쓰레기가 통과되는 것을 방지하는 것입니다. 문자열이 항상 정수 값이 될 것으로 예상하는 메서드를 갖는 것은 문제를 야기 할뿐입니다. Integer.parseInt조차도 잘 처리하지 못합니다 (예상 입력에 대한 예외는 나쁘고, .Net의 integer.TryParse 메소드가 훨씬 낫지 만 Java에는 out 매개 변수가 없기 때문에 다소 비실용적입니다).
jmoreno

3

1. 메서드 서명의 일부로 NumberFormatException을 지정해야합니다.

나도 그렇게 생각해. 좋은 문서입니다.

2. 확인 된 예외 (BadDataException)를 정의하고 메서드 내에서 NumberFormatException을 처리 한 다음 BadDataException으로 다시 throw해야합니다.

어쩔 땐 그래. 확인 된 예외는 경우에 따라 더 나은 것으로 간주되지만 작업은 상당히 PITA입니다. 이것이 많은 프레임 워크 (예 : Hibernate)가 런타임 예외 만 사용하는 이유입니다.

3. 내 자신의 확인 된 예외 (BadDataException)를 정의하고 정규 표현식과 같은 방식으로 두 문자열의 유효성을 검사하고 일치하지 않으면 BadDataException을 throw해야합니다.

못. 더 많은 작업, 더 적은 속도 (예외가 규칙이 될 것으로 예상하지 않는 한), 전혀 이득이 없습니다.

4. 당신의 생각은?

전혀.


2

Nr 4.

나는 방법을 전혀 바꾸지 않을 것이라고 생각합니다. 예외에서 비즈니스 논리를 사용하여 정상적으로 복구 할 수있는 컨텍스트에있는 스택 추적에서 호출 메서드 또는 그 이상을 시도해 보겠습니다.

나는 그것이 과잉이라고 생각하기 때문에 # 3을 확실하게하지 않을 것입니다.


2

작성중인 내용이 다른 사람에 의해 소비 될 것이라고 가정하면 (예 : API로) 1로 이동해야합니다. NumberFormatException은 특히 그러한 예외를 전달하기위한 목적이며 사용해야합니다.


2
  1. 먼저 자신에게 물어볼 필요가 있습니다. 제 방법의 사용자가 잘못된 데이터를 입력하는 것에 대해 걱정할 필요가 있는지, 아니면 적절한 데이터 (이 경우 문자열)를 입력해야하는지에 대해 걱정해야합니다. 이러한 기대는 계약에 의한 설계로도 알려져 있습니다.

  2. 그리고 3. 예, 아마도 BadDataException을 정의하거나 NumberFormatException과 같은 일부 예외를 사용하는 것이 좋지만 표준 메시지를 표시하도록 남겨 두는 것이 좋습니다. 메서드에서 NumberFormatException을 잡아서 원래 스택 추적을 포함하는 것을 잊지 않고 메시지와 함께 다시 던집니다.

  3. 상황에 따라 몇 가지 추가 정보와 함께 NumberFormatException을 다시 던질 수 있습니다. 또한 예상되는 값에 대한 javadoc 설명이 있어야합니다.String a, String b


1

당신이 속한 시나리오에 많이 달려 있습니다.

사례 1. 항상 코드를 디버그하고 다른 사람과 예외는 나쁜 사용자 경험을 유발하지 않습니다.

기본 NumberFormatException 발생

사례 2 : 코드는 유지 관리가 쉽고 이해하기 쉬워야합니다.

고유 한 예외를 정의하고이를 throw하는 동안 디버깅을 위해 더 많은 데이터를 추가합니다.

어쨌든 잘못된 입력에 대한 예외로 이동하므로 정규식 검사가 필요하지 않습니다.

프로덕션 수준 코드 인 경우 내 생각은 다음과 같은 사용자 지정 예외를 두 개 이상 정의하는 것입니다.

  1. 숫자 형식 예외
  2. 오버플로 예외
  3. Null 예외 등 ...

이 모든 것을 별도로 처리하십시오.


1
  1. 잘못된 입력으로 인해 발생할 수 있음을 분명히하기 위해 그렇게 할 수 있습니다. 코드를 사용하는 사람이이 상황을 처리하는 것을 기억하는 데 도움이 될 수 있습니다. 보다 구체적으로, 코드에서 직접 처리하거나 특정 값을 대신 반환하지 않는다는 점을 분명히합니다. 물론 JavaDoc도이 점을 분명히해야합니다.
  2. 호출자가 확인 된 예외를 처리하도록 강제하려는 경우에만.
  3. 과잉 인 것 같습니다. 구문 분석에 의존하여 잘못된 입력을 감지하십시오.

전반적으로 NumberFormaException은 올바르게 구문 분석 가능한 입력이 제공 될 것으로 예상되기 때문에 확인되지 않습니다. 입력 유효성 검사는 처리해야합니다. 그러나 실제로 입력을 구문 분석하는 것이이를 수행하는 가장 쉬운 방법입니다. 메서드를 그대로두고 문서에서 올바른 입력이 예상되며 함수를 호출하는 사람은 사용하기 전에 두 입력을 모두 유효성을 검사해야한다고 경고 할 수 있습니다.


1

예외적 인 동작은 문서에 명시되어야합니다. 실패한 경우 (예 null: 반환 유형을로 변경하여 Integer) 또는 case 1을 사용해야 하는 경우이 메서드가 특수 값을 반환 한다고 명시해야합니다. 메서드의 서명에 명시 적으로 지정하면 사용자가 다른 방법으로 올바른 문자열을 확인하면 무시할 수 있지만 메서드가 이러한 종류의 실패를 자체적으로 처리하지 않는 것은 여전히 ​​분명합니다.


1

업데이트 된 질문에 답하십시오.

예, "놀라운"예외를받는 것은 완전히 정상입니다. 프로그래밍을 처음 접했을 때 발생하는 모든 런타임 오류에 대해 생각해보십시오.

e.g ArrayIndexOutofBound

또한 for each 루프의 일반적인 놀라운 예외입니다.

ConcurrentModificationException or something like that

1

디자인 및 사용성 관점에서 런타임 예외가 여과되도록 허용되어야한다는 대답에 동의하지만 NumberFormatException으로 던지기보다는 IllegalArgumentException으로 래핑하는 것이 좋습니다. 그러면 메서드 계약이 더 명확 해져서 예외가 발생하여 잘못된 인수가 전달되었다고 선언합니다.

"Imagine, 그것은 오픈 소스 프레임 워크가 아닙니다. 어떤 이유로 써야합니다. 당신은 메소드의 서명을보고"OK, 절대 던지지 않는다 "라고 생각합니다. 그리고 언젠가 예외가 생겼습니다. . 정상입니까? " 메소드의 javadoc은 항상 메소드의 동작 (사전 및 사후 제약)을 유출해야합니다. null이 허용되지 않는 경우 javadoc에서 메소드 서명의 일부가 아니지만 null 포인터 예외가 발생한다고 말하는 컬렉션 인터페이스의 행을 생각해보십시오.


2
NumberFormatException은 IllegalArgumentException의 하위 클래스이므로이 래핑은 정보를 추가하지 않습니다.
Don Roby 2011-08-25

이것은 예외가있는 그대로 여과 될 수 있다는 것을 의미하며 (이 경우 nfe는 이미 불법 인수 예외입니다) 호출 계층의 어딘가에서 불법 인수를 처리하기위한 일반 처리가있을 수 있습니다. 따라서 이것이 사용자가 인수를 전달한 예라면 불법 인수에 대한 모든 처리를 래핑하고 사용자에게 알리는 일반 코드가있을 수 있습니다.
Scorpion

1

좋은 자바 연습에 대해 이야기하고 있듯이 제 생각에는 항상 더 좋습니다.

  • 확인되지 않은 예외를 처리하려면 확인되지 않은 사용자 지정 예외를 통해 분석합니다.

  • 또한 사용자 지정 확인되지 않은 예외를 throw하는 동안 클라이언트가 이해할 수있는 예외 메시지를 추가하고 원본 예외의 스택 추적을 인쇄 할 수도 있습니다.

  • 선택되지 않은 예외이므로 사용자 지정 예외를 "throws"로 선언 할 필요가 없습니다.

  • 이렇게하면 확인되지 않은 예외가 만들어지는 용도를 위반하지 않고 동시에 코드의 클라이언트가 예외의 원인과 해결책을 쉽게 이해할 수 있습니다.

  • 또한 java-doc에서 적절하게 문서화하는 것은 좋은 습관이며 많은 도움이됩니다.


1

나는 그것이 당신의 목적에 달려 있다고 생각하지만 최소한 문서화 할 것입니다.

/**
 * @return the sum (as an int) of the two strings
 * @throws NumberFormatException if either string can't be converted to an Integer
 */
public static int sum(String a, String b)
  int x = Integer.parseInt(a);
  int y = Integer.parseInt(b);
  return x + y;
}

또는 java.lang.Integer 클래스에 대한 Java 소스 코드에서 페이지를 가져 오십시오.

public static int parseInt(java.lang.String string) throws java.lang.NumberFormatException;

1

Google의 'Guava'라이브러리 또는 Apache의 'Validator'라이브러리 에서 구현 한 입력 유효성 검사 패턴은 어떻습니까 ( 비교 ) 어떻습니까?

제 경험상, 함수 시작 부분에서 함수의 매개 변수를 검증하고 적절한 경우 예외를 던지는 것이 좋은 습관으로 간주됩니다.

또한 저는이 질문이 언어와 무관하다고 생각합니다. 여기서 '좋은 관행'은 유효하거나 유효하지 않을 수있는 매개 변수를 취할 수있는 함수를 가진 모든 언어에 적용됩니다.


1

나는 당신의 첫 번째 "아주 어리석은 질문"문장이 매우 관련이 있다고 생각합니다. 애초에 그 서명이있는 메서드를 작성하는 이유는 무엇입니까? 두 개의 문자열을 합하는 것이 의미가 있습니까? 호출 메서드가 두 문자열을 합산하려는 경우 호출 메서드가 유효한 int인지 확인하고 메서드를 호출하기 전에 변환하는 것은 호출 메서드의 책임입니다.

이 예제에서 호출하는 메서드가 두 문자열을 int로 변환 할 수없는 경우 여러 작업을 수행 할 수 있습니다. 이 합산이 어떤 레이어에서 발생하는지에 따라 다릅니다. 문자열 변환이 프런트 엔드 코드에 매우 가깝다고 가정합니다 (올바르게 수행 된 경우).이 경우 1이 가장 가능성이 높습니다.

  1. 오류 메시지를 설정하고 처리를 중지하거나 오류 페이지로 리디렉션
  2. false를 반환합니다 (즉, 합계를 다른 객체에 넣고 반환 할 필요가 없음).
  3. 제안한대로 일부 BadDataException을 던지십시오. 그러나이 두 숫자의 합이 매우 중요하지 않는 한 이것은 과잉이며 위에서 언급했듯이 변환이 잘못된 위치에서 수행되고 있음을 의미하므로 잘못된 설계 일 수 있습니다.

1

이 질문에 대한 흥미로운 답변이 많이 있습니다. 하지만 여전히 이것을 추가하고 싶습니다.

문자열 구문 분석의 경우 항상 "정규식"을 사용하는 것을 선호합니다. java.util.regex 패키지는 우리를 돕기 위해 있습니다. 그래서 나는 어떤 예외도 던지지 않는 이와 같은 것으로 끝날 것입니다. 오류를 잡으려면 특수 값을 반환하는 것은 나에게 달려 있습니다.

import java.util.regex.Pattern;
import java.util.regex.Matcher;

public static int sum(String a, String b) {
  final String REGEX = "\\d"; // a single digit
  Pattern pattern = Pattern.compile(REGEX);
  Matcher matcher = pattern.matcher(a);
  if (matcher.find()) { x = Integer.matcher.group(); }
  Matcher matcher = pattern.matcher(b);
  if (matcher.find()) { y = Integer.matcher.group(); }
  return x + y;
}

보시다시피 코드는 조금 더 길지만 원하는 것을 처리 할 수 ​​있습니다 (x 및 y에 대한 기본값 설정, else 절에서 발생하는 작업 제어 등 ...) 우리는 더 일반적인 변환을 작성할 수도 있습니다. 루틴, 문자열, 기본 반환 값, 컴파일 할 REGEX 코드, throw 할 오류 메시지, ...

희망 그것은 유용했습니다.

경고 :이 코드를 테스트 할 수 없었으므로 최종 구문 문제를 용서해주십시오.


1
우리는 자바에 대해 이야기하고 있습니까? 무엇입니까 Integer.matcher? private메서드 내부 변수? 누락 ()많이 누락 IFS에 대한 ;, x, y선언되지를 matcher두 번 선언 ...
user85421

사실 Carlos는 서둘러 해냈고 말했듯이 즉시 테스트 할 수 없었습니다. 죄송합니다. 정규식 방식을 보여주고 싶었습니다.
Louis

좋아요,하지만 이것은 NumberFormatException 문제를 해결하지 못합니다-주요 질문 Integer.matcher.group()Integer.parseInt(matcher.group())
IMO-(이것이

0

이 문제는 사용자 오류가 애플리케이션의 핵심으로 너무 깊숙이 전파되도록하고 부분적으로는 Java 데이터 유형을 남용하기 때문에 발생합니다.

사용자 입력 유효성 검사와 비즈니스 논리를 더 명확하게 구분하고 적절한 데이터 유형을 사용하면이 문제는 저절로 사라집니다.

사실은의 의미 Integer.parseInt()가 알려져 있습니다- 유효한 정수 를 구문 분석하는 것이 주된 목적 입니다. 명시적인 사용자 입력 유효성 검사 / 파싱 단계가 누락되었습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.