JAVA

[JAVA] 변수

개발 공주 2023. 5. 23. 00:13
728x90

변수

Java 프로그램에서 값을 다루기 위해서는 값을 저장해둘 저장공간(그릇)의 선언이 필요합니다.

 

저장공간의 선언과 값의 저장

  • 저장공간의 선언
int number; // number 라는 이름의 int(숫자)타입의 저장공간을 선언
String name; // name 이라는 이름의 String(문자열)타입의 저장공간을 선언

- 선언할때는 저장공간에 담을 값의 타입과 이름을 명시하여 선언합니다.
- 값의 타입 : 저장공간의 종류
- 값의 이름 : 저장공간의 이름
  • 값의 저장
    • Java 프로그램에서 저장공간에 값을 저장하는 방법은 2가지 입니다.
// 1. 선언과 동시에 저장한다면 이것은 “초기화” 라고 합니다.
int number = 10; // 1. 선언과 동시에 값을 저장공간에 저장 (=초기화)
// 2. 선언 이후에 값을 저장한다면 일반적인 “덮어쓰기” 입니다.
number = 11; // 2. 선언 이후에 다른값을 저장공간에 저장

변수와 상수

변수 : 변하는 저장공간

  • Java 프로그램에서 저장하는 대부분의 값들은 변하는 것. 즉, 변수 입니다.
  • ‘수’로 끝나지만 숫자만 말하는것은 아니고 하나의 값을 저장할 수 있는 저장공간을 의미 합니다.
  • “저장공간” 이라고 표현한 이유는 “변하는 것”이라는 의미에 맞게 저장하고있는 값이 달라질 수 있기 때문입니다.
  • 우리는 이 저장공간에 이름(변수명)을 붙여서 필요한 값을 저장해둡니다.
  • 이 변수는 저장되는 값의 형태에 따라서 여러가지 모습을 지니게 됩니다.
int number = 10; // 1. 변수로 선언 및 초기화
number = 11; // 2. 변수의 값을 바꾼다. (덮어쓰기)

상수 : 변하지 않는 저장공간

  • Java 프로그램에서는 변하지 않을 값을 변하지 않는 저장공간에 저장해둡니다.
  • “변하지 않는 저장공간” 이라고 표현한 이유는 저장효율을 위해 “변하지 않을 값”을 따로 저장하는 공간이 있기 때문입니다.
  • 이 상수또한 저장되는 값의 형태에 따라서 여러가지 모습을 지니게 됩니다.
final int number = 10; // 1. 상수로 선언 (데이터 타입 앞에 final 을 붙이면 됩니다.)
number = 11; // e2. 변수의 값을 바꾸려고하면 에러가 납니다!

 

저장공간의 종류 (변수 타입)

변수의 종류와 범위

기본형 변수(primitive type)

  • 논리형 변수 : boolean
    • True/False 값만 저장한다
boolean flag = true; // 1. 논리형 변수 boolean 으로 선언 및 True 값으로 초기화

flag = false; // 2. False 값으로도 저장할 수 있습니다.
  • 문자형 변수 : char
    • 'A','1' 와 같은 문자 하나만 저장한다.
char alphabet = 'A'; // 문자 하나를 저장합니다.
  • 정수형 변수 : byte, short, int, long
    • 0,1,2,99 와 같은 정수형 숫자값을 저장합니다.
    • 정수형 변수 표현 범위
📌 각 변수 표현 범위를 넘는 숫자를 넣게되면 오버플로우가 발생하고, 해당 숫자를 출력해보면 입력값과 다른 값으로 표현됩니다. (표현 범위를 초과한것이기 때문에 입력한 값보다 작거나 음수인 값이 표현됩니다.)
=> 그렇기 때문에 각 변수들의 표현 범위를 잘 알아야 버그가 생기지 않는다.
  • byte : -128 ~ 127 범위의 숫자만 저장 가능합니다.
  • short (2byte) 는 -32,768~32,767 범위의 숫자만 저장 가능합니다.
  • int (4byte) 는 -21억~21억 범위의 숫자만 저장 가능합니다.
  • long (8byte) 은 9백경 정도의 매우 큰수를 저장 가능합니다.
