본문 바로가기

java

[java/기본]3. 변수&자료 타입(원시 자료 타입, 참조형 자료 타입), null, 소멸자

변수

데이터를 할당하는 공간이다.

 

public class Main {
	public static void main(String[] args) {
		//선언
        int b;

        
        //초기화
		int a = 1;
		String c=null;
		System.out.println(a);
        
        // 오류 발생
		System.out.println(b);
        
        //초기화
		b=1;
        
        //재할당
        a=10;
        
	}

}

 

새 변수 만들기

선언

자료 타입과 변수 이름만 명시하는 것이다

 

초기화

할당 연산자로 값을 할당하는 것이다.

 

선언과 초기화는 동시에 할 수도 있고  선언만 할 수도 있다.

변수를 선언하고 초기화한다는 건 메모리에 변수를 할당하고 미리 비트를 할당한다.

값을 준다는 건 할당된 비트에 맞게 값을 채워 넣는 것이다.

예컨대, int 자료타입 변수는 메모리에서 4바이트를 할당한다.

1바이트는 8비트이고 비트는 0과 1만 표현가능한 이진수이다. 

따라서 여기에 1을 넣으면, 00000000 00000000 00000000 00000001이 할당된다.

 

재할당

초기화된 변수에 새롭게 값을 할당하는 것

 

변수와 변수 간에도 할당이 가능하며, 이 때는 동일한 자료형 간에만 가능하다.

 

자료형1: 원시자료형


자료형은 원시자료형(primitive data type)과 참조자료형(reference data type)으로 구분

 

원시자료형

변수에 할당된 메모리에 값을 직접 저장한다.

정수, 실수, 불리언 타입이 해당함.

 

참조자료형

변수에 직접 데이터가 저장되는 대신, 데이터가 저장된 주소만을 메모리에 저장한다.

이를 참조 주소, 레퍼런스라고 한다. 레퍼런스는 항상 4바이트로 고정이다.

 

정수형

할당되는 바이트 갯수에 따라 구분된다.

 

byte 1바이트(8비트)

short 2바이트

 

char 2바이트

숫자값을 ASCII코드의 문자로 변환한다.

즉, 숫자 타입이지만 문자로 변환이 되는 것이다.

문자열로 변환할 수는 없다.

char a = 80;
char b = 'a';
        
// P 출력
System.out.println(a);

// b 출력
System.out.println(b);

숫자 대신, ASCII코드의 변환값을 바로 입력해도 된다.

단, 작은 따옴표로 감싸야 하며, 큰 따옴표는 안된다.

 

int 4바이트

정수형 중에서 일반적으로 가장 많이 사용한다.

실생활에서 사용되는 숫자의 대부분을 표현할 수 있다.

 

long 8바이트

정말 큰 숫자를 표현할 때 사용한다.

 

비트로 숫자 표현
제일 왼쪽 비트는 음수와 양수 표현를 표현하는 데 사용된다.
n비트는 2의 n-1승 -1 만큼 숫자 표현이 가능하다.
예컨대, 1바이트인 byte 타입은 8비트이므로 2의 7승-1부터 –2의 7승 -1까지 표현가능하다.

그 이상은 오버플로우며, 이는 컴파일 단계에서 오류 검사

 

실수형

정수도 표현가능하지만 공간 낭비이다.

정수형이랑 실수형 간에는 ==동등 비교 연산자로 비교가능하다.

 

float 4바이트

표현 방법

float a =1.1f

처럼 접미사로 f붙이면 됨

붙이지 않으면 자동으로 double

 

double 8바이트

일반적으로 많이 사용하다.

double을 기본으로 사용하는 이유는 정밀성과 c, c#과의 호환성 고려때문이다. (이들이 double을 기본 사용함)

 

논리형

bolean 1바이트

true, false를 할당가능하다.

 

할당과 형변환, 오버플로우

변수 간에는 서로 할당이 가능하다.

 

묵시적 형변환

작은 바이트에서 큰 바이트로는 할당 가능

반대는 불가

byte c =2;

short b =c;

int a=b;

// 여기서 에러
short x =a;

 

명시적 형변환

큰 바이트에서 작은 바이트로 이동할 때 사용한다.

 

