케네스로그

[Java] 자바 데이터 타입 - 리터럴, 원시형, 참조형 본문

Dev/Java

[Java] 자바 데이터 타입 - 리터럴, 원시형, 참조형

kenasdev 2022. 1. 30. 01:11
반응형

리터럴 Literal

literal  a. 문자 그대로의

리터럴은 변수나 상수에 저장되는 값 그 자체를 의미합니다. primitive type의 변수 또는 상수에 값을 할당할 때, 사용되는 값이 리터럴입니다. 

정수형 리터럴 Integer literals

정수형 숫자 중 L/l로 끝난다면 long type, 그 외에는 int 타입입니다. 기본적으로 정수형 데이터 타입(byte,short,...)은 int 리터럴로부터 생성되며, int 범주를 벗어나면 long 리터럴로 표현됩니다. 또한, 자바 SE 7부터는 바이너리형태의 리터럴을 지원합니다. 진법에 따른 표현식은 다음의 예제와 같이 0x, 0b같은 접두사를 사용합니다.

int decVal = 26;
int hexVal = 0x1a;
int binVal = 0b11010;

 

실수형 리터럴 Floating literals

실수 값 중 f로 끝나면 float형 리터럴, d는 double형 리터럴을 뜻합니다. 과학적 기수법(scientific notation)을 위해 e로 끝나는 경우도 있습니다.

double d1 = 123.4;
double d2 = 1.234e2;
float f1 = 123.4f;

 

부동소수점

(추가예정)

 

문자/문자열 리터럴 Character/String literals

