자바 데이터 타입, 변수, 배열

smj_716·2025년 1월 16일

Java-study / live-study

목록 보기
2/16

1. primitive 타입 종류와 값의 범위 그리고 기본 값

➡️ primitive Type이란?

  • 기본 자료형 혹은 원시 자료형이라고 불리는 프리미티브 타입은 값을 할당할 때 변수의 주소 값에 그 자체로 저장되는 데이터 타입이다.
  • 해당 데이터 타입은 값이 할당되면 앞서 다루었던 JVM의 Runtime Data Area 영역 중 Stack영역에 값이 저장된다.

👉 프리미티브 타입 종류


2. 프리미티브 타입과 레퍼런스 타입

➡️ Reference Type이란?

  • 참조자료형이라 불리는 레퍼런스 타입의 종류는 무한하다.
  • 프리미티브 타입과 달리 JVM의 Runtime Data Area 영역 중 Heap 영역에 할당되는데, 레퍼런스 타입의 변수 주소값에는 값이 아닌 Heap 영역에 할당된 주소가 저장된다.
public static void main(String args[]){
    Car car = new Car(vendor:"kia", price: 100);
}

예를 들어, 위와 같이 Car를 인스턴스화 시키면 Heap영역에 vendor가 "kia"이고 price가 100인 객체가 생성되고 car 변수는 단순히 어떠한 값을 저장하고 있는 것이 아니라 Heap영역에 저장된 객체의 주소가 저장된다.


3. 리터럴

리터럴은 변수나 상수에 저장되는 값 그 자체를 의미한다.

int a = 10 에서 10이 바로 리터럴이다.
즉, 123, 3.14, "ABC"와 같은 값들을 리터럴이라고 하는데 본래 이러한 값들은 상수라 부르지만 프로그래밍에서는 상수를 "값을 한 번 저장하면 변경할 수 없는 저장공간"으로 정의했기 때문에 이와 구분하기 위해 리터럴이라는 용여를 사용한다.

  • 정수 리터럴 : 10진법부터 2진법, 8진법 등이 있음
  • 실수 리터럴 : 기본적으로 double타입이고, float타입으로 하려면 f를 명시적으로 붙여야함
  • boolean 리터럴 : true, flase로 표현
  • 문자 리터럴 : ''안에 표현
  • 문자열 리터럴 : ""안에 표현
    🌟 다른 리터럴은 프리미티브 타입의 값을 표현하기 위해 존재하지만 String은 레퍼런스 타입이다. 그럼에도 String타입은 리터럴을 지원하는데, 리터럴 방식으로 String에 값을 주면 Heap영역에서 String constant pool이라는 특수한 영역에 값이 저장된다. 그리고 동일한 값을 쓰는 경우에 다른 일반적인 레퍼런스 타입처럼 Heap 에 또 올라가지 않고, String constant pool에 존재하는 값을 참조하는 방식으로 작동한다.
String str = "hello"; // String constant pool에 저장
String str2 = "hello"; // String constant pool에서 재사용
String str3 = new ("hello"); // 별도의 Heap 메모리에 저장

System.out.println(str == str2);	// true (같은 객체를 재사용하기 때문에)
System.out.println(str == str3);	// false
System.out.println(str.equals(str3));	// true

4. 변수 선언 및 초기화하는 방법

❓ Declaration

  • 변수를 선언한다는 것은 저장공간을 확보하겠다는 의미로 해석할 수 있다.
  • int a : int 타입의 값을 저장할 수 있는 공간을 확보했고(4byte) 그 공간을 지칭할 이름은 a 라는 의미이다.

❓ Initialization?

  • 변수를 초기화한다는 것은 저장공간에 원하는 값을 저장하는 것을 의미한다.
  • 변수를 선언하면 해당 공간에는 쓰레기값이 들어가있는데 그 상태에서 컴파일을 시도하면 Error:(10, 28) java: variable a might not have been initialized와 같은 컴파일 에러코드가 나온다. 그러므로 변수는 선언 후에 꼭 초기화를 해야한다!!

5. 변수의 스코프와 라이프타임

스코프는 해당 변수를 사용할 수 있는 영역 범위이고, 라이프타임은 해당 변수가 언제까지 메모리에 살아있는지 의미한다.

public class scope_and_lifetime {
    int num1, num2;   		//Instance Variables
    static int result;  	//Class Variable
    int add(int a, int b){  	//Local Variables
        num1 = a;
        num2 = b;
        return a+b;
    }
}

👉 인스턴스 변수
클래스 안에서 선언되어있고, 어떠한 method나 block안에서 선언되지 않은 변수

  • scope - static method를 제외한 클래스 전체
  • lifetime - 클래스를 인스턴스화한 객체가 메모리에서 사라질 때 까지

