백기선 자바 스터디 2주차

김성훈·2022년 6월 26일
0
post-thumbnail

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


학습할 것

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


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

자바 프로그래밍 언어는 정적으로 유형이 지정되므로 모든 변수를 사용하려면 먼저 선언을 해야한다, 여기에는 이미 본 것처럼 변수의 유형과 이름을 명시하는 것이 포함된다.


int age = 1;

이렇게 하면 age 라는 필드가 존재하고 초기 값이 "1"이라는 숫자 데이터를 보유하고 있다고 프로그램에 알려준다.
변수의 데이터 유형은 변수에 포함될 수 있는 값과 수행할 수 있는 작업을 결정한다.
자바에서는 8가지 기본 데이터 유형이 있다, 이것을 프리미티브 타입이라고 부른다.

논리형(boolean), 문자형(char), 정수형(byte, short, int, long), 실수형(float, double)이 있으며 프리미티브 타입은 값을 할당할 때 변수의 주소 값에 값이 그대로 저장되는 데이터 타입 이라고 볼 수 있다.

해당 데이터 타입은 값이 할당되면서 JVM의 Runtime Data Area 영역 중 Stack영역에 값이 저장된다.

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

java 에서 타입은 크게 primitive type 과 reference type이 있다.
primitive type 은 쉽게 말해 정수, 실수, 문자, 논리 리터럴 등의 실제 데이터 값을 저장하는 타입이고, reference type 은 객체의 번지를 참조 (주소를 저장) 하는 타입으로 메모리 번지 값을 통해 객체를 참조하는 타입이다.

Primitive Type

  • 실제 데이터 값을 저장하는 타입
  • 기본값이 있기 때문에 null이 존재하지 않는다.
  • 값이 할당되면서 JVM Runtime Data Area 영역 중 stack 영역에 값이 저장됨
  • 값의 범위를 벗어나면 컴파일 에러가 발생

Reference Type

  • 대표적으로 class, interface, enum, array, String Type이 있다
  • 원시타입(Primitive Type)을 제외한 모든 타입은 참조형 타입이다.
  • 빈 객체를 의미하는 null이 존재한다.
  • 값이 저장되어 있는 곳의 주소값을 저장하는 공간으로 Heap 영역에 저장된다.


기본타입변수 age, price의 경우에는 Stack 메모리 영역에 직접 그값이 저장되어 있지만 레퍼런스 타입변수인 name과 array의 경우에는 Stack영역에 해당하는 객체가 저장된 메모리(heap)주소값이 저장되어 있다.

접근속도


primitive type 은 Stack 메모리에 값이 존재한다
반면에 reference type 은 하나의 인스턴스이기 때문에 Stack 메모리에는 참조값만 있고, 실제값은 Heap 메모리에 존재한다.
그리고 값을 필요로 할 때마다 Unboxing 과정을 거쳐야 하니, primitive type 과 비교해서 접근 속도가 느려지게 된다.
예외적으로 엄청 큰 숫자를 복사해야 한다면, 참조값만 넘길 수 있는 reference type 이 좋을수도 있다.

3. 리터럴

  • 데이터 그 자체를 의미한다, 변수에 넣는 변하지 않는 데이터를 의미
  • 프로그램에서 직접 표현한 값
  • 정수, 실수, 문자, 논리, 문자열 리터럴이 존재한다.

리터럴은 언뜻 보면 상수와 같은 의미를 가진다고 생각이 된다.
수학적인 의미에서 변하지 않는 값은 모두 상수라고 하기 때문이다.
하지만 프로그래밍에서 상수의 개념은 아주 조금 다른데 변경할 수 없는 변수를 말한다.
그리고 이 상수는 어떤 값이 어떤 의미를 갖는지를 이해하기 쉽게 전달하기 위한 목적으로 쓰인다.

위의 Java 예제에서 의미하는 문자열 리터럴인 "HTTP" 를 표현할만한 용어가 필요해졌다.
그러나 이미 상수라는 용어는 쓰이고 있었기 때문에 값 자체를 의미하는 용어가 필요했고 그것을 리터럴이라는 용어로 구분지어 사용한 것이다.

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

