변수

박진선·2022년 11월 4일
0

1. 변수의 종류

class Example {
	Example(int lv){
    	this.iv = lv;
    }
	int static cv;
    int iv
    
	public void test() {
		int lv;
	}
}

변수의 종류는 선언 위치에 따라 달라지는데 클래스변수, 인스턴스변수, 지역변수로 나눌 수 있다

클래스변수(Class Variable)

  • 변수 cv와 같이 static키워드가 붙고 클래스 영역에 선언된 변수를 뜻하며, Example 클래스를 여러번 인스턴스화 시켜도 서로 같은값을 공유한다. 즉 모든 인스턴스가 공통된 메모리주소를 공유하게 됨
  • 인스턴스를 생성하지 않고도 Example.cv 형태로 접근이 가능한데 그 이유는 프로그램 실행 중에 어떤 클래스를 만나게 되면, JVM은 ClassLoader를 시켜 해당 클래스의 바이트코드를 읽어서 클래스에 대한 정보를 Method Area에 저장하여 그 때 클래스 멤버도 같이 메모리에 올라게 된다, 이와 같은 이유로 인스턴스를 생성하지 않고도 사용이 가능하다, 자세한 내용은 다음 자바의 메모리 구조에서 다룰 예정이다

인스턴스변수(Instance Variable)

  • 변수 iv와 같이 클래스 영역에 선언된 변수를 뜻하며, 해당 클래스의 인스턴스가 생성될 때 변수가 메모리에 올라가기 때문에 인스턴스를 생성해야 접근이 가능하다.
  • 인스턴스마다 별도의 저장공간을 가지므로 서로 다른 값을 가질 수 있다.

지역 변수(local variable)

  • 생성자 매개변수 lv와 test 메소드 내부 변수 lv와 같이 클래스 영역 이외의 영역
    (메소드, 생성자, 초기화 블럭 내부)에 선언된 변수를 뜻하며, Stack Area에 생성되어 해당 메소드 내부에서만 사용이 가능하며 메소드가 종료되면 소멸된다.

2. 변수의 타입

class Example {
	//정수형
	byte b;
    short s;
	int i;
    long l;
    //실수형
    float f;
    double d;
    //문자형
    char c;
    //논리형
    boolean b;
    

기본형 타입(primitive Type)

  • 모든 기본형 타입은 실제 값(데이터)을 변수에 저장한다.

  • 정수형은 byte, short, int, long 이 있으며 모든 정수는 기본적으로 int형으로 나타내고 int형을 초과하는 값을 long타입에 대입하려면 접미사L 을 반드시 붙여주어야 하고 그 이하의 값은 생략이 가능하다. 이외에 byte, short타입은 int타입의 정수를 사용하기 때문에 접미사는 필요 없다.

long l = 10; //접미사 L 생략가능
long l2 = 2200000000L; // int형을 초과하는 값이기에 접미사 L 생략 불가
  • 실수형은 float, double 이 있으며, 모든 실수는 기본적으로 double형으로 나타내기 때문에 float 타입의 변수에 값을 대입하려면 접미사 F 를 붙여주어야 한다.
double d = 0.1;
float f = 0.1F; // 접미사 F 생략 불가
  • 문자형은 char 하나 이며 char에 저장된 값은 실제로는 숫자를 가르킨다, 즉 값을 대입하기 위해 다음 3가지 방법으로 값을 대입할 수 있다
char testchar = 'c'; // 단일 문자열
char testascii = 99; // 아스키코드(문자열의 숫자값)
char testunicode = '\u0063'; // 유니코드값(문자열 맵핑 공간)
  • 논리형은 boolean 하나 이며 참(true), 거짓(false)의 값을 갖는다.
    참과 거짓을 표현하기 위해서는 1bit만 있으면 되지만, JVM이 다룰 수 있는 데이터의 최소 단위가 1byte이기 때문에 1byte(8bit)의 크기를 가진다.

타입별 크기

데이터 타입저장 가능한 값의 범위byte
booleanfalse, true1
char'\u0000' ~ '\uffff' (0 ~ 65535)2
byte-128 ~ 1271
short-32768 ~ 327672
int-2147483648 ~ 21474836474
long-9223372036854775808 ~ 92233720368547758078
float1.4E-45 ~ 3.4E384
double4.9E-324 ~ 1.8E3088

오버플로우 : 자료형이 표현할 수 있는 범위 중 최대값 이상의 값을 표현한 경우 발생한다.
최대값을 넘어가면 해당 데이터 타입의 최소값으로 값이 순환됨
예) byte형의 최대값인 127 을 가지는 변수에 +1을 할 경우 최소값인 -128이 됨
언더플로우 : 자료형이 표현할 수 있는 범위 중 최소값 이하의 값을 표현한 경우 발생한다.
최소값을 넘어가면 해당 데이터 타입의 최대값으로 값이 순환됨
예) byte형의 최소값인 -128 을 가지는 변수에 -1을 할 경우 최대값인 127이 됨

