래퍼 클래스 및 기본 유형을 사용하는 경우


답변:


69

다른 사람들은 Collections객체가 필요하고 객체가 원시 대응 물 (메모리 및 권투)보다 오버 헤드가 더 많다는 것과 같은 특정 구조를 언급했습니다 .

또 다른 고려 사항은 다음과 같습니다.

객체를 초기화 null하거나 null메서드 / 생성자에 매개 변수를 보내 상태 또는 기능을 나타내는 것이 편리 할 수 ​​있습니다 . 이것은 프리미티브로는 할 수 없습니다.

많은 프로그래머가이를 나타 내기 위해 숫자를 0 (기본값) 또는 -1로 초기화하지만 시나리오에 따라 잘못되거나 오해의 소지가있을 수 있습니다.

이것은 또한 NullPointerException무언가가 잘못 사용되는 경우에 대한 장면을 설정합니다. 이것은 임의의 버그보다 훨씬 더 프로그래머 친화적입니다.


15
"객체를 null로 초기화하는 것이 편리 할 수 ​​있습니다." 이것은 정확하지 않기 때문에 유용 할 수 없습니다. 필드가 선택 사항이면 명시 적으로 표시해야합니다.
Eddie Jamsession

8
lol @EddieJamsession 감사합니다. 다시는 null로 초기화하지 않습니다. (pfffft)
pstanton

@EddieJamsession 실제 값을 설정할 때 실패를 나타내는 방법으로 개체를 null로 초기화하는 경우이 문제를 잡기 위해 다른 방법을 제안 하시겠습니까? 오, 나는 이것을 입력하면서 깨달았습니다 : 예외. NullPointerException은 너무 일반적입니다. 무엇이 잘못되었는지 표시하기 위해 매우 구체적인 사용자 지정 예외를 사용하는 것이 좋습니다. 좋아, 나는 지금부터 ...에 일을 할 것입니다
klaar

1
@EddieJamsession 문제를 읽은 후 Optional 객체의 개념을 접하게되었습니다. 권리.
klaar

18

일반적으로 (컬렉션에 넣는 등) 어떤 이유로 객체 가 필요 하지 않으면 기본 유형을 사용해야합니다 . 그럼에도 불구하고 수치 성능을 극대화하려면 객체가 필요하지 않은 다른 접근 방식을 고려하십시오. 이는 문서 에서 권장하며이 문서 는 자동 박싱이 어떻게 큰 성능 차이를 유발할 수 있는지 보여줍니다.


3
성능 저하가 크지 않아 코드 가독성 / 신뢰성이 뒷받침되어야합니다.
pstanton

2
첫째, 프리미티브를 적절하게 사용한다고해서 코드를 읽을 수 없게되는 것은 아닙니다. 둘째, 경우에 따라 성능 저하가 심각합니다. 결코 그렇지 않다고 말하는 것은 어리석은 일입니다.
Matthew Flaschen

1
@pstanton : 방법에 대해 설명 바랍니다 Integer보다 읽기 쉬운입니다 int.
Stephen C

대부분의 경우 Integer는 int보다 더 읽기 쉽지 않으며 이러한 경우에는 항상 int를 사용합니다. 또는 특정 변수가 null이 될 수 없다는 것을 알고 있으면 int가 약간 더 효율적이기 때문에 int를 사용합니다. 그러나 많은 경우에 다른 프로그래머가 개체가 사용될 때 변수의 상태를 이해하는 것이 더 쉽습니다. 이는 준비되지 않았 음을 나타 내기 위해 null로 초기화 될 수 있기 때문입니다. 예를 들어 고유 한 증분 숫자 ID가있는 저장되지 않은 데이터베이스 레코드가있는 경우 유효한 ID가 할당되기 전에이 ID가 0, -1 또는 null이어야합니까? 이 경우 개체가 더 좋습니다.
pstanton

