자바 JAVA/자바 기초

자바 변수 : 기본형과 참조형 그리고 기본형의 종류와 범위

땅콩아놀자 2023. 5. 8. 18:28
반응형

변수(variable)

변수란 하나의 값을 저장할 수 있는 저장공간이다.

 

변수 선언과 대입

더보기

변수타입 변수이름;

 

① 변수의 선언 

정수를 저장하기 위한 변수 x를 선언

int x; 

 

② 변수에 대입

변수에 5라는 값 저장

x = 5;

①에서 x라는 이름의 변수(저장공간)이 생기고 ②의 문장으로 x에 5가 대입된다.

 

상수(constant) : final키워드 

상수는 변수 처럼 값을 저장할 수 있는 공간으로 값을 한번 초기화(저장)하면 다른 값으로 변경할 수 없다. 상수를 선언하는 방법은 변수와 동일하며 변수 타입 앞에 키워드 final을 붙여주면 된다. 상수의 이름은 모두 대문자로 하는 것이 관례이고, 여러 단어로 이루어져 있을 경우 '_' 로 구분한다.

더보기

final 타입 변수명 = ;

 

리터럴(literal)

12, 123, 3.14, 'A'와 같은 값들이 상수인데, 값을 한 번 저장하면 변경할 수 없는 저장공간으로 정의하였기 때문에 구분짓기 위해 상수를 다른 이름으로 불러야했다. 그래서 상수 대신 리터럴이라는 용어를 사용한다. 리터럴은 기존에 알고 있던 상수의 다른 이름으로 그 자체로 '값'을 의미하는 것이다.

* 상수는 값을 한번만 저장할 수 있는 공간, 변수는 하나의 값을 저장하기 위한 공간, 리터럴은 값을 의미

 

변수의 타입은 저장될 '값의 타입'에 의해 결정된다.

종류 리터럴 접미사
논리형 false, true 없음
정수형 123, 0b0101, 077, 0xFF, 100L long 타입은 l 또는 L 없다면 int형
실수형 3.14, 3.0e8, 1.4f, 0x1.0p-1 float는 f or F, double은 d or D
문자형 'A', '1', '\n' 없음
문자열 "ABC", "123", "A", "true" 없음

정수형과 실수형에는 여러 타입이 존재하므로 리터럴에 접미사를 붙여서 타입을 구분한다.  byte와 short타입의 리터럴은 별도로 존재하지 않고 int타입의 리터럴을 사용한다. long 타입의 경우 자바 1.7부터 long big = 100_000_000_000L; 처럼 구분자 _ 를 넣어 큰 숫자를 편하게 읽을 수 있게 됐다.

 

char타입의 경우 단 하나의 문자만으로 저장할 수 있고, 하나 이상의 문자가 존재해야 한다. String은 ""안에 아무런 문자도 넣지 않는 것을 허용하고 이를 빈 문자열이라 한다. 그러나 char 타입에 ' '처럼 공백 문자로 char 타입 변수를 초기화 할 수 있다.

 

String의 경우 클래스이므로 String name = "Java"; 로 사용가능하고 new 연산자로 String name = new String("Java");로 사용이 가능하다.

 

변수의 타입

변수를 선언할 때 변수에 저장할 값의 종류에 따라 변수의 타입을 선택해야 한다.

변수의 타입은 참조형과 8개의 기본형이 있다.

 

숫자

정수(integer) int int x = 100;
long 20억이 넘을 땐 long타입 사용
실수(floating-point number) double double pi = 3.14;
double은 15자리
float float는 오차없이 7자리

문자

문자(character, 문자 1개) char char ch = 'a';
문자열(string, 0개~n개 문자) String String str = "abc"; 

 

기본형과 참조형

값(data)의 종류(type)는 크게 문자와 숫자로 나눌 수 있고, 숫자는 정수와 실수로 나눌 수 있다.

그리고 값이 저장될 공간의 크기와 저장 형식을 정의한 것이 자료형(data type)이다.

 

자료형에는 문자형, 정수형, 실수형 등이 있고 변수를 선언할 때는 저장하려는 값의 특성을 고려해 가장 알맞는 자료형을 변수의 타입으로 선택한다.

 

* 참조형 변수는 변수 간의 연산을 할 수 없다. 실제 연산에 사용되는 것은 모두 기본형 변수이다.

더보기

기본형(primitive type) : 논리형(boolean), 문자형(char), 정수형(byte, short, int, long), 실수형(float, double)

기본형 변수는 실제 값(data)를 저장하며, 저장할 값(data)의 종류에 따라 구분되므로 기본형의 종류를 얘기할 때는 자료형(data type)이라는 용어를 쓴다.

 

참조형(reference type)  : 객체의 주소를 저장, 8개의 기본형을 제외한 나머지 타입

참조형 변수는 어떤 값이 저장되어 있는 주소(memory address)를 값으로 갖는다. 참조형은 항상 객체의 주소(4 byte 정수)를 저장하므로 값(data)이 아닌, 객체의 종류에 의해 구분되므로 참조형 변수의 종류를 구분할 때는 타입(type)이라는 용어를 사용한다.

 

타입이 자료형을 포함하는 보다 넓은 의미의 용어이므로 굳이 구분하지 않아도 된다.

 

기본형 종류와 범위

종류 자료형 저장 가능한 값의 범위 크기
bit          |           byte
                         
           
문자형 char '\u0000'~'\uffff' (0~2^16-1, 0~65535) 16 2 자바에서 유니코드(2byte 문자체계)를 사용하므로 2byte
논리형 bloolean false, true 8 1 true와 false 두 가지 값만 표현할 수 있으며 되도록 가장 작은 크기인 1byte
정수형 byte -128 ~ 127(-2^7 ~ 2^7-1) 8 1 정수형의 경우
-2^n-1 ~ 2^n-1(n은 bit 수)

