[java] Integer.parseInt ()를 캡슐화하는 좋은 방법

Integer.parseInt()String을 int로 변환하는 데 자주 사용하는 프로젝트가 있습니다. 무언가 잘못되었을 때 (예를 들어, String숫자가 아니라 문자 a등)이 메서드는 예외를 발생시킵니다. 그러나 모든 곳에서 내 코드에서 예외를 처리해야한다면 이것은 매우 빠르게보기 흉하게 보이기 시작합니다. 나는 이것을 메소드에 넣고 싶지만 변환이 잘못되었음을 보여주기 위해 깨끗한 값을 반환하는 방법에 대한 단서가 없습니다.

C ++에서는 int에 대한 포인터를 받아들이고 메서드 자체가 true 또는 false를 반환하도록하는 메서드를 만들 수 있습니다. 그러나 내가 아는 한 이것은 Java에서 가능하지 않습니다. 참 / 거짓 변수와 변환 된 값을 포함하는 개체를 만들 수도 있지만 이것도 이상적이지 않습니다. 같은 일이 전역 값에 적용되며 이것은 다중 스레딩에 문제를 일으킬 수 있습니다.

이 작업을 수행하는 깨끗한 방법이 있습니까?



답변

Integer대신을 int반환 null하여 구문 분석 실패시 반환 할 수 있습니다.

내부적으로 예외가 발생하지 않고 Java가이 작업을 수행하는 방법을 제공하지 않는 것은 부끄러운 일입니다. 예외를 포착하고 null을 반환하여 예외를 숨길 수 있지만 수백을 구문 분석하는 경우 여전히 성능 문제가 될 수 있습니다. 수천 비트의 사용자 제공 데이터.

편집 : 이러한 방법에 대한 코드 :

public static Integer tryParse(String text) {
  try {
    return Integer.parseInt(text);
  } catch (NumberFormatException e) {
    return null;
  }
}

textnull 인 경우 이것이 무엇을할지 내 머리 꼭대기에서 확실하지 않습니다 . -버그를 나타내는 경우 (즉, 코드가 유효하지 않은 값을 전달할 수 있지만 null을 전달해서는 안 됨) 예외를 던지는 것이 적절합니다. 버그를 나타내지 않는 경우 다른 잘못된 값과 마찬가지로 null을 반환해야합니다.

원래이 답변은 new Integer(String)생성자를 사용했습니다 . 이제는 Integer.parseInt권투 작업을 사용 합니다. 이런 식으로 작은 값은 캐시 된 Integer개체 에 상자로 묶여 이러한 상황에서 더 효율적으로 만듭니다.


답변

숫자가 아닌 경우 어떤 행동을 기대합니까?

예를 들어 입력이 숫자가 아닐 때 사용할 기본값이있는 경우 다음과 같은 방법이 유용 할 수 있습니다.

public static int parseWithDefault(String number, int defaultVal) {
  try {
    return Integer.parseInt(number);
  } catch (NumberFormatException e) {
    return defaultVal;
  }
}

입력을 구문 분석 할 수없는 경우 다른 기본 동작에 대해 유사한 메서드를 작성할 수 있습니다.


답변

어떤 경우에는 파싱 오류를 fail-fast 상황으로 처리해야하지만 애플리케이션 구성과 같은 다른 경우에는 Apache Commons Lang 3 NumberUtils를 사용하여 누락 된 입력을 기본값으로 처리하는 것을 선호합니다 .

int port = NumberUtils.toInt(properties.getProperty("port"), 8080);


답변

예외 처리를 방지하려면 정규식을 사용하여 먼저 모든 숫자가 있는지 확인하십시오.

//Checking for Regular expression that matches digits
if(value.matches("\\d+")) {
     Integer.parseInt(value);
}


답변

Ints.tryParse()구아바 . 숫자가 아닌 문자열에는 예외가 발생하지 않지만 null 문자열에는 예외가 발생합니다.


답변

질문에 대한 답변을 읽은 후 parseInt 메서드를 캡슐화하거나 래핑하는 것은 필요하지 않으며 좋은 생각이 아닐 수도 있습니다.

Jon이 제안한대로 ‘null’을 반환 할 수 있지만 이는 try / catch 구조를 null 검사로 대체하는 것입니다. 오류 처리를 ‘잊는’경우 동작에는 약간의 차이가 있습니다. 예외를 포착하지 않으면 할당이없고 왼쪽 변수가 이전 값을 유지합니다. null을 테스트하지 않으면 JVM (NPE)에 맞을 것입니다.

하품의 제안은 나에게 더 우아하게 보입니다. 왜냐하면 나는 일부 오류나 예외적 인 상태를 알리기 위해 null을 반환하는 것을 좋아하지 않기 때문입니다. 이제 문제를 나타내는 미리 정의 된 개체를 사용하여 참조 동등성을 확인해야합니다. 그러나 다른 사람들이 주장 하듯이 다시 확인하는 것을 ‘잊고’문자열을 구문 분석 할 수없는 경우 프로그램은 ‘ERROR’또는 ‘NULL’개체 내부에 래핑 된 int와 연속됩니다.

Nikolay의 솔루션은 훨씬 더 객체 지향적이며 다른 래퍼 클래스의 parseXXX 메서드에서도 작동합니다. 그러나 결국 그는 NumberFormatException을 OperationNotSupported 예외로 대체했습니다. 다시 한 번 구문 분석 할 수없는 입력을 처리하려면 try / catch가 필요합니다.

그래서 평범한 parseInt 메서드를 캡슐화하지 않는다는 결론입니다. 일부 (응용 프로그램에 따라 다름) 오류 처리도 추가 할 수있는 경우에만 캡슐화합니다.


답변

다음과 같이 사용할 수 있습니다.

public class Test {
public interface Option<T> {
    T get();

    T getOrElse(T def);

    boolean hasValue();
}

final static class Some<T> implements Option<T> {

    private final T value;

    public Some(T value) {
        this.value = value;
    }

    @Override
    public T get() {
        return value;
    }

    @Override
    public T getOrElse(T def) {
        return value;
    }

    @Override
    public boolean hasValue() {
        return true;
    }
}

final static class None<T> implements Option<T> {

    @Override
    public T get() {
        throw new UnsupportedOperationException();
    }

    @Override
    public T getOrElse(T def) {
        return def;
    }

    @Override
    public boolean hasValue() {
        return false;
    }

}

public static Option<Integer> parseInt(String s) {
    Option<Integer> result = new None<Integer>();
    try {
        Integer value = Integer.parseInt(s);
        result = new Some<Integer>(value);
    } catch (NumberFormatException e) {
    }
    return result;
}

}