서로 같은 자료형이지만 타입이 다를 경우, 명시적인 형변환으로 할당이 가능하다.

단, 이때 오버플로우를 조심해야 한다.

오버플로우란, 데이터를 큰 곳에서 작은 곳으로 옮길 때 바이트가 모자라서 남는 비트를 버리며 데이터가 변형되는 현상이다.

byte u=1;
char a = 1000;

// 명시적인 형변환을 사용했다.
// byte에는 127~-127까지만 저장가능하다. 오버플로우가 발생했다.
u=(byte)a;

// -24출력
System.out.println(u);

실수형에서 정수형으로 데이터를 할당할 때에도 동일한 데이터 변형 문제를 겪을 수 있다.

그러니 가능하면 이런 데이터 타입 변환은 조심해야 한다.

일반적으로는 처음부터 int, double 같은 넉넉한 바이트 자료형을 사용한다.

 

자료형2: 참조자료형/객체


변수에 직접 데이터가 저장되는 대신, 데이터가 저장된 주소만을 메모리에 저장한다.

이를 참조 주소, 레퍼런스라고 한다. 레퍼런스는 항상 4바이트로 고정이다.

String, Arrays, ArrayList, Vector 등등 아주 다양하다.

 

String 

문자열을 담는 자료형이다.

일반적으로 객체는 new String("hi"); 처럼 new 키워드로 생성한다.

하지만, string은 자주 사용되는 형식이라 특별히 

String a = "hi"; 같은 방식으로 처리 가능하다.

 

두 방식은 동일해보이지만, 작동방식에 조금 차이가 있다.
new String("hi")는 새 메모리에 hi를 할당한다.
반면
String a = "hi"는 상수 풀에 hi를 생성하고 a가 이를 참조한다. 
이 차이는 다음 코드를 보자.

객체는 비교 시, 두 변수의 주소값을 비교한다.
두 객체의 값이 동일해도 주소값이 다르면 다른 걸로 간주한다.
String a = "hi";
String b = "hi";

//true, 주소값 동일
System.out.println(a==b);

String c = new String( "by");
String d = new String( "by");
//false, 주소값이 서로 다름
System.out.println(c==d);

//true. 
System.out.println(c.equals(d));

 

메모리 관리와 null


객체는 참조형 자료 타입이므로 객체 자료를 담은 두 변수를 비교할 시 메모리 주소를 비교한다.

따라서 내부 값이 동일하여도 주소가 다르면 동등연산자(==)의 비교에서 false가 나온다.

 

객체는 자신을 참조하는 변수가 없을 경우 가비지 콜렉터에 의해 수거된다.

즉, 메모리에 할당된 객체를 삭제하거나 덮어 쓴다.

 

null

레퍼런스(변수)를 초기화하거나 재할당하여 객체와 연결을 끊는 데 사용한다.

null이 할당된 변수에 도트 접근자로 참조하려는 경우 NullPointerException 에러가 발생한다.

com1 =null

 

 

 

소멸자


finalize와 수거 과정

가비지 콜렉터는 수거될 객체에게서 finalize()라는 메소드를 실행시키고 이를 통해 소멸한다,

 

확인해보기

클래스에 finalize 메소드를 오버라이드한다.

이후, 객체 인스턴스를 생성하고 null로  레퍼런스를 끊은 후 System.gc()로 빠른 수거를 요청하면 finalize 메소드가 실행된다.

public class LottoGame {
public LottoGame() {
	System.out.println("init");
}

// 오버라이팅
public void finalize() {
System.out.println("finalize");
}

}


public class Main {
public static void main(String[] args) {
	LottoGame lottoGame =new LottoGame("charchar");

// 객체와 연결 끊기
lottoGame = null;
System.gc();

	}
}

// 출력
// init
// finalize

 

System.gc();
가비지 콜렉팅이 빨리 작동하도록 요청한다.
단, 호출 시점에서 바로 작동하진 않는다.

 

(단, 둘 다 개발자가 직접 자주 사용하진 않음)

 

 

단축키
ctrl + space
작성하던 코드의 자동완성 지원

alt space 화살표 
코드 복사

alt 화살표
코드 이동

ctrl d
코드 삭제