char/String 리터럴 타입은 유니코드(UTF-16) 캐릭터형으로 구성됩니다. 시스템이 유니코드를 지원하지 않는다면 {\u+유니코드}의 형태로 표현해야 합니다. ie. C -> '\u0108'. character형은 홑따옴표('), String은 쌍따옴표(")를 사용합니다.

몇가지의 이스케이프 문자를 위해 리터럴 표기법이 사전에 정의되어 있으며, 아래와 같습니다.

Name expression
backsapce \b
tab \t
line feed \n
form feed \f
carriage return \r
double quote \"
single quote \'
backslash \\

 

String Literal은 어디에 저장될까?

참조: https://www.tutorialspoint.com/how-and-where-does-string-literals-in-java-stored-in-the-memory

문자열은 연속된 문자의 조합을 뜻하며, 자바에서는 이러한 문자열을 객체의 형태로 다룹니다. 문자열을 선언하는 방법은 new 키워드를 통해 만들 수 있으며, “String”과 같이 리터럴 형식으로 할당할 수 있습니다.

문자열은 힙 영역의 String Constant pool이라는 곳에 생성됩니다. JVM은 새로운 문자열을 만들어야할 때, 이 String Constant Pool에 같은 문자열 값이 존재한다면 해당 문자열을 참조한다.

 

PermGen (Permanent Generation)

(참조:https://www.baeldung.com/java-permgen-metaspace)

PermGen(permanent Generation)은 힙 메모리 영역에서 특수한 영역으로, 정적인 자료들이 모두 저장되는 특수한 공간입니다. 모든 privimite type variable, static method, referece of static object들이 저장됩니다. String의 경우, PermGen 내부에 위치한 Constant String pool에 저장되며, String이 저장되는 방식에 대해서는 밑에서 다시 한번 언급하도록 하겠습니다.

 

 

 

Null

null 리터럴은 레퍼런스 타입을 위해서만 사용할 수 있습니다. 주로 null은 레퍼런스의 존재 유무를 테스트하는데에 사용되며, 특정 객체가 사용이 불가능하다는 것을 나타내기위해 사용됩니다.

 

 

Class

class리터럴은 Class클래스를 표기하기위한 리터럴입니다. 이 부분이 이해가 잘 가지 않았는데, String리터럴은 String 클래스의 인스턴스(객체)를 표기하기 위해 사용됩니다. 마찬가지로, Class리터럴은 Class클래스의 인스턴스(객체)를 표기하기 위해 사용되는 것입니다.

💡Class 클래스
Class클래스는 java.lang 패키지에 정의되어 있으며, 자바에서는 프로그램의 클래스와 인터페이스를 관리하는데에 사용된다. enum은 클래스의 일종이며, annotation은 인터페이스의 일종이다. 예제 블로그(https://devyongsik.tistory.com/292)

 

 

under score(_) & numeric literals

자바 7 이후부터 _기호를 통해 숫자의 자릿수를 표현할 수 있게 되었습니다. 가독성을 증가시키기 위해 사람들이 사용하던 ,기호 대신 _기호를 사용하는 것이죠.

long creditCardNumber = 1234_5678_9012_3456L;
float pi = 3.14_15F;
long maxLong = 0x7fff_ffff_ffff_ffff;

 

 

 

원시형 Primitive type

  • byte, short, int, long, float, double, char

자바에서 원시형 primitive type은 사전에 정의된 자료형을 이야기한다. 이 타입은 값이 할당되면 JVM의 Runtime Data Area의 Stack영역에 값이 저장됩니다. 값이 다른 변수에 복사되면, 새롭게 값을 할당받은 변수에서 변경하더라도 원래 있던 값이 변경되지 않는다. 

 

public static void main(String[] args) {
	int i = 15;
	char c = 'a';
}

위의 코드는 i, c 두가지 변수를 통해 값을 저장하고 있습니다. primitive type은 메모리 상 변수에 직접 값이 들어가는 형태로 이루어져있다. 변수 i의 메모리 주소는 300, c의 주소는 604이며, 여기서 메모리주소 300에는 15라는 상수값이, 604에는 'a'가 직접 들어가게 됩니다.

 

💡변수를 지정할때 주로 int타입으로 이용하는 이유
하드웨어(CPU)에서 연산을 수행할 때, 효율적인 연산을 위해 모든 정수형 피연산자를 int타입으로 변환하는 과정을 거친다. 따라서, 메모리 공간 효율이 매우 중요한 상황이 아니라면 int타입을 사용하며, 그래픽스와 같은 경우엔 short을 사용한다.
출처(https://stackoverflow.com/questions/27122610/why-does-the-java-api-use-int-instead-of-short-or-byte)

 

참조형 Reference Type

reference타입(참조형)은 객체와 같은 복합적인 값을 지니는 데이터 타입을 말합니다. 대표적으로 String타입은 reference type입니다.

참조형 변수는 값이 할당되면 참조값이 할당되는데, 이 참조값은 JVM의 Runtime Data Area의 Heap 영역에 위치한 객체의 주소이다. 즉, 참조형 변수는 Heap 영역에 위치한 객체의 위치를 저장한다.

public static void main(String[] args) {
	String s = "Hello World";
}

위의 코드를 통해 변수 s는 메모리 어딘가에 할당됩니다. 그와 동시에, "Hello World"라는 string값은 메모리 어딘가에 할당됩니다. 변수 s의 메모리 값은 "Hello World"가 할당된 메모리의 주소를 지닌다. 이는 C/C++의 포인터와 같은 개념이죠. 변수는 string값의 주소를 지니며, 변수는 값을 참조(reference)합니다.

 

Primitive vs Reference

int i1 = 5;
int i2 = i1;

String s1 = "hello"; // 4420 메모리주소를 가리킴
String s2 = s1; // 4420 메모리주소를 가리킴

i1과 i2변수는 5라는 값을 각자 지닙니다. 반면, s1,s2변수는 같은 값을 참조하고 있습니다.

4420에 위치한 문자열이 다른 문자열로 변경된다면 s1,s2변수가 참조하고 있는 값 또한 바뀌는것과 같습니다.

 

 

Primitive vs Wrapper class

  • primitive자료형에 대응되는 wrapper클래스가 존재한다. ie. int→Integer
  • wrapper클래스 사용 시 primitive와 달리 Null을 통한 데이터 검증이 가능하다.
  • 탐색, 정렬 등과 같은 기능을 제공하는 Java Collection Framework(리스트, 큐)는 객체를 다루기때문에 primitive자료형을 사용할 수 없다.

 

 

반응형