개발/Java

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

Debin 2022. 5. 12.
반응형

백기선님이 과거에 진행했던 Java 스터디 2주차 스터디 입니다.

프리미티브 타입 종류와 값의 범위 그리고 기본 값

프리미티브 타입을 기본형이라고 부르겠다. 자바에는 총 8가지의 기본형이 있다.

우선 기본형은 NULL을 가질 수 없다. 만약 NULL을 쓴다면 Wrapper 클래스를 사용해야 한다.

기본형 변수는 메모리에서 스택 영역에 저장된다.

기본형 분류, 타입 메모리 크기, 기본 값, 범위에 대해 아래와 같이 정리했다.

분류 타입 메모리 크기 기본 값  범위
논리형 boolean 1 byte false false, true
문지형 char 2 byte '\u000' '\u0000' ~ '\uffff'
정수형 byte 1byte 0 -128 ~ 127
short 2byte 0 -32,768 ~ 32,767
int 4byte 0 -2,147,483,648 ~
  2,147,483,647
long 8byte 0L -9,223,372,036,854,775,808 ~
  9,223,372,036,854,775,807
실수형 float 4byte 0.0F 1.4E-45 ~ 3,4E38
double 8byte 0.0 or 0.0D 4.9E-324 ~ 1.8E308

레퍼런스 타입

레퍼런스 타입은 참조형이라고 부르겠다. 먼저 자바에는 기본형 타입이 8가지가 있다. 이 8가지를 제외하면 모두 참조형 타입이다.

참조형 변수는 힙 영역에 저장된다.

  • 기본형 변수 : 변수 자체가 데이터 값을 가지고 있다. 초기화하지 않으면 기본 값이 할당된다.
  • 참조형 변수 : 참조형 변수가 인스턴스가 저장된 주소 값을 가지고 있다. 기본형과 달리 Null값을 할당할 수 있다. 

여기서 한 가지 생각이 정리 되었다. 평소에 toString()을 참조형 변수에서 사용하면 주소 값이 나왔다.

참조형 변수의 실제 인스턴스는 힙 영역에 저장되는데, 힙 영역에 있는 인스턴스의 주소 값을 스택 영역에 저장한 것이다.

그래서 참조형 변수에서 toString을 사용하면 인스턴스의 주소 값이 나온 것이 아닌가 조심스럽게 생각해본다.

그렇다면 이 스택 영역에 저장된 주소 값을 포인터 같은 역할이라고 이해하면 되겠다.

(주소는 4byte 크기다.)

리터럴

리터럴에 관해서는 과거에 아래 포스팅에 정리해 놓았다.

https://devdebin.tistory.com/91?category=1004578 

 

변수와 리터럴

자바의 정석을 학습하면서 본인이 중요하다고 생각하는 부분을 정리해보겠습니다. 변수란 무엇인가? 변수란, 단 하나의 값을 저장할 수 있는 메모리 공간이다. 변수를 선언하면, 메모리의 빈 공

devdebin.tistory.com

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

우선 변수란 무엇인가?

변수는 프로그래밍 언어에서 단 하나의 값을 저장할 수 있는 메모리 공간이다.

하나의 변수에는 하나의 값만 저장할 수 있으므로, 새로운 값을 저장하면 기존의 값은 사라진다.

이제 변수를 사용하려고 한다. 그러면 제일 먼저 진행할 것은 변수 선언이다. 변수 선언 방법을 알아보자.

//변수 타입과 변수 이름을 선언
int num;
  • int : 변수 타입을 지정한다. 저장하고자 하는 값의 종류에 맞게 변수의 타입을 선택해서 적는다.
  • num : 변수 이름을 정해준다. 메모리 공간에 이름을 붙여주는 것이다.

이렇게 변수를 선언하면, 메모리의 빈 공간에 변수 타입에 알맞은 크기의 저장 공간이 확보되고 (int형이므로 4byte),

앞으로 이 저장 공간을 변수 이름을 통해 사용할 수 있다.

 

다음은 변수 초기화다. 

변수를 선언한 이후부터는 변수를 사용할 수 있으나, 그 전에 반드시 변수를 초기화해야 한다.

메모리는 여러 프로그램이 공유하는 자원이므로 전에 다른 프로그램에 의해 저장된 쓰레기 값이 남아있을 수 있기 때문이다.

즉 변수 초기화란, 변수를 사용하기 전에 처음으로 값을 지정하는 것이다.

int a; //변수 선언
a = 10; //초기화

int age = 20 //변수 선언과 초기화를 한 번에

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