👉 클래스 변수
클래스 안에서 선언되어있고, 어떠한 메서드나 블럭안에서 선언되지 않았으며 static 키워드가 포함되어 선언된 변수
클래스 변수는 항상 인스턴스 변수보다 먼저 생성 및 초기화됨

  • scope - 클래스 전체
  • lifetime - 프로그램 종료시 까지

👉 지역변수
인스턴스 변수, 클래스 변수가 아닌 모든 변수

  • scope - 변수가 선언된 block 내부
  • lifetime - control 이 변수가 선언된 block 내부에 있는 동안

6. 타입 변환, 캐스팅 그리고 타입 프로모션

1) 타입 변환

변수 또는 상수의 타입을 다른 타입으로 변환하는 것을 의미한다.

  • 형변환 방법 :
    변환할 변수나 리터럴 앞에 타입을 괄호하여 함께 지정
    형변환 연산자는 피연산자의 값을 읽어 지정된 타입으로 변환하며, 기존 변수나 리터럴은 변화하지 않는다.
double value = 123.456;
int score = (int)value;
System.out.println(value == 123.456); // true

위 코드에서 value는 변환되지 않고, 변환된 결과값만 사용한다.

  • 기본형간의 형변환 (명시적 형변환) :
    boolean을 제외한 나머지 기본형은 서로 형변환이 가능하다.
    타입 간 크기(범위)의 차이로 인해 값 손실(Data Loss)이 발생할 수 있다.
byte b = (byte)10000; // byte의 표현 범위는 -128 ~ 127
System.out.println(b); // 출력: 16
  • 자동 형변환
    특정 상황에서는 형변환을 생략할 수 있으며, 컴파일러가 이를 자동으로 처리한다.
    표현 범위가 좁은 타입에서 넓은 타입으로 변환된다.
byte a = 10;
int b = a; // 자동 형변환
System.out.println(b); // 출력: 10

2) 타입 캐스팅 - 명시적 형변환

더 큰 크기의 자료형을 더 작은 크기의 자료형으로 변환하는 것을 의미한다. 이 경우 데이터 손실이나 변형이 발생할 수 있다.

3) 타입 프로모션 - 자동 형변환

더 작은 크기의 자료형을 더 큰 크기의 자료형으로 변환하는 것을 의미한다. 데이터 손실이나 변형이 발생하지 않으므로, 명시적인 형변환 없이 자동으로 변환된다.

4) 레퍼런스 타입에서의 변환

기본형과 달리 크기 개념보다는 상속 관계에 따라 자동 변한(업캐스팅)과 명시적변환(다운 캐스팅)으로 나뉜다.

  • 업 캐스팅 : 자식 클래스의 객체를 부모 클래스 타입으로 변환
class Parent {}
class Child extends Parent {}

Child child = new Child();
Parent parent = child; // 자동 형변환

💡 생각해보면 자식클래스는 부모클래스의 필드나 메소드를 물려받기 때문에 자식 클래스 타입의 객체를 부모 클래스 타입으로 바꾼다고해서 데이터의 손실이나 변형이 일어나지 않는 것은 당연하다.

  • 다운 캐스팅 : 부모 클래스의 객체를 자식 클래스 타입으로 변환
Parent parent = new Child();
Child child = (Child)parent; // 명시적 형변환

7. 1차 및 2차 배열 선언하기

1) 배열 선언
int[] arr1; / int arr2[]; 처럼 변수명 앞이나 뒤에[]를 붙여 선언

2) 배열 생성

  • int[] arr = new int[3] / arr[0] = 1; arr[1] = 5 처럼 배열은 new 연산자를 사용하여 생성하며, 배열의 타입과 길이를 지정하면 메모리에 해당 길이만큼 영역이 확보
  • 배열의 길이는 최초 생성 시 정적으로 설정되며, 길이를 변경하려면 새로운 배열을 생성해야함‼️
  • int arr[] = {1,2,3,4} 선언과 초기화 동시 가능

8. 타입 추론, var

타입 추론이란 데이터 타입을 소스코드에 명시하지 않아도, 컴파일 단계에서 컴파일러가 타입을 유추해 정해주는 것이다.

뒤에서 다룰 1.5버전 부터 추가된 Generic이나 자바 8 버전에서 추가된 lamda에서 타입추론이 사용된다. 자바 10에서는 이러한 타입추론을 사용하는 var 이라는 Local Variable Type-Inference 가 추가되었다.

var a = "hello";	// String a = "hello";
var b = 10;		// int b = 10;

0개의 댓글