기본형 타입 변환

  • boolean 타입을 제외한 primitive 변수타입들 끼리는 형변환이 가능함 char, byte, short, int, long, float, double

  • 자동 타입 변환 : 바이트 크기가 작은 타입에서 큰 타입으로 변환할 때 (예 : byte → int), 덜 정밀한 타입에서 더 정밀한 타입으로 변환할 때 (예 : 정수 → 실수)
    byte(1) -> short(2)/char(2) -> int(4) -> long(8) -> float(4) -> double(8) 화살표를 기준으로 좌측의 타입이 우측의 타입으로 자동으로 변환될 수 있다.
    float 의 경우 int와 long 보다 크기가 작거나 같지만 표현할 수 있는 값이 정수형 보다 정밀하기 때문에 더 뒤쪽에 있음

  • 수동 타입 변환 : 메모리 용량이 더 큰 타입에서 작은 타입으로는 자동으로 타입이 변환되지 않음, 수동으로 타입을 변환 casting(캐스팅) 해주어야 함
    예) int i = 128; byte b = (byte)i; int타입이 byte타입 보다 데이터 크기가 크기 때문에 캐스팅이 필요함, 예시의 경우 btye의 최대크기는 127 이기 때문에 오버플로우가 발생하여 -128이 대입됨

참조형 타입(Reference Type)

  • 참조 타입은 기본 타입을 제외한 타입으로, 객체의 주소를 저장하는 타입이다. 문자열, 배열, 열거형 상수, 클래스, 인터페이스 등이 있다. 실제 객체는 Heap Area 에 저장되며, 참조 타입 변수는 실제 객체의 주소를 JVM Stack Area에 저장한다. 그리고 객체를 사용할 때마다 참조 변수에 저장된 객체의 주소를 불러와 사용하게 된다.

  • test라는 이름의 메모리 공간이 스택 영역에 생성되고, 생성된 test의 인스턴스는 힙 영역에 생성된다. 즉, 스택 영역에 생성된 참조 변수 test는 힙 영역에 생성된 test의 인스턴스 주소 값을 가지게 된다.

Test test = new Test();

기본형과 참조형의 차이

  • 성능
    기본형 타입은 스택 영역에 존재한다. 반면 참조 타입은 스택 영역에는 참조 값만 있고, 실제 값은 힙 영역에 존재한다. 참조 타입은 최소 2번 메모리 접근을 해야 하고, 일부 타입의 경우 값을 필요로 할 때 언박싱 과정(ex. Double → double, Integer → int)을 거쳐야 하므로 원시 타입과 비교해서 접근 속도가 느린 편이다.
  • 메모리
    기본형 타입보다 참조 타입이 사용하는 메모리 양이 압도적으로 높다. 이외의 참조 타입은 최근 들어 64 비트의 JVM을 많이 사용하므로 일반적으로 64 bits를 차지한다고 한다.
  • 초기값
    기본형 타입은 null을 담을 수 없지만, 참조 타입은 null을 담을 수 있다. 이것은 원시 타입의 경우, 값이 없으면 디폴트 값을 반환하기 때문이다. (ex. int은 0, boolean은 false)

처음 블로깅을 해보는데 쉽지만은 않다🤣 메모장에 정리하는 것 보다 코드를 입력할 수 있고 어디서든 볼 수 있는 장점이 있어 맘에든다 앞으로 적극적으로 블로깅을 해볼 생각이다

2022.11.04 17:08 첫번째 작성일

profile
주니어 개발자 입니다

0개의 댓글