byte byteNumber = 127; // byte 는 -128 ~ 127 범위의 숫자만 저장 가능합니다.
short shortNumber = 32767; // short 는 -32,768~32,767 범위의 숫자만 저장 가능합니다.
int intNumber = 2147483647; // int 는 -21억~21억 범위의 숫자만 저장 가능합니다.
long longNumber = 2147483647L; // long 은 숫자뒤에 알파벳 L 을 붙여서 표기하며 매우 큰수를 저장 가능합니다.

📌 정수형 리터럴 구분값(리터럴 = 데이터값)

int 와 long 의 데이터값(리터럴)을 구분하기 위한 구분자로 long으로 담을 숫자뒤에 L을 붙입니다.

이런식으로 데이터값(리터럴) 뒤에 붙이는 구분값을 “접미사” 라고 부릅니다.

  • 실수형 변수 : float, double
    • 0.123, 0.99999 와 같은 소수점 실수값을 저장합니다.
    • 실수형 변수의 표현 범위
📌 실수도 동일하게 각 변수 표현 범위를 넘는 숫자를 넣게되면 오버플로우가 발생하고, 해당 숫자를 출력해보면 입력값과 다른 값으로 표현됩니다. 특히, 실수는 표현범위가 매우 넓어서 정수형 변수에서 담지 못할 수 있습니다.
float floatNumber = 0.123f; // float 는 4byte 로 3.4 * 10^38 범위를 표현하는 실수값,소수점 7자리 까지 저장(표현)가능
double doubleNumber = 0.123123123; // double 은 8byte 로 1.7 * 10^308 범위를 표현하는 실수값, 소수점 16자리까지 저장(표현)가능

참조형 변수(reference type)

  • 문자열 변수 : String
    • “Apple”, “텍스트” 와 같은 문장을 저장합니다.
String message = "Hello World"; // 문자열을 저장합니다.
  • 그 외 :  객체(Object), 배열(Array), 리스트(List), 열거(Enumeration), 클래스(Class), 인터페이스(Interface)
    • 객체, 배열, 리스트와 같은 단일 저장공간에 담을 수 없는 값을 저장합니다.
List<int> alphabet = [0,1,2,3]; // 기본형 변수 여러개를 저장합니다.

 

래퍼 클래스 변수

📌래퍼 클래스(Wrapper Class) 라는 말 그대로 “기본형 변수를 클래스로 한번 랩핑(감싸는) 변수” 라고 생각하시면 됩니다.
  • 기본형 변수 타입명에서 첫글자를 대문자로 바꾸어서 래퍼 클래스를 정의해주었습니다.
  • 래퍼 클래스를 사용하는 이유
    • 클래스는 객체지향 언어인 Java 의 핵심기능인데요. 그렇기 때문에 클래스로 변수를 관리하면 객체지향의 많은 기능을 사용할 수 있게됩니다.
  • 박싱 vs 언박싱
    • 기본 타입에서 래퍼 클래스 변수로 변수를 감싸는 것을 “박싱” 이라고 부르며
    • 래퍼 클래스 변수를 기본 타입 변수로 가져오는 것을 “언박싱”이라고 부릅니다.
// 박싱 VS 언박싱

// 박싱
// Integer 래퍼 클래스 num 에 21 의 값을 저장
int number = 21;
Integer num = new Integet(number);

// 언박싱
int n = num.intValue(); // 래퍼 클래스들은 inValue() 같은 언박싱 메서드들을 제공해줍니다.

모든 기본 타입에는 래퍼 클래스가 있습니다.

기본타입 래퍼 클래스
byte Byte
short Short
int integer
long long
float Float
double Double
char Character
boolean Boolean

숫자와 문자

  • 숫자(int)를 문자(char)로 매핑해서(짝을 지어서) 표현
  • 아스키 코드 표

import java.util.Scanner;

public class Main {

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

		int asciiNumber = sc.nextInt(); //숫자 -> 문자 입력 : 97
		char ch = (char)asciiNumber; // 문자로 형변환을 해주면 숫자에 맞는 문자로 표현됩니다.

		System.out.println(ch);	//출력 : a
        
        	// 첫번째 글자만 받아오기위해 charAt(0) 메서드를 사용합니다.
        	char letter = sc.nextLine().charAt(0); //입력 : a
       	 	// 숫자로 형변환을 해주면 저장되어있던 아스키 숫자값으로 표현됩니다.
		int asciiNumber = (int)letter; 

