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

이기영·2024년 5월 24일

Java 기초학습

목록 보기
2/14
post-thumbnail

목표

자바의 프리미티브 타입, 변수 그리고 배열을 사용하는 방법을익힙니다.

목차

1. 프리미티브 타입 종류와 값의 범위 그리고 기본 값
2. 프리미티브 타입과 레퍼런스 타입
3. 리터럴
4. 변수 선언 및 초기화하는 방법
5. 변수의 스코프와 라이프타임
6. 타입 변환, 캐스팅 그리고 타입 프로모션
7. 1차 및 2차 배열 선언하기
8. 타입 추론, var


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

Primitive Type 요약

  primitive type은 자바의 기본 타입들이라고 할 수 있습니다. 총 8개로 이루어져있으며, 자바에서는 필드 선언시 초기화를 하지 않으면, 기본값으로 초기화 됩니다.

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

프리미티브 타입의 종류

정수형 : byte, short, int, long
실수형 : float, double
문자형 : char
논리형 : Boolean


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

Reference Type?

  Reference Type은 Primitive Type을 제외한 모든 타입을 포함합니다. 참조값을 통해 관리하기 때문에 Reference Type이라고 불리며, Null을 사용할 수 있습니다.

  또한 Reference Type은 변수 선언시 변수에 값이 저장되는 것이 아니라 객체에 대한 힙 영역의 참조를 저장하게 됩니다. 즉, 프리미티브 타입과 다르게 변수의 주소가 아닌, heap영역에 할당된 주소가 저장됩니다.


※ WrapperClass

Primitive Type을 인스턴스로 다룰 수 있게끔 도와주는 것들을 말합니다. 값을 조작하기 위해 작성된 UtilMethod를 사용하기 위해서 이용하는 경우도 많습니다.

// 대응 클래스
// 가장 앞 문자를 대문자로 사용하면 됩니다.
byte -> Byte      char -> Character
short -> Short    float -> Float
int -> Integer    double -> Double
long -> Long      boolean -> Boolean

// 선언 예시
Integer num = new Integer(10);

3. 리터럴

 리터럴(literal)은 프로그래밍에서 변수에 저장되는 값을 나타내는 구체적인 표기입니다. 즉, 코드에서 고정된 값으로 직접 작성되는 데이터를 말합니다. 리터럴은 여러가지 유형이 있으며, 각 유형은 특정한 데이터 타입을 나타냅니다.

// ex) 정수
`10`, `-5` ...

// 실수(float)
`3.14`, `-0.001`, ..

이 외에도 list([ ]), tuple(( )), set({ }),
dictionary({'key': 'value'}), None, boolean 등이 있습니다.

참고로 특수문자 리터럴도 존재합니다.(\t, \n, \r 등등)

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

Declaration / Initialization

  • Declaration
    변수를 선언한다는 것은, 저장공간을 확보하겠다는 의미라고 볼 수 있습니다.
  • Initialization
    변수를 초기화 한다는 것은, 저장공간에 원하는 값을 저장하는 것을 의미합니다.
// Declaration
int a;

// Initialization
a = 10;

  위 코드의 Declaration을 보면 int 타입의 a 라는 이름으로 4byte(int는 4byte)를 확보했다고 볼 수 있겠습니다. 이어서 Initialization을 보면, a 이름에 10이라는 값을 할당해 주었다는 것을 알 수 있습니다.


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

여기서 scope는 변수의 유효범위를 뜻하고, lifetime은 존재 기간을 의미합니다.

스코프(Scope)

1) 클래스 스코프(Class Scope)

  • 클래스 내에서 선언된 변수(필드)는 클래스 전체에서 접근 가능합니다.
  • 클래스 변수(static 변수)는 클래스의 모든 인스턴스에서 공유됩니다.
  • 인스턴스 변수(non-static 변수)는 각 인스턴스마다 개별적으로 존재합니다.
public class MyClass {
    // 클래스 변수 (static)
    static int staticVar;
    
    // 인스턴스 변수 (non-static)
    int instanceVar;
    
    public void myMethod() {
        // 메서드 내부에서는 static 변수와 인스턴스 변수 모두 접근 가능
        staticVar = 10;
        instanceVar = 20;
    }
}

