태그 보관물: java

java

Java에서 원시 클래스와 클래스를 언제 사용합니까? 정수 (클래스) 대 int (기본)가 있습니다. 기본

Java에는 부울 (클래스) 대 부울 (기본)이 있습니다. 마찬가지로 정수 (클래스) 대 int (기본)가 있습니다. 기본 버전과 클래스를 사용하는시기에 대한 모범 사례는 무엇입니까? 특정 (성능?) 이유가없는 한 기본적으로 항상 클래스 버전을 사용해야합니까? 가장 일반적으로 사용되는 방법은 무엇입니까?



답변

Joshua Bloch는 효과적인 Java의 항목 5에서

교훈은 분명하다 : 박스형 프리미티브보다 프리미티브를 선호하고 의도하지 않은 오토 박싱에주의한다 .

클래스의 일반적인 용도는 클래스를 일반 유형 (목록 및 맵과 같은 Collection 클래스 포함)으로 사용하거나 암시 적 캐스트없이 다른 유형으로 변환하려는 경우입니다 (예 : Integerclass에는 메소드 doubleValue()또는) byteValue().

편집 : Joshua Bloch의 이유는 다음과 같습니다.

// Hideously slow program! Can you spot the object creation?
public static void main(String[] args) {
    Long sum = 0L;
    for (long i = 0; i < Integer.MAX_VALUE; i++) {
         sum += i;
    }
    System.out.println(sum);
}

이 프로그램은 정답을 얻지 만 한 글자 인쇄상의 오류로 인해 예상보다 훨씬 느립니다. 변수 sum는 a Long대신에 선언됩니다. long즉, 프로그램은 약 2 ^ 31 개의 불필요한 Long인스턴스를 구성합니다 (대개 long i에 추가 될 때마다 대략 1 개씩 Long sum). 합계 선언을에서 Long로 변경 long하면 컴퓨터에서 런타임이 43 초에서 6.8 초로 줄어 듭니다.


답변

일반적인 방법은 제네릭을 다루지 않는 한 기본 요소를 사용하는 것입니다 (자동 상자 및 상자 해제에 대해 알고 있어야합니다 !).

이 협약을 따라야하는 여러 가지 이유가 있습니다.

1. 간단한 실수를 피하십시오.

초보자를 종종 사로 잡는 미묘하고 직관적이지 않은 경우가 있습니다. 숙련 된 코더조차도 실수를해서 실수를 저지르기도합니다 (코드를 디버깅하고 오류를 찾을 때 맹세합니다!).

가장 일반적인 실수는 a == b대신을 사용하는 것입니다 a.equals(b). 사람들은 a == b프리미티브 작업에 익숙 하므로 Object 래퍼를 사용할 때 쉽게 수행 할 수 있습니다.

Integer a = new Integer(2);
Integer b = new Integer(2);
if (a == b) { // Should be a.equals(b)
    // This never gets executed.
}
Integer c = Integer.valueOf(2);
Integer d = Integer.valueOf(2);
if (c == d) { // Should be a.equals(b), but happens to work with these particular values!
    // This will get executed
}
Integer e = 1000;
Integer f = 1000;
if (e == f) { // Should be a.equals(b)
    // Whether this gets executed depends on which compiler you use!
}

2. 가독성 :

다음 두 가지 예를 고려하십시오. 대부분의 사람들은 두 번째가 더 읽기 쉽다고 말합니다.

Integer a = 2;
Integer b = 2;
if (!a.equals(b)) {
    // ...
}
int c = 2;
int d = 2;
if (c != d) {
    // ...
}

3. 성능 :

사실 프리미티브를 사용하는 것보다 프리미티브에 Object 래퍼를 사용하는 것이 속도 느립니다. 객체 인스턴스화, 메소드 호출 등의 비용을 모든 곳에서 사용하는 것에 추가하고 있습니다 .

Knuth의 “… 시간의 약 97 % : 조기 최적화는 모든 악의 근원”이라는 말은 실제로 적용되지 않습니다. 그는 코드 (또는 시스템)를 더 복잡하게 만드는 최적화에 대해 이야기했습니다. 포인트 # 2에 동의하면 코드가 복잡해집니다.

4. 컨벤션입니다.

다른 Java 프로그래머의 99 %와 다른 스타일을 선택하면 두 가지 단점이 있습니다.

  • 다른 사람의 코드를 읽기가 더 어렵다는 것을 알게 될 것입니다. 예제 / 자습서 등의 99 %가 기본 요소를 사용합니다. 당신이 그것을 읽을 때마다 당신은 그것이 익숙한 스타일로 어떻게 보일지에 대한 생각에 대한인지 적 오버 헤드를 갖게 될 것입니다.
  • 다른 사람들은 코드를 읽기가 더 어렵다는 것을 알게 될 것입니다. Stack Overflow에 대해 질문 할 때마다 “왜 프리미티브를 사용하지 않습니까?”라는 답변 / 설명을 살펴보아야합니다. 당신이 나를 믿지 않는다면, 사람들이 대괄호 배치와 같은 것들에 대한 전투를 살펴보십시오.이 코드는 생성 된 코드에도 영향을 미치지 않습니다!

일반적으로 나는 몇 가지 반점을 열거하지만, 나는 여기서 대회에 참석하지 않는 좋은 이유를 솔직히 생각할 수 없습니다!


답변

보통 나는 프리미티브와 함께 간다. 그러나, 같은 클래스를 사용하여 하나의 특질 IntegerBoolean할당의 가능성 null이 변수에이. 물론 이것은 null항상 검사 를 수행해야 하지만 올바르게 초기화되지 않은 일부 int또는 boolean변수 를 사용하여 논리 오류가 발생하는 것보다 NullPointerException을 얻는 것이 좋습니다 .

물론, Java 8 이후로 한 단계 더 발전 Integer할 수 있습니다 ( 예 : Optional<Integer>값이 있거나없는 변수에 사용할 수 있음).

또한 null해당 변수에 ” 알 수없는 “또는 ” 와일드 카드 “값 을 할당하는 데 사용할 수 있는 가능성을 소개합니다 . 이는 Ternary Logic 과 같은 일부 상황에서 유용 할 수 있습니다 . 또는 특정 개체가 일부 템플릿과 일치하는지 확인하고 싶을 수도 있습니다. 이 경우 null개체의 값을 가질 수있는 템플릿의 변수에 사용할 수 있습니다.


답변

평신도의 말로 :

컬렉션에 항목을 추가해야 할 때 래퍼를 사용합니다.

컬렉션은 기본 요소를 보유 할 수 없습니다.


답변

자바는 m3th0dman이 지적한대로 오토 박스 기능을 갖추고 있습니다. 가능한 가장 낮은 수준에서 생각해 보면 오토 박싱 (in 또는 out) 프리미티브 값이 애플리케이션 주변의 기본 데이터 유형으로 작업하는 경우 필요하지 않은 일부 작업에서 소비되는 클럭 사이클을 의미한다는 것을 알 수 있습니다.

일반적으로 가능할 때마다 기본 데이터 유형을 사용해야합니다.


답변