성능과 관련하여-특별한 경우에는 성능 저하가 심각 할 수 있습니다. 즉, 이러한 오브젝트를 매우 빠르게 생성하거나 일정 기간 동안 많은 오브젝트가 축적되는 경우입니다. 그러나 나는 괜찮은 프로그래머가 이러한 특수한 경우를 식별하거나 그에 따라 수정할 수 있기를 기대합니다. 나는 그것이 결코 중요하지 않다고 말한 적이 없지만 일반적으로 말하면 그렇지 않습니다.
pstanton

12

내 생각에 클래스 멤버가 래퍼 변수이면 개발자 친화적 인 동작 인 기본값에 의존하지 않습니다.

1.

class Person {
   int SSN ; // gets initialized to zero by default 
}

2.

class PersonBetter {
  Integer SSN; //gets initialized to null by default
}

첫 번째 경우에는 SSN 값을 초기화하지 않은 상태로 유지할 수 없습니다. 사용하기 전에 값이 설정되었는지 확인하지 않으면 손상 될 수 있습니다.

두 번째 경우에는 SSN을 null로 초기화 할 수 있습니다. NullPointerException이 발생할 수 있지만 SSN 필드를 초기화하지 않고 사용하려고 할 때마다 무의식적으로 기본값 (0)을 SSN으로 데이터베이스에 삽입하는 것보다 낫습니다.


3
빌더 패턴은이 문제를 해결하기위한 것입니다. 이 시나리오에서는 인스턴스 PersonBuilder를 가져 오기 위해 "build"를 호출하기 전에 SSN이 설정되지 않은 경우 예외를 throw하는를 만듭니다 Person. 나는 이런 종류의 것이 과도하다고 생각하지만 Java 언어가 적절한 패턴을 장려하는 것입니다.
Sandy Chapman

8

필요한 경우에만 래퍼 유형을 사용합니다.

그것들을 사용함으로써 당신은 그들이 있다는 사실 외에 많은 것을 얻지 못합니다 Objects.

또한 메모리 사용량과 boxing / unboxing에 소요되는 시간의 오버 헤드를 잃게됩니다.


4
많이 얻지 못할 수도 있지만 많이 잃지는 않습니다. 1990 년대 팜 파일럿을 달리지 않는 한.
pstanton

그들이 객체라는 사실은 또한 평범한 프리미티브보다 훨씬 더 많은 컨텍스트와 캡슐화를 제공합니다. 따라서 이러한 프리미티브의 의미와 사용 위치에 따라 실제로 많은 것을 얻을 수 있습니다.
aberrant80

4

실제로 나는 래퍼 클래스의 사용을 설명 할 수있는 상황에 직면했습니다.

long유형 변수 가있는 서비스 클래스를 만들었습니다.

  1. 변수가 유형 인 경우 long-초기화되지 않은 경우 0으로 설정됩니다. 이는 GUI에 표시 될 때 사용자에게 혼동을 줄 것입니다.
  2. 변수 유형이 Long초기화되지 않은 경우 다음 으로 설정됩니다 null.이 null 값은 GUI에 표시되지 않습니다.

이것은 기본 값을 Boolean사용할 때 값이 더 혼란 스러울 수있는 경우 에도 적용됩니다 boolean(기본값은 false이므로).


3

컬렉션은 단순한 Java 래퍼 개체의 일반적인 경우입니다. 그러나 코드 (값 개체)에서 래퍼에보다 구체적인 의미를 부여하는 것을 고려할 수 있습니다.

IMHO는 코드의 가독성과 유지 관리로 귀결 될 때 값 객체를 사용하는 데 거의 항상 이점이 있습니다. 특정 책임이있는 객체 내부에 간단한 데이터 구조를 래핑하면 코드가 단순화되는 경우가 많습니다. 이것은 Domain-Driven Design 에서 매우 중요한 것입니다 .

물론 성능 문제가 있지만 적절한 데이터로 성능을 측정하고 문제 영역에 대한보다 직접적인 조치를 취할 수있을 때까지이를 무시하는 경향이 있습니다. 코드도 이해하기 쉬운 경우 성능 문제를 이해하는 것이 더 쉬울 수도 있습니다.


3

수치 계산이 지배하는 응용 프로그램의 성능 은 프리미티브를 사용하여 큰 이점을 얻을 수 있습니다.

