11 min read

<Java> 변수 2

<Java> 변수 2
  • 변수에 대한 두번째 포스팅은 DataType에 대해 알려드리겠습니다.

변수의 타입

  • 우리가 사용하는 Data의 종류는 크게 문자와 숫자로 나눌 수 있습니다.또한 숫자는 정수와 실수로 나누어집니다.
  • 위와 같은 Data의 종류에 따라 값이 저장될 공간의 크기와 저장형식을 정의한 것을 자료형(Data Type)이라고 합니다.
  • 변수를 선언 할 경우, 저장하려는 데이터의 특성에 알맞은 자료형을 선택하여 선언해야 합니다.

기본형과 참조형

  • 자료형의 경우, 크게 기본형과 참조형으로 나누어질 수 있습니다. 기본형 변수(primitive type)는 실제 값(data)를 저장하는 반면에, 참조형 변수(reference type)는 어떠한 값이 저장되어 있는 주소를 값으로 가집니다.
  • 처음 자바를 접하는 사람의 경우, 기본형 변수에 대한 이해는 쉽게 할 수 있습니다.앞선 포스팅에서 설명한 그릇안에 실제 데이터를 담는 과정에서 사용되는 것이 기본형 변수라고 볼 수 있습니다. 하지만 참조형 변수의 경우, 클래스에 대한 이해가 없이는 완전히 이해 할 수 없다고 생각합니다.
  • 그래도 참조형 변수에 대해 설명을 하자면 주소값을 가지는 변수이기 때문에 변수 간의 연산이 불가합니다.즉, 연산이 가능한 모든 변수는 primitive type이라고 보셔도 됩니다.또한 참조형 변수는 아래와 같이 변수의 타입으로 클래스의 이름을 사용합니다.즉 새로운 클래스를 생성한다는 것은 새로운 참조형을 만들어내는 것과 동일합니다.
  • Reference Type의 초기화는 아래와 같이 new키워드와 생성자를 통해 진행합니다.(생성자는 Order()이고 추후에 다룰 예정입니다) 이후 연산자 new에 의해서 생성된 객체의 주소는 대입 연산자를 통해서 order라는 변수에 저장되는 것입니다.
  • 위와 같은 일련의 과정을 거치면 우리는 객체를 사용할 수 있게 됩니다.
  • 참고로 객체를 선언만 할 경우, null 주소를 가집니다. null이라 함은 어떤 객체의 주소도 저장되어있지 않음을 의미합니다.
Order order; // reference type 선언
Order order = new Order(); // reference type 초기화

기본형(Primitive Type)

  • 아직은 조금 헷갈리는 참조형은 뒤로 미루고, 직관적으로 이해할 수 있는 기본형에 대해서 말하겠습니다.(참고로 기본형이라는 용어보다는 Primitive Type이라는 용어를 더 자주 사용합니다)
  • 기본형은 아래와 같이 크게 4가지의 종류로 나누어집니다.
  1. 논리형 -> boolean
  2. 문자형 -> char
  3. 정수형 -> byte,short,int,long
  4. 실수형 -> float,double
  • 사실 논리형을 제외하고는 직관적으로 어떤 일을 수행하는지 유추가 가능할 것입니다. 먼저 논리형의 경우, boolean 타입을 사용하며 true와 false중 하나를 값으로 가지며 조건식과 논리적 계산에서 이용됩니다.
  • 문자형은 char라는 data-type(자료형)이 있으며, 변수에 단 하나의 글자만 저장할 수 있는 기능을 수행합니다.
  • 이후 정수형과 실수형은 다양한 data-type(자료형)들을 가지고 있으며 이는 각 자료형들마다 저장 할 수 있는 값의 범위가 다르기 때문입니다.
  • 자료형간의 저장 할 수 있는 값의 범위가 다르다는 것은 그릇의 크기가 상이하다는 의미입니다. 정수를 저장하는 int의 경우 4byte, 동일하게 정수를 저장하는 long의 경우 8byte, 실수를 저장하는 double의 경우 8byte, 동일한 실수를 저장하는 float의 경우는 4byte 등 다양하게 존재합니다. 하지만 대체적으로 정수는 int,실수는 double을 많이 사용합니다.
  • Primitive Type의 크기는 아래의 표를 참조하시면 됩니다.