2) 메서드 스코프(Method Scope)

  • 메서드 내에서 선언된 변수는 메서드가 실행되는 동안에만 유효합니다.
  • 메서드가 종료되면 메서드 스코프 내의 변수는 더 이상 접근할 수 없습니다.
public void myMethod() {
    int localVar = 10; // 지역 변수
    // localVar은 myMethod 내에서만 접근 가능
}

3) 블록 스코프(Block Scope)

  • 중괄호 {} 로 둘러싸인 블록 내에서 선언된 변수는 해당 블록 내에서만 유효합니다.
  • 블론이 종료되면 블록 스코프 내의 변수는 더 이상 접근 할 수 없습니다.
public void myMethod() {
    if (true) {
        int blockVar = 10; // 블록 변수
        // blockVar은 if 블록 내에서만 접근 가능
    }
    // 여기서는 blockVar에 접근할 수 없음
}

라이프 타임(Lifetime)

  변수의 라이프타임은 변수가 메모리에 존재하는기간을 의미합니다. 변수의 스코프와 라이프타임은 종종 밀접하게 관련되어 있지만, 두 개념은 다릅니다.

1) 클래스 변수(static 변수)

  • 프로그램 시작 시 메모리에 할당되고, 프로그램 종료시 해제 됩니다.
  • 클래스 로더에 의해 클래스가 메모리에 로드될 때 생성되며, JVM이 종료될 때까지 유지됩니다.

2) 인스턴스 변수(non-static 변수)

  • 객체가 생성될 때 메모리에 할당되고, 객체가 Garbage Collection에 의해 소멸될 때 해제됩니다.
  • 객체가 메모리에 존재하는 동안 인스턴스 변수도 함께 존재합니다.

3) 지역 변수(Local Variable)

  • 메서드 또는 블록이 실행될 때 메모리에 할당되고, 메서드 또는 블록이 종료되면 해제됩니다.
  • 지역 변수는 스택 메모리에 저장되며, 메서드 호출이 끝나면 스택프레임과 함께 제거됩니다.

public class VariableScope {
    // 클래스 변수 (static)
    static int classVar = 10;
    
    // 인스턴스 변수 (non-static)
    int instanceVar = 20;

    public void method() {
        // 지역 변수 (local)
        int localVar = 30;
        
        // 블록 내에서 선언된 블록 변수 (block scope)
        if (true) {
            int blockVar = 40;
            // 여기서는 classVar, instanceVar, localVar, blockVar 모두 접근 가능
        }
        // 여기서는 blockVar에 접근할 수 없음
    }
    
    public static void main(String[] args) {
        // main 메서드도 하나의 블록이므로, 
        // 여기서 선언된 변수는 이 블록 내에서만 유효
        VariableScope obj = new VariableScope();
        obj.method();
    }
}

  이 예제에서 classVar는 프로그램이 종료될 때까지 유효하며, instanceVar는 obj 객체가 가비지 컬렉션될 때까지 유효합니다. localVar는 method가 실행되는 동안에만 유효하고, blockVar는 if 블록 내에서만 유효합니다.



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

타입 변환(Type Conversion)

  타입 변환은 하나의 데이터 타입을 다른 데이터 타입으로 변환하는 과정입니다. 타입 변환은 암시적(자동) 또는 명시적(수동)으로 이루어질 수 있습니다.

1) 자동 타입 변환(Implicit Type Conversion, Widening Conversion)

  • 작은 크기의 데이터 타입이 큰 크기의 데이터 타입으로 자동으로 변환되는 것을 말합니다.
  • 데이터 손실이 발생하지 않으므로 안전한 변환입니다.
int intValue = 100;
long longValue = intValue;  // int가 long으로 자동 변환
double doubleValue = intValue;  // int가 double로 자동 변환

2) 명시적 타입 변환(Explicit Type Conversion, Narrowing Conversion)

  • 큰 크기의 데이터 타입 작은 크기의 데이터 타입으로 변환할 때 명시적으로 변환을 지정해야 합니다.
  • 데이터 손실이 발생할 수 있으므로 주의가 필요합니다.
int intValue = 100;
long longValue = intValue;  // int가 long으로 자동 변환
double doubleValue = intValue;  // int가 double로 자동 변환