		System.out.println(asciiNumber); //출력 : 97
	}

}

문자와 문자열

기본형 변수 중 문자와 문자열의 차이점에 대해서 알아보자.

  • 선언 관점에서 차이점
    • 문자(char)
      • 문자 한개만 저장하며 따옴표를 사용하여 값을 지정한다.
    • 문자열(String)
      • 문자 여러개를 문장형태로 저장하며 쌍따옴표를 사용하여 범위를 지정합니다.
char alphabet = 'A'; // 문자 하나를 저장합니다.
String message = "Hello World"; // 문자열을 저장합니다.
  • 저장 관점에서 차이점
    • 문자 (char)
      • 문자 뒤에 \0(널문자)가 없습니다. (1 byte 만 쓰기 때문에 끝을 알아서 데이터만 저장하면 됩니다.)
    • 문자열 (String)
      • 문장의 끝에 \0(널문자)가 함께 저장이 됩니다. (몇개의 byte 를 쓸지 모르기 때문에 끝을 표시해야 합니다.)

참조형

  • 참조형 변수 = 주소형 변수?
    • 다른 기본형 변수가 실제 값을 저장하는 저장공간 이라면 참조형 변수는 실제 값이 아닌 원본값의 주소값을 저장합니다.
    • 다시말해 참조형 변수는 주소값을 저장하는 주소형 변수라고 불러도 됩니다.
  • 저장 관점에서 차이점
    • 기본형 변수 : 원본값이 Stack 영역에 있습니다.
    • 참조형 변수 : 원본값이 Heap 영역에 있습니다.
      • Stack 영역에는 따로 저장 해둔 원본값의 Heap 영역주소를 저장합니다.
  • 📌 Stack 영역 vs Heap 영역
    • Stack의 경우에는 정적으로 할당된 메모리 영역입니다.
      • 그래서, 크기가 몇 byte 인지 정해져 있는 기본형 변수를 저장합니다.
      • 추가로, 크기가 정해져 있는 참조형 변수의 주소 값도 저장합니다.
    • Heap의 경우에는 동적으로 할당된 메모리 영역입니다.
      • 그래서, 크기가 계속 늘어날 수 있는 참조형 변수의 원본을 저장합니다.

입력 & 출력

  • 입력
    • Java 프로그램에서는 기본적으로 Scanner.in 객체의 next() 명령을 사용해서 입력받습니다.
Scanner sc = new Scanner(System.in); // Scanner 객체를 new 명령어로 생성합니다.
String input = sc.next();  // sc(Scanner)의 .next(); 를 실행하면 input 변수에 입력한 글자를 받을 수 있습니다.
  • 출력
    • Java 프로그램에서는 기본적으로 System.out 객체의 println() 명령을 사용해서 출력합니다.
Scanner sc = new Scanner(System.in);
String input = sc.next();  

System.out.println("입력값 : " + input);  // 입력한 글자를 출력합니다.

// 실행 결과
{입력}
입력값 : {입력}

비트&바이트

  • Bit
    • Bit(비트)는 0,1 형태의 2진수 데이터로써 컴퓨터가 저장(표현)할 수 있는 최소 단위 입니다.
    • 정수형 값은 10진수 숫자(0~10범위의 숫자)이며 2진수(0~1범위)Bit 로 저장(표현) 합니다.
    • 4개의 Bit로 16진수 숫자(0~F(16)범위의 숫자)를 2진수(0~1범위)Bit 로 저장(표현) 합니다.
    • 2진수(0~1)를 10진수, 16진수로 변환된 값 예시 표

  • Byte = 8 Bit
    • Byte(바이트)는 8개의 Bit(비트)로 구성되어 있습니다.
    • 1 Byte 내에서 숫자 변수는 Bit 2진수를 10진수로 저장(표현)을 합니다.
      • 10진수로는 0~255(2의8승)까지 저장(표현) 합니다.
    • 1 Byte 내에서 문자 변수의 경우만 Bit 2진수를 16진수로 저장(표현)합니다.