https://www.startertutorials.com/corejava/java-data-types.html
https://www.startertutorials.com/corejava/java-data-types.html

상수(Constant)와 Literal

  • 먼저 상수의 경우 변수와 마찬가지로 값을 저장할 수 있는 공간이지만, 변수와 달리 한번 값을 저장하면 다른 값으로 변경할 수 없다는 특징을 가지고 있습니다.
  • 상수를 선언하는 방법은 아래 코드와 같습니다. 아래의 코드는 선언과 초기화를 동시에 진행하였습니다.
final int MAX_NUM_OF_ORDER = 1000000;
  • 명명법에서 한번 언급이 되었듯이, 상수는 모두 대문자로 구성하며 단어간 구별은 언더바를 통해서 진행합니다.
  • Literal이란, 저도 자바를 처음 배울 때 많이 헷갈렷던 부분입니다. 이를 어떻게 이해했냐면 실제 저희가 배우는 수학에서의 상수의 역할을 리터럴이 한다고 생각하면 됩니다.즉, 1,’B’,45,-1 등 이러한 값들을 기존의 수학에서 상수라고 명명합니다. 하지만 자바에서 상수라는 단어은 이미 바뀌지 않는 수라는 의미로 사용을 해버려서 이를 대체할 용어로 Literal을 선택 한 것입니다.
int age = 25; // 25도 리터럴
final int MIN_VALUE = 0; //0도 리터럴
  • 놀랍게도 이러한 리터럴도 변수처럼 타입을 가집니다. 아래의 코드를 보시죠.
long order_id = 1L;
float value = 12.12f;
  • long과 float 자료형을 초기화할 경우, 위의 경우처럼 L(l) 또는 F(f)를 리터럴에 붙여서 초기화를 진행해 주어야 합니다.
  • 또한 16진수나 8진수를 표현 할경우에도, 0x 또는 0을 접미사로 붙여줘야합니다.

타입의 불일치

  • 보통 리터럴의 타입은 저장될 변수의 타입과 일치하는 것이 보통이지만, 타입이 달라도 저장범위가 넓은 타입에 좁은 타입의 값을 저장하는 것은 가능합니다.
  • 아래의 예제를 통해 알아봅시다.
int x = 'A'; // 가능
long y = 321;// 가능
double d = 3.14F;// 가능
float f = 2.12; // error
  • 가능한 코드들은 리터럴의 값이 변수 타입의 범위를 넘어서지 않는 경우들입니다.
  • 에러가 발생하는 4번째의 경우, 리터럴이 double형인데 데이터 타입을 float형으로 선언했기에 에러가 발생합니다.

문자 리터럴과 문자열 리터럴

  • 위 두가지의 경우 직관적으로 이해 할 수 있습니다.
  • 문자 리터럴의 경우 단 하나의 문자만을 저장할 수 있는 리터럴을 의미하고 문자열 리터럴의 경우 문자가 두개 이상인 경우에 사용합니다.
  • 이들은 각각 홑따옴표, 쌍따옴표에 넣을 수 있습니다.
  • 그리고 이들을 취할 수 있는 자료형은 각각 char, String 타입이 존재합니다.아래 예제를 통해 이해 해 봅시다.
//먼저 문자 리터럴
char x = 'x';//홑따옴표 사용
String str = "hello"; // 쌍따옴표 사용
  • 여기서 살펴볼 점이 있습니다. 우리가 배운 primitive type에 String이라는 데이터 타입은 존재하지 않았는데 어떻게 변수처럼 사용가능할까요?
  • 사실 위의 str이라는 변수를 선언하는 코드에는 생략된 부분이 있습니다.실제로 아래와 같은 방법을 통해 사용해야합니다.