캐스팅 (Casting)

캐스팅은 명시적 타입 변환의 한 형태로, 주로 참조 타입(객체) 사이의 변환을 가리킵니다. 캐스팅은 상속 관계에 있는 클래스 간에 이루어집니다.


1) 업케스팅 (Upcasting)

  • 서브 클래스 타입을 슈퍼 클래스 타입으로 변환합니다.
  • 암시적으로 이루어지며, 명시적인 캐스팅이 필요하지 않습니다.
class Animal { }
class Dog extends Animal { }

Animal animal = new Dog();  // 업캐스팅

2) 다운캐스팅 (Downcasting)

  • 슈퍼 클래스 타입 서브 클래스 타입으로 변환합니다.
  • 명시적인 캐스팅이 필요하며, 런타임에 'ClassCastException'이 발생할 수 있습니다.
Animal animal = new Dog();
Dog dog = (Dog) animal;  // 다운캐스팅

타입 프로모션 (Type Promotion)

 타입 프로모션은 표현식을 평가할 때 작은 데이터 타입의 피연산자가 큰 데이터 타입으로 자동 변환되는 과정입니다. 이는 주로 연산자와 함께 사용됩니다.

1) 정수형 타입 프로모션

  • byte, short, char 타입의 값이 int 타입으로 자동 프로모션됩니다.
  • 여러 피연산자가 있을 경우, 피연산자의 데이터 타입이 가장 큰 타입으로 프로모션 됩니다.
byte b = 42;
char c = 'a';
int i = b + c;  // b와 c가 int로 프로모션됨

2) 실수형 타입 프로모션

  • float 타입이 double 타입으로 자동 프로모션 됩니다.
float f = 3.14f;
double d = f + 2.0;  // f가 double로 프로모션됨

예재 코드

public class TypeConversionExample {

    public static void main(String[] args) {
        // 자동 타입 변환 (Widening)
        int intVal = 100;
        long longVal = intVal;  // int to long
        double doubleVal = intVal;  // int to double
        
        // 명시적 타입 변환 (Narrowing)
        double doubleNum = 9.78;
        int intNum = (int) doubleNum;  // double to int
        System.out.println("Converted double to int: " + intNum);

        // 업캐스팅
        Animal animal = new Dog();  // Upcasting
        animal.makeSound();  // Animal의 메서드를 호출

        // 다운캐스팅
        Dog dog = (Dog) animal;  // Downcasting
        dog.bark();  // Dog의 메서드를 호출

        // 타입 프로모션
        byte byteVal = 42;
        char charVal = 'a';
        int result = byteVal + charVal;  // byte와 char가 int로 프로모션됨
        System.out.println("Promoted result: " + result);

        float floatVal = 3.14f;
        double doubleResult = floatVal + 2.0;  // float가 double로 프로모션됨
        System.out.println("Promoted double result: " + doubleResult);
    }
}

class Animal {
    public void makeSound() {
        System.out.println("Animal makes a sound");
    }
}

class Dog extends Animal {
    public void bark() {
        System.out.println("Dog barks");
    }
}

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

1차원 배열

  1차원 배열은 단일 차원의 배열을 의미합니다. 배열은 동일한 데이터 타입의 요소를 저장하는 연속된 공간을 갖습니다.

1) 선언

array라는 이름의 정수형 배열

int[] array;

2) 배열생성 및 초기화

길이가 5인 정수 배열을 생성합니다. 배열 요소는 자동으로 기본값(정수의 경우 0)으로 초기화 됩니다.

array = new int[5]; // 길이가 5인 배열 생성

3) 선언과 동시에 초기화

int[] array = new int[5];

4) 선언과 동시에 값 할당

int[] array = {1, 2, 3, 4, 5}

2차원 배열

1) 배열 선언

int[][] matrix;

2) 배열 생성 및 초기화

matrix = new int[3][4]; // 3x4 배열 생성

이 구문은 3개의 행과 4개의 열을 갖는 2차원 배열을 생성합니다. 모든 요소는 기본값으로 초기화 됩니다.

3) 선언과 동시에 초기화

int[][] matrix = new int[3][4];

4) 선언과 동시에 값 할당

