Java에서 오토 박싱과 언 박싱을 사용하는 이유는 무엇입니까?
Autoboxing은 Java 컴파일러가 기본 유형과 해당 객체 래퍼 클래스간에 수행하는 자동 변환입니다. 예를 들어 int를 Integer로, double을 Double로 변환하는 식입니다. 변환이 다른 방향으로 진행되는 경우이를 unboxing이라고합니다.
그렇다면 왜 이것이 필요하고 자바에서 오토 박싱과 언 박싱을 사용 하는가?
이것의 주된 이유를 완전히 이해하려면 약간의 컨텍스트가 필요합니다.
프리미티브 대 클래스
Java의 기본 변수에는 값 (정수, 배정 밀도 부동 소수점 이진 숫자 등)이 포함됩니다. 때문에 이 값은 다른 길이있을 수 있습니다 ,이를 포함하는 변수는 다른 길이있을 수 있습니다 (고려 float
대 double
).
반면에 클래스 변수에는 인스턴스에 대한 참조 가 포함 됩니다. 참조는 일반적으로 여러 언어에서 포인터 (또는 포인터와 매우 유사한 것)로 구현됩니다. 이런 일들은 일반적으로 상관없이 (참조하는 인스턴스의 크기, 같은 크기를 가지고 Object
, String
, Integer
, 등).
클래스 변수의이 속성은 포함 된 참조를 (범위까지) 상호 교환 가능하게 만듭니다 . 이것은 우리가 대체 라고 부르는 것을 할 수있게합니다 : 대체로 말하자면, 특정 유형의 인스턴스를 다른 관련 유형의 인스턴스로 사용하는 String
것 Object
입니다 (예를 들어를로 사용).
프리미티브 변수는 같은 방식으로 서로 또는 Object
. 이것에 대한 가장 명백한 이유 (유일한 이유는 아님)는 크기 차이입니다. 이것은이 점에서 원시 유형을 불편하게 만들지 만, 우리는 여전히 언어에서 그것들이 필요합니다 (주로 성능으로 귀결되는 이유 때문에).
제네릭 및 유형 삭제
제네릭 유형은 하나 이상의 유형 매개 변수 가있는 유형입니다 (정확한 숫자를 제네릭 arity 라고 함 ). 예를 들어, 제네릭 유형 정의 List<T>
에는 ( 구체적인 유형 생성 ), ( ), ( ) 등이 T
될 수 있는 유형 매개 변수 가 있습니다 .Object
List<Object>
String
List<String>
Integer
List<Integer>
제네릭 유형은 비 제네릭 유형보다 훨씬 더 복잡합니다. 그들이 JVM에 급진적 인 변화 이상 바이너리 가능성이 파괴 호환성을 방지하기 위해, (초기 릴리스 이후) 자바에 소개되었을 때, 자바의 창조자는 최소 침습적 방법으로 일반적인 유형을 구현하기로 결정 : 모든 콘크리트 유형의 List<T>
실제로 (이진에 해당하는)로 컴파일됩니다 ( List<Object>
다른 유형의 경우 바운드는 이외의 것이 될 수 Object
있지만 요점을 얻습니다). 이 과정에서 일반 arity 및 유형 매개 변수 정보가 손실 되므로이를 유형 삭제 라고합니다 .
두 가지를 합치면
이제 문제는 위의 현실의 조합은 다음과 같은 경우 List<T>
가됩니다 List<Object>
모든 경우에, 다음 T
항상 직접 할당 할 수있는 유형이어야합니다Object
. 다른 것은 허용 할 수 없습니다. 앞서 말했듯이,는 int
, float
와 double
상호 교환 Object
할 수 없기 때문에 List<int>
, List<float>
또는 List<double>
(JVM에 훨씬 더 복잡한 제네릭 구현이 존재하지 않는 한)는 있을 수 없습니다 .
그러나 자바 이벤트 유형은 좋아 Integer
, Float
하고 Double
있는 그들을 효과적으로 대용하고, 클래스 인스턴스에서 이러한 프리미티브를 포장 Object
하여, 프리미티브와 간접적으로 업무에 제네릭 형식을 허용 (당신이 있기 때문에뿐만 아니라 수 있습니다 List<Integer>
, List<Float>
, List<Double>
등).
Integer
에서 int
, Float
에서 a float
등 을 만드는 과정을 boxing 이라고 합니다. 그 반대를 unboxing 이라고 합니다. 프리미티브를 사용하고 싶을 때마다 박스형을해야하는 Object
것은 불편하기 때문에 언어가이를 자동으로 수행하는 경우가 있습니다 . 이를 autoboxing 이라고 합니다.
Auto Boxing 은 원시 데이터 유형을 래퍼 클래스 객체로 변환 하는 데 사용 됩니다. 래퍼 클래스는 기본 유형에서 수행 할 광범위한 기능을 제공합니다. 가장 일반적인 예는 다음과 같습니다.
int a = 56;
Integer i = a; // Auto Boxing
됩니다 필요 쉽게 권투 언 박싱 처리됩니다 직접 쓰기 코드와 JVM을 할 수 있기 때문에 프로그래머.
Auto Boxing은 java.util.Collection 유형으로 작업 할 때도 유용합니다. 기본 유형의 컬렉션을 생성하려는 경우 기본 유형의 컬렉션을 직접 생성 할 수 없으며 Object의 컬렉션 만 생성 할 수 있습니다. 예 :
ArrayList<int> al = new ArrayList<int>(); // not supported
ArrayList<Integer> al = new ArrayList<Integer>(); // supported
al.add(45); //auto Boxing
래퍼 클래스
Java의 8 가지 기본 유형 (byte, short, int, float, char, double, boolean, long)은 각각 별도의 Wrapper 클래스와 관련되어 있습니다. 이러한 래퍼 클래스에는 기본 데이터 유형에 대한 유용한 작업을 미리 정의하기위한 미리 정의 된 메서드가 있습니다.
의 사용 래퍼 클래스
String s = "45";
int a = Integer.parseInt(s); // sets the value of a to 45.
Wrapper 클래스가 제공하는 유용한 기능이 많이 있습니다. 여기 에서 자바 문서를 확인 하세요.
Unboxing 은 래퍼 클래스 객체를 다시 기본 유형으로 변환하는 Auto Boxing과 반대입니다. 이것은 JVM에 의해 자동으로 수행되므로 특정 작업에 래퍼 클래스를 사용한 다음 기본 형식으로 인해 처리 속도가 빨라지므로 기본 형식으로 다시 변환 할 수 있습니다. 예 :
Integer s = 45;
int a = s; auto UnBoxing;
개체와 함께 작동하는 컬렉션의 경우 자동 언 박싱 만 사용됩니다. 방법은 다음과 같습니다.
ArrayList<Integer> al = new ArrayList<Integer>();
al.add(45);
int a = al.get(0); // returns the object of Integer . Automatically Unboxed .
원시 (비 객체) 유형에는 효율성에 대한 정당성이 있습니다.
기본 유형 int, boolean, double
은 즉각적인 데이터 인 반면 Object
s는 참조입니다. 따라서 필드 (또는 변수)
int i;
double x;
Object s;
로컬 메모리 4 + 8 + 8이 필요합니까? 객체의 경우 메모리에 대한 참조 (주소) 만 저장됩니다.
Object 래퍼 Integer, Double
및 기타를 사용하면 힙 메모리의 일부 Integer / Double 인스턴스에 대한 참조 인 간접 참조가 도입됩니다.
권투가 필요한 이유는 무엇입니까?
그것은 상대적 범위의 문제입니다. 미래의 자바에서는 ArrayList<int>
, 리프팅 기본 유형 을 가질 수 있도록 계획되어 있습니다 .
답변 : 현재 ArrayList는 Object에 대해서만 작동하며, 객체 참조를위한 공간을 확보하고 마찬가지로 가비지 수집을 관리합니다. 따라서 제네릭 유형 은 Object 자식입니다. 따라서 부동 소수점 값의 ArrayList를 원하면 Double 객체에 double을 래핑해야합니다.
여기서 Java는 템플릿이있는 기존 C ++와 다릅니다. C ++ 클래스 vector<string>, vector<int>
는 두 개의 컴파일 제품을 만듭니다. Java 디자인은 하나의 ArrayList.class를 갖기 위해 사용되었으며 모든 매개 변수 유형에 새로 컴파일 된 제품이 필요하지 않았습니다.
따라서 Object one에 대한 박싱 없이는 매개 변수 유형이 발생할 때마다 클래스를 컴파일해야합니다. 구체적으로 말하면 모든 컬렉션 또는 컨테이너 클래스에는 Object, int, double, boolean 버전이 필요합니다. Object 버전은 모든 자식 클래스를 처리합니다.
실제로 이러한 다양 화의 필요성은 int, char, double에서 작동하는 IntBuffer, CharBuffer, DoubleBuffer 등의 Java SE에 이미 존재했습니다. 일반적인 소스에서 이러한 소스를 생성 하여 해키 방식으로 해결되었습니다 .
JDK 5부터 자바는 오토 박싱과 오토 언 박싱이라는 두 가지 중요한 기능을 추가했습니다. AutoBoxing 은 이러한 객체가 필요할 때마다 기본 유형이 동등한 래퍼에 자동으로 캡슐화되는 프로세스입니다. 객체를 명시 적으로 구성 할 필요는 없습니다. 자동 언 박싱 은 값이 필요할 때 캡슐화 된 개체의 값이 유형 래퍼에서 자동으로 추출되는 프로세스입니다. intValue () 또는 doubleValue () 와 같은 메서드를 호출 할 필요가 없습니다 .
오토 박싱 및 자동 언 박싱의 추가는 작성 알고리즘을 크게 단순화 하여 미끼를 수동으로 박싱하고 값을 언 박싱하는 것을 제거합니다. 실수 를 피하는 것도 도움이됩니다 . 객체에서만 작동하는 제네릭 에게도 매우 중요 합니다. 마지막으로, 오토 박싱은 Collections Framework 와의 작업을 용이하게합니다 .
왜 우리는 (un) boxing을 가지고 있습니까?
프리미티브와 OO (Object Oriented) 대안을 더 편안하고 덜 장황하게 혼합하는 코드를 작성합니다.
프리미티브와 OO 대안이있는 이유는 무엇입니까?
기본 형식은 C #과 달리 클래스가 아니므로 하위 클래스가 Object
아니므로 재정의 할 수 없습니다.
we have primitives like int
for performance reasons, and the Object
alternatives like Integer
for the benefits of OO programming, and as a minor point, to have a good location for utility constants and methods (Integer.MAX_VALUE and Integer.toString(int)
).
The OO benefits are visible most easily with Generics (List<Integer>
), but are not limited to that, for example:
Number getMeSome(boolean wantInt) {
if (wantInt) {
return Integer.MAX_VALUE;
} else {
return Long.MAX_VALUE;
}
}
Because they are different types, and as a convenience. Performance is likely the reason for having primitive types.
Some data structures can accept only objects, no primitive types.
Example: the key in a HashMap.
See this question for more: HashMap and int as key
There are other good reasons, such as a "int" field in a database, which could be NULL as well. An int in Java cannot be null ; an Integer reference can. Autoboxing and unboxing provide with a facility to avoid writing extraneous code in the conversions back and forth.
ArrayList does not support primitive types only support class. but we need to use primitive types e.g int, double etc.
ArrayList<String> strArrayList = new ArrayList<String>(); // is accepted.
ArrayList<int> intArrayList = new ArrayList<int>(); // not accepted.
The Integer class wraps a value of the primitive type int in an object.so bellow code is accepted.
ArrayList<Integer> intArrayList = new ArrayList<Integer>(); // is accepted.
we can add a value with add(value) method. To add a String value say "Hello" in strArrayList code is just
strArrayList.add("Hello");
and add a int value say 54 we can write
intArrayList.add(54);
but when we write intArrayList.add(54); compiler convert to the following line
intArrayList.add(Integer.valueOf(54));
As intArrayList.add(54) is easy and more acceptable from user side so compiler does the hard job which is `intArrayList.add(Integer.valueOf(54));
it is autoBoxing.
Similarly to retrieve value we just type intArrayList.get(0) and compiler convert to <code>intArrayList.get(0).intValue();
which is autoUnboxing.
Autoboxing: Converting a primitive value into an object of the corresponding wrapper class.
Unboxing: Converting an object of a wrapper type to its corresponding primitive value
// Java program to illustrate the concept
// of Autoboxing and Unboxing
import java.io.*;
class GFG
{
public static void main (String[] args)
{
// creating an Integer Object
// with value 10.
Integer i = new Integer(10);
// unboxing the Object
int i1 = i;
System.out.println("Value of i: " + i);
System.out.println("Value of i1: " + i1);
//Autoboxing of char
Character gfg = 'a';
// Auto-unboxing of Character
char ch = gfg;
System.out.println("Value of ch: " + ch);
System.out.println("Value of gfg: " + gfg);
}
}
참고URL : https://stackoverflow.com/questions/27647407/why-do-we-use-autoboxing-and-unboxing-in-java
'Development Tip' 카테고리의 다른 글
NameValueCollection을 통해 C # 반복 (0) | 2020.10.28 |
---|---|
판다 집계 수 구별 (0) | 2020.10.28 |
Pycharm 및 sys.argv 인수 (0) | 2020.10.28 |
'CELL TO THE LEFT'를 참조하는 Excel 수식 (0) | 2020.10.28 |
기본 열거 형 클래스 상속 (0) | 2020.10.28 |