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


답변:


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.