변수 타입 바꾸기(형변환)

  • 형변환에 대한 이해
    • Java 프로그래밍을 하다보면 문자열로 입력받은 변수를 숫자로 변환해서 계산을 하고싶은 경우, 문자열에 숫자값을 추가하고 싶은 경우 등… 어떤 변수형을 다른 형으로 변환이 필요한 경우가 많습니다.
    • 형변환은 주로 기본형 변수인 정수 ↔ 실수 ↔ 문자 들 사이에서 일어나며 방법은 아래와 같습니다.
  • 정수형, 실수형 간 발생하는 형변환
  • 정수 ↔ 실수 간에 변환할때는 ({원하는 타입}) 명령을 통해 변환할 수 있습니다. (캐스팅)
    • Double, Float to Int
      • (Int)캐스팅 방식으로 실수를 정수로 치환하는 방법입니다. 
      • 이때 실수형의 소수점아래자리는 버려집니다.
    • Int to Double, Float
      • (Double,Float) 캐스팅으로 정수형을 실수형으로 변환하는 방법입니다.
double doubleNumber = 10.101010;
float floatNumber = 10.1010

int intNumber;
intNumber = (int)doubleNumber; // double -> int 형변환
intNumber = (int)floatNumber; // float -> int 형변환

double doubleNumber = 10.101010;
float floatNumber = 10.1010

int intNumber;
intNumber = (int)doubleNumber; // double -> int 형변환
intNumber = (int)floatNumber; // float -> int 형변환

자동 형변환

  • Java 프로그래밍에서 형변환을 직접적으로 캐스팅하지 않아도 자동으로 형변환 되는 케이스가 있습니다.
  • 프로그램 실행 도중에 값을 저장하거나 계산할때 자동으로 타입변환이 일어납니다.

 

  • 1) 자동 타입변환은 작은 크기의 타입에서 큰 크기의 타입으로 저장될때 큰 크기로 형변환이 발생합니다.
📌 변수 타입별 크기 순서
byte(1) → short(2) → int(4) → long(8) → float(4) → double(8)
byte byteNumber = 10;
int intNumber = byteNumber;    // byte -> int 형변환
System.out.println(intNumber); // 10

char charAlphabet = 'A';
intNumber = charAlphabet;   // char -> int 형변환
System.out.println(intNumber); // A의 유니코드 : 65

intNumber = 100;
long longNumber = intNumber; // int -> number 형변환
System.out.println(longNumber); // 100

intNumber = 200;
double doubleNumber = intNumber; // int -> double 형변환
System.out.println(doubleNumber); // 200.0  (소수점이 추가된 실수출력)
  • 2) 작은 크기의 타입이 큰 크기의 타입과 계산될때 자동으로 큰 크기의 타입으로 형변환이 발생합니다.
int intNumber = 10;
double doubleNumber = 5.5;
double result = intNumber + doubleNumber; // result 에 15.5 저장됨 (int -> double)

intNumber = 10;
int iResult = intNumber / 4; // iResult 에 2 저장됨 (int형 연산 -> 소수점 버려짐)

intNumber = 10;
double dResult = intNumber / 4.0; // dResult 에 2.5 저장됨 (double형 연산 -> 소수점 저장)
  • 🔥 자동 형변환 vs 강제 형변환

  • 작은 타입 > 큰 타입 형변환시 (자동 형변환)
    • 더 큰 표현범위를 가진 타입으로 변환되는것이라 값의 손실이 없습니다.
    • 값의 손실없이 변환이 가능하기 때문에 컴파일러가 자동으로 형변환을 해줍니다.
  • 큰 타입 > 작은 타입 형변환시 (강제 형변환 = 캐스팅)
    • 더 작은 표현범위를 가진 타입으로 변환된는것이라 값의 손실이 생깁니다.
    • 값의 손실이 생기기 때문에 자동으로 형변환을 해주지 않고 개발자가 선택하여 형변환을 합니다.

'JAVA' 카테고리의 다른 글

[JAVA] 참조형 배열로 정리하기 (컬렉션)  (0) 2023.05.27
[JAVA] 배열  (2) 2023.05.26
[JAVA] 조건문, 반복문  (0) 2023.05.24
[JAVA] 연산자  (0) 2023.05.24
[JAVA] JVM  (0) 2023.05.22