일단 자바에서 크게 변수는 3가지가 있다.

class Variables{
	int iv; //인스턴스 변수
    static int cv; //클래스 변수, static 변수
    
    void method(){
    
    	int lv=0; //지역 변수
    }
}

인스턴스 변수, 클래스 변수, 지역 변수다. 클래스 변수, 인스턴스 변수, 배열의 초기화는 선택적이지만, 지역 변수의 초기화는 필수적이다.

클래스 변수와 인스턴스 변수를 합쳐서 멤버 변수라고 부르기도 한다. 이제 변수들의 스코프와 라이프타임에 대해 알아보자.

변수 선언 위치 스코프 라이프 타임 특징
클래스 변수 클래스 영역 코드 전체에서 사용 가능 생성 시기 :
프로그램이 동작할 때
소멸 시기 : 
프로그램이 종료될 때
클래스가 메모리에 올라가면  static(메소드) 영역에 생성된다.
인스턴스 변수 private :
클래스 내부 메서드에서 사용 가능
public :
코드 전체에서 사용 가능
(인스턴스가 존재한다는 가정)
생성 시기 : 
인스턴스가 생성될 때
소멸 시기 :
GC에 의해 인스턴스가
메모리에서 소멸할 때까지
힙 영역에 생성된다.
지역 변수 클래스 영역 
이외의 블럭
선언된 블록 내부 생성 시기 : 
메소드에서
변수 선언이 진행되었을 때
소멸 시기 : 
메소드 종료 시 메모리에서 소멸
stack 메모리에 생성된다.
초기화가 필수다.

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

  • 변수 또는 상수의 타입을 다른 타입으로 변환하는 것이 타입 변환이다.
  • 타입 변환에는 크게 명시적 형변환(캐스팅)과 묵시적 형변환(타입 프로모션)이 있다.

명시적 형변환(캐스팅)

  • 명시적 형변환은 형변환하고자 하는 타입을 괄호와 함께 붙여주면 된다.
  • 기본형은 boolean을 제외하고는 서로 캐스팅이 가능하다.
double = d = 85.4;
int score = (int) d; //85

//(타입)피연산자

묵시적 형변환(타입 프로모션)

  • 서로 다른 타입의 변수간의 연산은 캐스팅을 하는 것이 원칙이지만, 값의 범위가 작은 타입에서 큰타입으로의 캐스팅은 생략할 수 있다.
  • byte(1byte) -> short(2byte) -> int(4byte) -> long(8byte) -> float(4byte) -> double(8byte)
int a = 100;
float b = a;         
System.out.println(b); //100.0
 
// int에서 float 자동 형변환

1차 및 2차 배열 선언하기

1차 배열 선언

int[] arr = new int [5]{1, 2, 3, 4, 5}; //초기화

int[] arr2 = new int[4]; //선언

2차 배열 선언

int[][] arr = new int [2][2]{{1,2}, {3,4}}; //초기화

int[][] score = new int[4][3]; //선언

다음은 score 2차원의 배열의 인덱스 구조다.

score[0][0] score[0][1] score[0][2]
score[1][0] score[1][1] score[1][2]
score[2][0] score[2][1] score[2][2]
score[3][0] score[3][1] score[3][2]

타입 추론, var

  • 타입 추론이란 코드를 작성할 때 개발자가 변수의 타입을 명시적으로 적지 않고, 컴파일러가 리터럴을 통해 타입을 추론하는 것이다.
  • Java 10에서 도입된 var는 변수를 선언할 때 타입을 생략할 수 있으며, 컴파일러가 타입을 추론한다.
  • var는 지역 변수를 선언할 때만 사용할 수 있습니다. 클래스의 멤버 변수를 선언할 때 사용할 수 없다.
  • 초기화를 하지 않으면 어떤 타입인지 추론할 수 없기 때문에 컴파일 에러가 발생합니다. 즉 초기화가 필수다.
  • null로 초기화할 수 없고, 배열에 사용할 수 없고, 람다식에도 사용할 수 없다.
  • 아래와 같은 코드를 작동하면 if 문의 System.out.println이 잘 작동한다.
public class Hello {
public static void main(String[] args){
        var str = "Hello, World";
	if (str instanceof String) System.out.println("This is a String: " + str);
        }
}

 

 

피드백은 언제나 환영입니다! 이상으로 포스팅을 마칩니다. 

 

참고 자료

자바의 정석 (저자 : 남궁성)

https://codechacha.com/ko/java-local-variable-type-inference/

반응형

댓글