자바에서 변수를 사용하기 위해서는 변수를 선언해야 한다.
변수를 선언하는 이유는 값을 저장하는 공간을 확보하겠다는 말이다.
쉽게 말하면 컴퓨터가 가진 메모리를 사용하겠다고 미리 컴퓨터에게 말하는 것이다.

변수 선언 방법


String address;

변수 선언 방법은 변수 타입과 변수명을 함께 작성하는 것이다.
변수 타입은 변수에 담는 값의 성질과 직접적으로 연관이 있고, 그렇기 때문에 어떤 값을 변수에 담느냐에 따라 변수 타입을 결정해야 한다.

초기화 하는 방법

변수를 사용하려면 초기화(Initialize)를 해야 한다.
변수는 변수를 선언한 후 값 할당을 해주어야만 사용할 수 있다.
경우에 따라 초기화를 하지 않고도 사용할 수 있지만 기본적으로는 변수는 선언과 초기화를 이루어져야 사용할 수 있다.

// 변수 선언
String address;

// 변수 초기화
address = "Suwon";

// 변수 선언 및 초기화
String address1 = "Busan";

변수의 초기화는 위에 코드처럼 선언과 초기화를 각 각 하는 방법과 선언과 초기화를 동시에 하는 방법도 있다.
한 문장에 변수를 여러 개 선언하는 방법도 있지만 추천하지 않는 방법이니 되도록이면 아래와 같은 변수 초기화 구문은 비추천 한다

// 다중 변수 선언
String address, address1;

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

변수 스코프

변수를 사용할 수 있는 범위를 이야기 한다, {중괄호} 안에서 변수를 선언했을 경우 영역이 끝나기 전까지는 어디서든 사용이 가능하다

자바의 변수 (클래스, 인스턴스, 지역변수)

변수의 선언 위치에 따라서 종류가 달라진다.

public class test {

	int instVar; // 인스턴스 변수    
    static int classVar; // 클래스 변수
    
    void method() {
    	int localVar; // 지역 변수
    }
}

클래스 변수 (static 멤버)

  • 클래스 내에 static 키워드로 선언된 변수
  • 처음 JVM이 실행되어 클래스가 메모리에 올라갈 때 ~ 프로그램이 종료될 때까지 유지
  • 동일한 클래스의 모든 객체들에 의해서 공유된다.
  • main 메소드는 static 이라는 키워드로 메소드가 정의되어 있다. 이런 메서드를 static 한 메소드 라고 한다.

지역 변수 (Local variable)

  • 특정 스코프 ({}) 내에서 생성되어 그 스코프 안에서만 사용 가능하다.
  • ex) 함수 속에 선언되어 해당 함수 속에서만 사용이 가능한 변수

전역 변수 (인스턴스 변수)

  • 클래스 속성으로 선언된 변수 GlobalScope 의 사용 범위는 클래스 전체
  • 메인 메소드가 같은 크래스 안에 있어도 GlobalScope 변수를 사용할 수 없다
  • 인스턴스 변수(Instance variable)와 클래스 변수(class variable)가 있다.
    • 클래스 변수는 클래스가 메모리에 올라갈때, 인스턴스 변수는 인스턴스가 생성되었을 때 생성된다,
  • 객체 생성시 마다 매번 새로운 변수가 생성된다.
  • main은 static한 메소드이다. static한 메서드에서는 static 하지 않은 필드를 사용 할 수 없다.

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

타입변환(캐스팅) 은 특정 자료형을 다른 자료형으로 변환하는 것이다.
예를 들면 int형과 float 형은 자료형을 저장하는 방식이 다르다, 또한 int와 long도 자료를 저장하는 방식이 다른다, 특정 자료형을 다른 자료형과 호환되게 변경하는 방법을 타입변환, 타입캐스팅, 형변환 이라고 한다.

타입 변환

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

