영권's

2주차 과제: 자바 데이터 타입, 변수 그리고 배열 본문

스터디/백기선 라이브 스터디(자바)

2주차 과제: 자바 데이터 타입, 변수 그리고 배열

ykkkk 2020. 11. 21. 03:19

목표

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

학습할 것

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

 

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

프리미티브 타입이란 정수, 실수, 문자, 논리 리터럴을 직접 저장하는 타입을 말한다.

정수 타입에는 byte, char, short, int, long이 있고, 실수에는 float, double이 있다 그리고 논리 타입에는 boolean이 있다.

도서) 이것이 자바다

 byte, char, short, int, long, float, double, boolean 타입의 기본 값

byte	0
short	0
int		0
long	0L
char	'\u0000'
float	0.0f
double	0.0d
boolean	false

 

 

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

도서) 이것이 자바다

기본 타입이란 정수, 실수, 문자, 논리 리터럴을 저장하는 타입을 말하며 참조 타입이란 객체의 번지를 참조하는 타입으로 배열, 열거, 클래스 ,인터페이스 타입을 말한다.

 

리터럴

리터럴은 데이터 그 자체를 뜻한다.

 

변수에 넣는 변하지 않는 데이터를 의미한다.

 

int a = 100;

여기서 a는 변수가 되며 100은 변수에 들어가는 리터럴이 된다.

 

그렇다면 인스턴스(클래스 데이터)가 리터럴이 될 수 있을까?

답은 아니오다. 만약 인스턴스안에 있는 값들을 변경하지 않는다면 모를까,

보통의 인스턴스는 동적으로 사용하기 위해 작성되므로.

리터럴이 될 수가 없다. 왜냐하면 값이 언제 바뀔지 모르는 것이기 때문이다.

하지만 프로그래밍 에서 객체 리터럴이란 표현을 들어본적이 있을 것이다.

데이터가 변하지 않도록 설계를 한 클래스를 불변 클래스라 칭한다.(immutable class)

해당 클래스는 한번 생성하면 객체 안의 데이터가 변하지 않는다. 변할 상황이면 새로운 객체를 만들어준다.

자바의 String, Color 같은 클래스가 이와 같은 예이다. 

따라서 우리는 "abc" 와 같은 문자열을 자바에서는 '객체 리터럴' 짧게는 '리터럴' 이라고 표현 하는것이다.

 

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

도서) 이것이 자바다

// 기본 타입 변수
int age = 25;
double price = 100.5;

// 참조 타입 변수
String name = "신용권";
String hobby = "독서";

위 코드와 같이 변수 선언 및 초기화를 할 수 있고 사진처럼 기본 타입 변수와 참조 타입 변수의 생성 방식(?)이 다르다

 

기본 타입 변수는 Runtime Data Areas 에 스택 영역에 직접 값을 저장하고 있지만 참조 타입 변수는 힙 영역의 String 객체 주소 값을 가지고 있다.

객체 주소를 통해 객체를 참조한다는 뜻에서 참조 타입 변수라고 한다.

 

변수의 스코프와 라이프사이클

각 변수에는 접근이 가능한 범위와 선언부터 필요 없으면 사라지는 메모리 해체 될 때까지 라이프 사이클이 존재한다.

 

인스턴스 변수

인스턴스 변수란 객체를 생성 후 사용할 수 있는 변수를 말하는데 이를 인스턴스 변수라 한다.

인스턴스 변수와 인스턴스 메서드는 객체에 소속된 멤버이기 때문에 객체없이는 사용할 수 없다.

인스턴스 선언을 안하고 사용하려고 하면 실제 객체가 메모리상에 존재하지 않기 때문에 사용할 수 없다.

때문에 해당 객체를 사용할 수 있으면 인스턴스 변수 또한 사용할 수 있다.(라이프 사이클)

 

클래스 변수

클래스 변수는 인스턴스 변수에 static이 붙은 변수며 인스턴스 변수는 각각 고유한 값을 가지지만 클래스 변수는 모든 인스턴스가 공통된 값을 공유하게 됩니다.

한 클래스들의 모든 인스턴스들이 공통적인 값을 가져야할 때 클래스 변수로 선언합니다.

클래스가 로딩될 때 생성되어(메모리에 한번만 올라감) 종료 될 때 까지 유지되는 클래스 변수는 public 을 붙이면 같은 프로그램 내에서 어디서든 접근할 수 있는 전역 변수가 됩니다. 또한 인스턴스 변수의 접근법과 다르게 인스턴스를 생성하지 않고 클래스이름.클래스변수명 을 통해 접근 가능합니다.

프로그램이 끝나거나 클래스가 메모리에 로딩 되어 있는 동안 접근해서 사용할 수 있습니다

 

지역 변수

메서드 내에서 선언되며 메서드 내에서만 사용할 수 있는 변수입니다.

메서드가 실행될 때 메모리를 할당 받으며 메서드가 끝나면 소멸되어 사용할 수 없게 됩니다. (메서드의 매개변수도 지역변수에 속하게 됩니다.)

지역 변수 영역이 끝날때까지가 라이프 사이클이며 지역 변수 영역이 아닌 외부에서는 사용할 수 없다.

 

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

타입 변환이란 데이터 타입을 다른 데이터 타입으로 변환하는 것을 말한다.

 