기본 유형 에서는 == 연산자를 사용하지만 래퍼의 경우 선호되는 선택은 equals () 메서드를 호출하는 것입니다.

"유해한 것으로 간주되는 원시 유형 "은 "절차 적 의미를 통일 된 객체 지향 모델로 혼합하기 때문입니다."

많은 프로그래머가이를 나타 내기 위해 숫자를 0 (기본값) 또는 -1로 초기화하지만 시나리오에 따라 잘못되거나 오해의 소지가있을 수 있습니다.


1

컬렉션을 사용 하려면 래퍼 클래스 를 사용해야합니다 .

기본 유형은 배열에 사용됩니다. 또한 동작이없는 데이터 (예 : 카운터 또는 부울 조건)를 나타냅니다.

오토 박싱 이후, "프리미티브 또는 래퍼를 사용해야하는 경우"경계가 매우 모호해졌습니다.

그러나 Wrappers는 객체이므로 모든 멋진 Java 기능을 사용할 수 있습니다. 예를 들어 반사를 사용하여 Integer 개체를 만들 수 있지만 int 값은 만들 수 없습니다. 래퍼 클래스에는 valueOf와 같은 메서드도 있습니다.


컬렉션 외에 래퍼 클래스를 사용하면 안 되나요? Integer i = new Integer (10); 같은 일반적인 선언에 사용하는 것은 어떻습니까? 이렇게하면 좋은가요?
Gopi

autoboxing을 사용하면 Integer i = 10을 수행 할 수 있습니다.

1
아니, 스리. 내가 대상이되어야한다는 요구 사항이 없다면, 그것을 만들지 마십시오.
Matthew Flaschen

Autoboxing은 위에서 선언 한 i를 int i = 10 또는 Integer i = 10으로 언 박스합니까?
Gopi

3
int pi = new Integer (10); 공장. 정수 oi = 10; 공장. int ni = null; 작동하지 않습니다. LHS는 RHS가 요구하는대로 변환됩니다.
pstanton

0

값 유형을 생성하려는 경우. ProductSKU 또는 AirportCode와 같은 것입니다.

기본 유형 (내 예제의 문자열)이 동등성을 정의 할 때 동등성을 재정의하고 싶을 것입니다.


5
문자열은 원시 아니다
pstanton

2
문자열을 기본 개체로 포함하는 값 유형을 래핑해야하는 이유가 여전히 있습니다.
Chris Missal

당신의 대답은 말이되지 않습니다. 무슨 말을 하시는지 잘 모르겠습니다. 나는 귀하의 의견에 동의합니다. 래퍼 클래스는 가독성을 높이면 좋은 생각입니다.
pstanton

값 유형 또는 값 객체는 생성되어야하며 변경 불가능해야합니다. 예를 들어, new CountryCode ( "USA")와 같은 "CountryCode"개체를 만든 다음 동일한 방식으로 다른 개체를 만든 다음 나중에 다른 개체를 만드는 것은 이치에 맞지 않습니다. 시작하는 문자열 일 뿐이지 만 그 뒤에 의미가 있습니다. 문자열을 사용하면 더 많은 데이터를 추가하는 등의 방법으로 문자열을 수정할 수 있지만 더 이상 동일하지 않습니다. 감지 내가이 차종을 희망 :) 설명하기 위해 노력하고있어 더 나은 설명은이 문서를 참조하십시오 c2.com/cgi/wiki?ValueObject
크리스 미사 경본

0

Java의 기본 값은 객체가 아닙니다. 이러한 값을 객체로 조작하기 위해 java.lang 패키지는 각 기본 데이터 유형에 대한 래퍼 클래스를 제공합니다.

모든 래퍼 클래스는 최종입니다. 시작될 수있는 모든 래퍼 클래스의 개체는 변경 불가능하므로 래퍼 개체의 값을 변경할 수 없습니다.

그러나 void 클래스는 래퍼 클래스로 간주되지만 기본 값을 래핑하지 않으며 초기화 할 수 없습니다. public 생성자가 없으며 void 키워드를 나타내는 클래스 객체를 나타냅니다.

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