형변환 방법

변활할 변수나 리터럴 앞에 타입을 괄호와 함께 붙혀주기만 하면 된다. 이 때 형변환 연산자는 그저 피연산자의 값을 읽어서 지정된 타입으로 형변환하고 그 결과를 반환할 뿐이기에 기존의 변수나 리터럴이 변화되지는 않는다.

(type)operand



double value = 123.456;
int score = (int)value;
System.out.println(value == 123.456); //true

기본형(primitive type) 변수는 boolean을 제외한 나머지 타입은 서로 형변환이 가능하다.

단점

타입간에는 각각이 가지는 범위(크기)가 다르기 때문에 형변환을 통해 크기의 차이만큼 값이 잘려나감으로써 값 손실(loss of data)이 발생할 수 있다.

자동 형변환

경우에 따라서 형변환을 생략할 수 있다, 그래도 컴파일러가 생략된 형변환을 자동으로 추가한다.

저장될 변수 타입의 범위가 더 작은 경우 에러가 발생한다, 이는 더 작은 값으로 할당되며 값 손실이 발생할 수 있기 때문에 이를 이미 알고 명시적으로 형변환을 작성해주면 에러를 발생시키지 않음.

byte b = 10000; //에러 발생. byte의 범위는 -128~127이다.
byte c = (byte)10000; //명시적 형변환으로 에러가 발생하지 않는다.

자동 형변환 규칙

기존의 값을 최대한 보존할 수 있는 타입으로 자동 형변환 됨

표현범위가 좁은 타입에서 넓은 타입으로 형변환 할 때 손실이 없기에 두 타입 중 표현범위가 더 넓은 쪽으로 형변환 된다.

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

Array(배열)

동일한 타입의 데이터를 연속된 공간에 저장하기 위한 자료구조.

자바에서 배열의 선언은 두 가지 방법으로 한다.
변수 선언에서 데이터타입 뒤에 [] 을 입력하는 방법과 변수 명뒤에 []를 입력하는 방법이다.

int[] array;   //가능
int array[];   //가능

하지만 이렇게 선언하면 배열은 null 값을 가지고 있다, 이후 초기화를 하면 배열의 주소가 할당되어 사용할 수 있게 된다, 초기화 방식은 여러가지 있다.


int[] array = new int[3];
// OR

int[] array = {0, 1, 2};

== int arr [] = new int[3];
   arr[0] = 1;
   arr[1] = 2;
   arr[2] = 3;
   
// OR

int[] array;
Arrays.fill(array,1);

// OR

for(int i=0;i<i_array.length;i++) {
    array[i]=i;
}

2차원 배열도 크게 다르지 않다.
[]를 추가해주는 것으로 2차원,3차원 배열을 구성할 수 있다.

int[][] array;   //가능
int array[][];   //가능

초기화 방법


int [][] arr = new int [2][2];
arr[0][0] = 1;
arr[0][1] = 2;
arr[1][0] = 3;
arr[1][1] = 4;

// OR

int arr[][] = {{1,2},{3,4}}

// OR

for(int i=0;i<array.length;i++) {
    for(int j=0;j<array[i].length(); j++)
        array[j]=j;
    }
}

8. 타입 추론, var

타입 추론이란 코드 작성당시에는 타입이 정해지지 않았지만, 컴파일러가 그 타입을 유추하는 것을 의미한다.
자바 9까지는 generics나 lamda식에 대해서만 타입추론을 지원했지만 자바 10부터 타입추론을 지원하는 var이라는 키워드가 추가되어 자바에서도 타입추론을 사용가능하게 되었다.
var은 지역변수로 사용해야하고 선언과 동시에 초기화가 필요합니다


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

출처

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

JAVA - 프리미티브 타입이란? (feat.레퍼런스 타입)

[211105 금] 셀 과제 : primitive type, reference type

profile
"한 명이 걷는 천 걸음 보다 천 명이 함께 걷는 한 걸음이 성공의 시작이고 완성이다"

0개의 댓글