자동 타입 변환(묵시적 형변환)

작은 크기를 가지는 타입이 큰 크기를 가지는 타입에 저장될 때 발생한다.

큰 크기 타입과 작은 크기 타입의 구분은 사용하는 메모리 크기이다.

예를 들어 byte 타입은 1byte크기를 가지고 int 타입은 4byte 크기를 가지므로 int 타입이 큰 크기 타입이다.

 

강제 타입 변환(명시적 형변환)

큰 크기의 타입은 작은 크기의 타입으로 자동 타입 변환을 할 수 없다. 예를 들어 4byte인 int타입을 1byte인 byte 타입에 담을 수 없다.

마치 큰 그릇의 물을 작은 그릇안에 모두 넣을 수 없는 것과 동일한 이치이다.

하지만 큰 그릇을 작은 그릇 사이즈로 쪼개어 한 조각만 작은 그릇에 넣는다면 가능하다.

즉 int 타입을 4개의 byte로 쪼개고 끝에 있는 1byte만 byte 타입 변수에 저장하는 것은 가능하다.

이와 같이 강제적으로 큰 데이터 타입을 작은 데이터 타입으로 쪼개어서 저장하는 것을 강제 타입 변환(캐스팅 : casting)이라고 한다.

강제 타입 변환은 캐스팅 연산자()를 사용한다.

+ 업 캐스팅과 다운 캐스팅 과거에 정리해 놓은 글(cyk0825.tistory.com/2)

보고 수정해야 할 부분 있으면 다시 작성해야겠다...

 

1차 및 2차 배열 선언하기

배열이란 변수는 하나의 데이터만 저장 할 수 있다. 데이터 수가 많아지면 그만큼 많은 변수가 필요하다.

그래서 같은 타입의 많은 양의 데이터를 다루는 프로그램에소는 좀 더 효율적인 방법이 필요한데 이것이 배열이다.

배열은 같은 타입의 데이터를 연속된 공간에 나열시키고, 각 데이터에 인덱스를 부여해 놓은 자료구조이다.

 

1차원 배열 선언

int i[] = new int[10]; // 공간이 10개인 1차원 배열을 선언 int[] i = new int[10]; 과 똑같다
i[0] = 1; // 배열 i의 0번째 공간에 1로 초기화
		for (int j = 0; j < i.length; j++) {
            System.out.print(i[j] + " ");
        }

 

결과 : 1 0 0 0 0 0 0 0 0 0 

 

int test[][] = new int[3][3];

        for (int j = 0; j < test.length; j++) {
            System.out.print(j + " : ");

            for (int k = 0; k < test[0].length; k++) {
                test[j][k] = j;
                System.out.print(test[j][k] + " ");
            }
            System.out.println();
        }

결과 : 

0 : 0 0 0 
1 : 1 1 1 
2 : 2 2 2 

 

타입 추론, var

타입 추론이란 코드 작성 당시 타입이 정해지지 않았지만, 컴파일러가 그 타입을 유추하는 것이다.

 

Java 10에서 var라는 Local Variable Type-Inference 가 추가되었다. 

이 키워드는 local variable이면서 선언과 동시에 initializer가 필수적으로 요구된다.

// java 9 이하
String message = "data";
// java 10 이상
var message = "the initializer present on the right-hand side";


> We don't provide the data type of message. Instead, we mark the message as a var, and the compiler infers the type of message from the type of the initializer present on the right-hand side.
* "컴파일러는 오른쪽에 초기화 값으로 제공되는 것을 통해 타입을 유추한다."

 

주의 및 신경써야할 부분

  • 자바 7에서 다이아몬드 연산자라는 방식이 추가되었는데, 자바 10에서 나온 var 와 함께 사용하게 되면 컴파일 에러가 발생한다.
// 컴파일러가 타입을 유추할 수 있는 정보가 없다.
var messages = new ArrayList<>();

// 이렇게 사용
var messages = new ArrayList<String>();

 

가독성에 있어, 다른 개발자가 읽을때 가독성이 좋을지 고민해야할 것 같다. 다른 사람의 코드를 읽는 경우는 IDE 상에서 코드를 받아 보는 경우도 많겠지만, PR 이 올라와서 github 이나 bitbucket 웹 상으로 보는 경우도 많은 것 같다. 아래 두 경우가 있는데,

  1. 해당 위치만 보고 message 에 어떤 타입의 데이터가 할당될지 알 수 있는 경우
var message = "문자열 입니다.";

 

 

  1. 예시에서는 바로 아래 메소드가 있었지만, 다른 클래스 파일에 있는 경우 두 군데 이상의 파일을 조회해야 한다.
public void some() {
    var message = getMessage();
}

public Message getMessage() {
  	// ...
    return new Message("객체입니다.", MessageType.SOME);
}

 

 

출처:

도서) 이것이 자바다

https://www.baeldung.com/java-10-local-variable-type-inference

 

 https://mommoo.tistory.com/14 [개발자로 홀로 서기]

 

julingks.tistory.com/entry/Defualt-values-of-primitive-varibales-in-Java

 

itmining.tistory.com/20

 

velog.io/@bk_log/Java-%ED%83%80%EC%9E%85-%EC%B6%94%EB%A1%A0

Comments