1. 프리미티브 타입 종류, 범위, 기본 값
프리미티브 타입(Primitive Type)은 자바의 기본적인 데이터 타입임
1.1. 타입 종류와 타입 범위
1.2. 문자형
1.2.1. char
모든 문자를 저장할 때 사용하는 타입
정확히는 모든 유니코드(전 세계의 문자를 일관되게 표현할 수 있도록 설계된 표준)를 저장할 수 있음
public class UnicodeExample {
public static void main(String[] args) {
// 유니코드 코드 포인트를 사용하여 문자 할당
char unicodeChar = '\u44032'; // '가'의 유니코드 코드 포인트
System.out.println("유니코드 문자: " + unicodeChar); // 출력: 가
// 직접 문자 할당
char letter = '가';
System.out.println("문자: " + letterA); // 출력: 가
}
}
1.3. 정수형
1.3.1. byte
만약 변수에 저장 가능한 값의 범위를 넘는 값을 저장한다면?
byte a = 128;
위와 같이 byte 타입의 변수 a에 -128~127 을 넘는 값인 128을 저장한다면, 컴파일 에러가 발생함
byte 타입의 변수 a에 있는 값이 동적으로 변경되다가, 저장 가능한 값을 초과한다면?
127에서 -128로 넘어감
1.3.2. short
2바이트로 표현되는 정수를 저장하기 위해 사용되는 데이터 타입
왜 존재할까?
보통 임베디드 코드를 짜거나 low 레벨의 작업을 할 때 사용한다고 함
1.3.3. int
자바에서 "연산"을 하기 위해 만든 타입
정수를 담을 수 있는 타입은 short와 byte도 있음
그러나 short + int 또는 short + short 등의 연산을 하면, int 타입으로 자동 형변환되어 연산이 수행됨
public class JavaTest {
public static void main(String[] args) {
short a = 2;
short b = 3;
System.out.println(((Object)(a + b)).getClass().getName()); // 출력: java.lang.Integer
}
}
1.3.4. long
기본적으로 자바는 정수를 int로 취급하기에, long 타입에 값을 넣을 때는 정수 끝에 접미사로 'l' 또는 'L'을 붙여줌
long val = 999999999999L;
붙이지 않으면 컴파일 에러가 발생함
1.4. 실수형
1.4.1. float과 double
기본적으로 자바는 실수를 double로 취급하기에, 실수 끝에 접미사로 'f'를 붙여줌
float val = 3.14f;
붙이지 않으면 컴파일 에러가 발생함
1.5. 논리형
1.5.1. boolean
진실 혹은 거짓..
2. 프리미티브 타입과 레퍼런스 타입
자바의 데이터 타입은 기본형인 프리미티브 타입(Primitive Type)과 참조형인 레퍼런스 타입(Reference Type)으로 나뉨
기본형은 실제 값을 저장하고,
참조형은 객체의 주소를 저장한다. 기본적으로 Java.lang.Object를 상속받은 경우 참조형이 됨
public class TypeTest {
public static void main(String[] args) {
int i = 1111;
int j = 1004;
Integer var1 = 1111;
Integer var2 = 1004;
}
}
기본형은 스택 영역에 실제 값이 저장되고,
참조형은 실제 인스턴스는 힙 영역에 생성되고, 그 영역의 주소를 스택 영역에서 저장하고 있음
비교할 때는 기본형은 실제 값을 비교, 참조형은 주소 값을 비교함
3. 리터럴
3.1. 리터럴의 개념
리터럴은 데이터 그 자체를 의미함
2020, 123, 3.14, "ABC"와 같은 값들을 리터럴이라고 함
본래 이러한 값들을 상수라 불러야하지만, 프로그래밍에서는 상수를 '값을 한 번 저장하면 변경할 수 없는 저장공간'으로 정의했기에 이와 구분하기 위해 리터럴이라는 용어를 사용함
인스턴스는 리터럴이 될 수 있을까?
인스턴스 안의 값이 불변성이 보장되면 객체 리터럴이 될 수 있음
하지만 보통의 인스턴스는 동적으로 사용되고 내용이 변할 수 있기에 객체 리터럴이 될 수 없음
Java.lang.String 과 같은 클래스는 값이 변하는 상황이면 새로운 객체를 만들어 내용의 불변성이 보장되기에
아래와 같은 경우 ssoyeong은 문자열 리터럴이라 할 수 있음
String var1 = "ssoyeong";
3.2. 리터럴과 String 객체
자바에서 문자열을 생성하는 방법은 2가지가 있음
3.2.1. 문자열 리터럴 사용
public class Main {
public static void main(String[] args) {
String strLiteral1 = "TEST"; // 1번 과정
String strLiteral2 = "TEST"; // 2번 과정
String strLiteral3 = "Java"; // 3번 과정
}
}
생성 과정
(1) String pool에 "TEST"가 생성됨
(2) JVM이 String pool에 "TEST"가 이미 존재하므로 strLiteral2는 1번 과정에서 생성된 "TEST"를 참조함
(2) String Pool에 "Java"가 생성됨
3.2.2. new String() 사용
public class Main {
public static void main(String[] args) {
String strObject1 = new String("TEST"); // 1번 과정
String strObject2 = new String("Java"); // 2번 과정
String strObject3 = new String("TEST"); // 3번 과정
}
}
생성 과정
(1) Java Heap에 "TEST"가 생성됨
(2) Java Heap에 "Java"가 생성됨
(3) Java Heap에 "TEST"가 생성됨
String pool이 아닌 Java Heap 영역에 생성됨
동일한 문자열이라도 기존의 문자열을 참조하지 않고 새로 생성됨
String Pool이란?
Java Heap의 저장 영역
JVM은 과도한 String 개체 수를 줄이고자 문자열 리터럴이 생성될 때마다 String pool을 체크함
4. 변수 선언 및 초기화 방법
4.1. 변수 선언
int year;
변수: 값을 저장할 수 있는 메모리 공간
변수 타입: 변수에 저장될 값이 어떤 타입인지 지정
변수 이름: 메모리 공간에 붙이는 이름
4.2. 변수 초기화
변수를 사용하기 전 처음으로 값을 저장하는 것
변수는 크게 전역(멤버) 변수와 지역 변수로 나뉨
전역 변수는 클래스에 선언한 변수, 지역 변수는 메소드 안에서 선언한 변수
지역 변수는 사용하기 전 반드시 초기화해야 함
4.2.1. 명시적 초기화
변수 선언과 동시에 초기화하는 것
int var = 10;
4.2.2. 블록 초기화
일반적인 초기화 블록: Class가 new를 통해 인스턴스를 생성되는 순간 초기화됨
정적 초기화 블록: JVM이 클래스 로더로 클래스를 메모리에 로딩하는 시점에 초기화됨
4.2.3. 생성자
인스턴스 생성 시 생성자 함수 안에서 명시적 초기화가 이루어짐
5. 타입 변환, 캐스팅, 타입 프로모션
자바에서 타입을 변환하는 데는 '프로모션'과 '캐스팅' 방식이 있음
5.1. 프로모션, Widening Conversion
원래 타입보다 더 큰 타입으로 변경할 때 자동 형변환되는 것을 의미
4바이트 int를 8바이트 long으로 변경하는 경우
int i = 0;
long l = i;
5.2. 캐스팅, Narrow Conversion
원래 타입보다 더 작은 타입으로 변경할 때 캐스팅을 사용해야 함
long l = 123;
int i = (int) l;
형변환을 통해 크기의 차이만큼 loss of data가 발생할 수 있음
6. 배열
동일한 데이터 타입을 가지는 여러 값을 저장할 수 있는 자료구조, 객체임
고정된 크기로 선언되며, 한 번 생성된 배열의 크기는 변경할 수 없음
배열을 재선언하면 새로운 배열 객체가 생성되어 그에 대한 참조가 변수에 할당되는 것
자바에서 배열은 java.lang.Object 클래스를 상속 받고 Cloneable 인터페이스를 구현함
Cloneable 인터페이스는 객체 자신의 메모리를 복사하는 메소드를 제공하는 Object 클래스의 인터페이스임
이를 통해 배열은 clone() 메소드를 사용해 배열을 복제할 수 있음
int[] arr = {1, 2, 3, 4, 5};
int[] arrClone = arr.clone(); // 배열 복제
System.out.println(Arrays.toString(arr)); // 기존 배열 출력
System.out.println(Arrays.toString(arrClone)); // 복제된 배열 출력
7. 타입 추론, var
7.1. 타입 추론
타입 추론은 개발자가 변수의 타입을 명시적으로 적어주지 않고도, 컴파일러가 알아서 해당 변수의 타입을 대입된 리터럴로 추론하는 것
제네릭(Generics)은 자바의 기능 중 하나로, 다양한 타입의 객체를 다룰 수 있도록 타입 추론을 지원해 타입을 매개변수화할 수 있도록 해줌
이를 통해 코드의 재사용성과 타입 안정성을 높일 수 있음
public class Box<T> {
private T value;
public void setValue(T value) {
this.value = value;
}
public T getValue() {
return value;
}
}
public class Main {
public static void main(String[] args) {
Box<Integer> intBox = new Box<>();
intBox.setValue(10);
int value = intBox.getValue(); // 형변환 불필요
Box<String> strBox = new Box<>();
strBox.setValue("Hello");
String strValue = strBox.getValue(); // 형변환 불필요
}
}
7.2. var
Local Variable Type Inference 는 Java 10부터 추가된 기능으로,
var를 사용해 초기화 값이 있는 지역 변수의 타입을 추론할 수 있음
var number = 10; // int로 타입 추론됨
var text = "Hello"; // String으로 타입 추론됨
// 배열도 가능
var numbers = new int[]{1, 2, 3}; // int[]로 타입 추론됨
// 컬렉션도 가능
var list = new ArrayList<String>(); // ArrayList<String>으로 타입 추론됨
var numbers = Arrays.asList(1, 2, 3, 4, 5);
for (var number : numbers) {
System.out.println(number);
}
참고자료
[Java-6] Java 기본 타입 (primitive)
자 이제 자바의 데이터 타입과 변수 및 배열에 대해서 설명하는 시간을 가져보도록 하자. 프리미티브 타입이란걸 알아 보기전에 타입은 알겠는데, 프리미티브는 뭘까 할 수 있다. 1. 타입은 알겠
catch-me-java.tistory.com
[2주차] 자바 데이터 타입, 변수 그리고 배열
목차
catsbi.oopy.io
[Java]String 리터럴(Literal), String 객체(Object)
Java에서 문자열을 생성하는 과정은 2가지 방법이 있습니다. 1. 문자열 리터럴(Literal)을 사용 public class Main { public static void main(String[] args) { String strLiteral1 = "TEST"; String strLiteral3 = "TEST"; String strLitera
developer-talk.tistory.com
'Computer Science' 카테고리의 다른 글
[Network] 1. 웹 브라우저가 요청 메시지를 만드는 방법 (0) | 2023.10.16 |
---|---|
[Database] 6. 인덱스 (0) | 2023.10.01 |
[Database] 5. 트랜잭션의 격리 수준과 락 (0) | 2023.09.30 |
[Database] 4. 트랜잭션과 무결성 (0) | 2023.09.12 |
[Java] 1. JVM과 자바 코드 실행 과정 (0) | 2023.09.09 |