String str = new String("hello");
  • 어디서 많이 본것 같지 않나요? 바로 참조형 변수, 즉 클래스를 통해 주소값을 가지는 변수가 생성됩니다.즉 String이라는 타입은 참조형 변수이지만 예외적으로 Primitive Type처럼 선언하고 초기화 할 수 있게 합니다.왜냐하면 워낙 빈번하게 사용하기 때문이죠.
  • 하나의 예외가 더 존재하는데 String의 경우 연산이 가능하다는 점입니다. 아래의 코드를 보시면 이미 String으로 저장된 변수들에 + 연산을 하여 하나의 이름처럼 이어 붙이는게 가능합니다.
package ch2;

public class StringEx {
    public static void main(String[] args) {
        String firstName = "Chang" + "Sub";
        String lastName = "Hong";
        System.out.println(firstName + lastName);

        String fullName = firstName + lastName;

        String empty = " ";
        System.out.println(empty + fullName);
    }
}

  • 조금 더 분석을 하기위해 String class를 읽어보면 String이라는 객체는 내부에 private으로 byte데이터 타입의 배열이 선언되어있습니다.
  • 즉, 문자열을 구성하는 하나하나의 문자들을 byte타입으로 나열하는 형태로 구성됨을 알 수 있습니다.이는 실제 디버거를 돌려보아도 다음과 같이 byte타입의 배열이 선언되어 있음을 알 수 있습니다.
  • 여기서 배열이라함은 우리가 배운 다양한 자료형들을 순서대로 쭈욱 나열해놓은 하나의 또 다른 변수라고 간단하게 이해하셔도 됩니다.

콘솔창에 출력하기

  • 기본적으로 자바는 System.out.println()을 통해 콘솔 출력을 수행합니다.이와 같은 출력함수들은 다양하게 존재하는데 대표적으로 println은 출력후 개행을 진행해줍니다.개행이라함은 한줄 띄워준다고 생각하면 됩니다. 대부분의 콘솔 출력은 println()을 사용합니다.
  • 예외적으로 printf()라는 함수가 있습니다.이는 C언어를 하신분들은 상당히 익숙하실 것 입니다.아래와 같이 형식 지정자를 사용하고 해당 형식에 알맞은 변수를 함수의 parameter로 넣어줍니다.
int age = 25;
System.out.println("Age: %d",age);
  • 하지만 기본적으로 println()를 사용하시는것에 더 익숙해지는게 좋다고 생각합니다.
  • 마지막으로 모니터를 통해 출력하는 것을 표준출력이라고 합니다.

화면에서 입력받기

  • 이제 키보드로부터 사용자가 원하는 값을 입력받는 방법을 알아봅시다.위에서 배운 표준 출력과 반대로 이는 표준입력이라고 합니다.
  • 우리는 표준입력을 수행하기위해 Scanner라는 참조형 변수(클래스)를 사용해보겠습니다.
  • 아래와 코드의 결과를 통해 스캐너의 nextInt() 또는 next()를 함에 따라 입력값의 데이터 타입이 달라짐을 확인 할 수 있습니다.
  • 즉, 사용자가 어떠한 데이터 타입을 받을지 정하고 그에 알맞은 함수를 적절히 사용해야 한다는 것을 알 수 있습니다.
package ch2;

import java.util.Scanner;

public class ScannerEx {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        System.out.print("정수를 입력하세요 : ");
        int input1 = sc.nextInt();
        System.out.println("input1 = " + input1);

        System.out.print("정수를 입력하세요 : ");
        String input2 = sc.next();
        System.out.println("input2 = " + input2);
        System.out.println("input2.getClass().getName() = " + input2.getClass().getName());
    }
}

Ref : 자바의 정석 - 남궁성