int[][] matrix = {
	{1, 2, 3, 4},
    {5, 6, 7, 8},
    {9, 10, 11, 12}
};

예제 코드

public class ArrayExample {

    public static void main(String[] args) {
        // 1차 배열 선언 및 초기화
        int[] oneDimArray = new int[5];  // 선언과 동시에 길이가 5인 배열 생성
        oneDimArray[0] = 1;
        oneDimArray[1] = 2;
        oneDimArray[2] = 3;
        oneDimArray[3] = 4;
        oneDimArray[4] = 5;

        // 1차 배열 선언과 값 할당
        int[] anotherOneDimArray = {1, 2, 3, 4, 5};

        // 2차 배열 선언 및 초기화
        int[][] twoDimArray = new int[3][4];  // 3x4 배열 생성
        twoDimArray[0][0] = 1;
        twoDimArray[0][1] = 2;
        twoDimArray[0][2] = 3;
        twoDimArray[0][3] = 4;
        twoDimArray[1][0] = 5;
        twoDimArray[1][1] = 6;
        twoDimArray[1][2] = 7;
        twoDimArray[1][3] = 8;
        twoDimArray[2][0] = 9;
        twoDimArray[2][1] = 10;
        twoDimArray[2][2] = 11;
        twoDimArray[2][3] = 12;

        // 2차 배열 선언과 값 할당
        int[][] anotherTwoDimArray = {
            {1, 2, 3, 4},
            {5, 6, 7, 8},
            {9, 10, 11, 12}
        };

        // 배열 요소 출력
        System.out.println("1차 배열 요소:");
        for (int i = 0; i < oneDimArray.length; i++) {
            System.out.print(oneDimArray[i] + " ");
        }

        System.out.println("\n\n2차 배열 요소:");
        for (int i = 0; i < twoDimArray.length; i++) {
            for (int j = 0; j < twoDimArray[i].length; j++) {
                System.out.print(twoDimArray[i][j] + " ");
            }
            System.out.println();
        }
    }
}

8. 타입 추론, var

  타입 추론과 'var'는 Java 10부터 도입된 기능으로, 코드를 간결하게 만들어주고 가독성을 향상시키는 데 도움을 줍니다.


타입 추론(Type Inference)

  타입 추론은 변수를 선언할 때 변수의 타입을 컴파일러가 자동으로 추론하여 할당하는 기능입니다. 이는 코드의 가독성을 향상시키고 타입 선언을 줄여줍니다.

// 타입 추론을 사용하지 않은 경우
Map<String, List<Integer>> myMap = new HashMap<String, List<Integer>>();

// 타입 추론을 사용한 경우
var myMap = new HashMap<String, List<Integer>>();

  컴파일러는 new HashMap<String, List<Integer>>()를 보고 HashMap<String, List<Integer>> 타입을 추론하고, myMap의 타입을 설정합니다.

var

  var 키워드는 변수의 타입을 컴파일러가 자동으로 추론하도록 지시합니다. 이를 통해 코드를 간결하게 만들 수 있습니다.

// 타입 추론을 사용한 경우
var number = 10;  // number의 타입은 int로 추론됨
var name = "John";  // name의 타입은 String으로 추론됨

var myList = new ArrayList<String>();  
// myList의 타입은 ArrayList<String>으로 추론됨

제한사항

  • var는 지역 변수에 대해서만 사용할 수 있습니다. 클래스 멤버 변수, 메서드의 매개변수, 반환값의 타입으로는 사용할 수 없습니다.
  • var로 선언된 변수는 반드시 초기값이 있어야 합니다. 초기값이 없는 경우 컴파일 에러가 발생합니다.
  • var로 선언된 변수의 타입은 컴파일 시점에 결정되며, 런타임 시에는 변하지 않습니다.

주의 사항

var를 남용하면 코드의 가독성을 떨어뜨릴 수 있으므로 적절하게 사용하는 것이 중요합니다. 변수명이나 초기화 값에서 타입을 명시하는것이 코드의 가독성을 높일 수 있는 경우에는 명시적인 타입 선언을 사용하는 것이 좋습니다.





profile
안녕나를소개하지이름은HaBu직업은Programer취미는tai chi meditation

0개의 댓글