크기가 1 byte라서 byte
int(4 byte)를 기준으로
짧아서 short(2byte)
길어서 long(8byte)

7~9자리 수를 계산할 때는 넉넉하게 long 타입(약 19자리)으로 변수를 선언하는 것이 좋다.
short -32,768 ~ 32,767(-2^15~2^15-1) 16 2
int -2,147,483,648 ~ 2,147,483,647(-2^31 ~ 2^31-1, 약 +-20억) 32 4
long -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807(-2^63 ~ 2^63 -1) 64 8
실수형 float 1.4E-45 ~ 3.4E38 (1.4x10^-45 ~ 3.4x10^38) 32 4 float는 실수값을 부동소수점(floating-point)방식으로 저장하기 때문에 float이고

double은 float 보다 두 배의 크기(8 byte)를 갖기 때문에 double

float와 double은 양의 범위만 적은 것으로 음의 범위에 음수부호를 붙이면 된다.
double 4.9E-324 ~ 1.8E308(4.9x10^-324~1.8x10^308) 64 8

 

정수형의 오버플로우(Overflow)

타입이 표현할 수 있는 값의 범위를 넘어서는 것을 오버플로우라한다.

(오버플로우가 발생했다고 해서 에러가 발생하는 것은 아님)

 

채널을 증가시키다가 마지막 채널에서 채널을 더 증가시키면 첫 번째 채널로 이동하고, 첫번쨰 채널에서 채널을 감소시키면 마지막 채널로 이동하는 것과 같이 정수형에서도 000에서 정방향으로 돌리면 0001이 되지만 역방향으로 돌리면 9999로 되는 개념이다.

 

더보기

최대값 + 1 = 최소값

최소값 - 1 = 최대값

정수형 타입이 표현할 수 있는 최대값에 1을 더하면 최소값이 되고, 최소값에서 1을 빼면 최대값이 된다.

 

부호가 있는 경우 없을 때와 최대값과 최소값의 범위가 달라서 오버플로우 발생시점 또한 다르다.

더보기

부호 있는 정수 : 부호비트가 0에서 1이 될 때 오버플루우 발생

부호 없는 정수 : 2진수로 0000이 될 때 오버플로우가 발생

부호없는 10진수 2진수 부호 있는 10진수
7 0111 7  : 최대값 (오버플로우 발생)
8 1000 -8 : 최소값
9 1001 -6
10 1010 -5
11 1011 -4
12 1100 -3
13 1101 -2
14 : 최대값  (오버플로우 발생) 1111 -1
15 : 최소값 0000 0

 

참조형 변수 String

자바에서는 문자열을 위한 클래스 String을 제공하고 있다. 문자열을 저장하고 이를 다루는데 필요한 메서드들도 함꼐 제공하고 있다.

 

① 변경이 물가능한(immutable) 클래스

String 클래스는 문자열을 저장하기 위해 문자형 배열 참조변수(char[]) value를 인스턴스 변수로 정의해놓고 있다.

인스턴스 생성 시 생성자를 매개변수로 입력받는 문자열은 인스턴스 변수(value)에 문자형 배열(char[])로 저장된다.

 

또한 String클래스는 앞에 final이 붙어 있으므로 다른 클래스의 조상이 될 수 없다.

 

public final class String implements java.io.Serializable, Comparable {
	private char[] value;
}

한번 생성된 String인스턴스가 갖고 있는 문자열은 읽어 올 수만 있고, 변경은 할 수 없다.

문자열끼리 + 연산자로 결합하는 경우에는 문자열이 바뀌는게 아닌, 새로운 값이 담긴 String 인스턴스가 생성되는 것이다.

* 연산 시 마다 새로운 문자열을 가진 String 인스턴스가 생성되어 메모리공간을 차지하게 되므로 가능한 결합횟수를 줄이는게 좋다.

 

문자열 간의 결합이나 추출 등 문자열을 다루는 작업이 많이 필요한 경우에는 String 클래스 대신 StringBuffer 클래스를 사용하는게 좋다. StringBuffer 인스턴스에 저장된 문자열은 변경이 가능하므로 하나의 StringBuffer 인스턴스만으로도 문자열을 다루는 것이 가능하다.

 

② String 사용하기

String을 사용할 때는 문자열 리터럴로 변수를 선언하는 것 처럼 사용할 수 있고 new 연산자로 생성자를 사용해서 만드는 방법이 있다.

 

  • String 클래스의 생성자
    new 연산자에 의해서 메모리할당이 이루어지기 때문에 항상 새로운 String인스턴스가 생성된다.
String str = new String("abc");

 

  • 문자열 리터럴
    이미 존재하는 것을 재사용 하는 것이다. 문자열 리터럴은 한번만 저장되며 마찬가지로 String 인스턴스이고,
    하나의 String 인스턴스가 생성된 후 참조변수가 그 String 인스턴스를 참조하게 된다.

클래스 파일이 클래스 로더에 의해 메모리에 올라갈 때, 클래스 파일의 리터럴들이 JVM내에 있는 상수 저장소에 저장된다.

String str = "abc";

equals()로 String 클래스 생성자로 만든 인스턴스 두개의 값을 비교할 경우 두 문자열의 내용까지 모두 비교하기 때문에 true로 나올 수 있지만, 등가 연산자인 == 로 비교하면 주소로 비교가 되기 때문에 false로 나올 수 있다. 단, 문자열 리터럴은 이미 존재하는 것을 재사용하는 것이기 때문에 ==로 비교할 경우에도 true가 나올 수 있다.

반응형