본문 바로가기
JAVA

1. JAVA의 자료형

by 김마리님 2020. 3. 17.

1. 정수형

정수형이 담을 수 있는 수는 비트 수 만큼 2의 제곱을 한다. 이 때, 이 경우의 수 안에 음수가 포함되기 때문에 담을 수 있는 최댓값/2로 보는 것이 옳다.

 

byte=1byte(-128~127)

★int=4byte

long=8byte

		byte num1 = -120;
		System.out.println(num1);
		int num2 = 1000000000;
		System.out.println(num2);
		long num3 = 10;
		System.out.println(num3);

다음과 같이 출력된다. 

숫자형의 주의할 점은, 형의 변환이다.

		int n1 = num1;

다음과 같은 형은 오류가 나지 않는다. 왜냐하면 int형의 크기가 byte형의 크기보다 크기 때문에, 들어갈 수 있기 때문이다. 

그러나,

		 byte n2= num2;

다음과 같은 경우는 오류가 난다. 왜냐면, 앞서 코드에서 num2는 int형(4byte)으로 지정되어 있기 때문에, 2byte인 byte 형으로 들어갈 수 없다. 마치 작은 상자는 큰 상자로 들어갈 수 있지만, 큰 상자는 작은 상자로 들어갈 수 없는 것과 같은 이치이다.

이것을 방지하기 위해, 

		byte n3 = (byte) num3;

과 같이 (괄호)안에 변환할 숫자형을 적는데, 이렇게 해서 강제적으로 크기를 늘이거나 줄인다. 이것을 캐스팅이라고 한다. 다음과 같은 경우는, long 정수형을 byte로 줄였기 때문에, 다운 캐스팅이라고 한다.

이 때 주의할 점은, 다운 캐스팅 시, 다운된 숫자형보다 값이 클 경우, 데이터가 유실될 수 있다.

 

정수형은 대체적으로 int를 사용한다. int보다 큰 경우 long을 사용한다.

 

 

2. 실수형

정수형이 담을 수 없는 소숫값을 나타낼 수 있다.

 

 

★double=8byte

float=4byte

 

 

double 자료형의 경우 4byte는 정수형, 4byte는 소숫점을 나타낼때 쓰인다. 

		double myNum=10.5;
		System.out.println(myNum);

 

다음과 같이 double 자료형을 입력하면 10.5의 값을 돌려받는다.

그렇다면 이 실수형을 정수형으로 다운캐스팅 하면 어떤 일이 벌어질까??

		int num1=(int)myNum;
		System.out.println(num1);

소수점이 있음에도 불구하고 소수점이 버려지고 10, 정수형으로 뜬다.

그렇다면 정수형을 실수형으로 나타내면 어떻게 될까?

		int num2=10;
		double num3=num2;
		System.out.println(num3);

다음과 같이 정수형임에도 소수가 나타나서 실수형처럼 나타난다.

 

 

3. 문자형

문자를 담을 수 있는 자료형이다. 이 때, 문자형은 문자 '하나'만을 담는 자료형이다.

 

char=2byte

 

2byte에서 알 수 있듯이 java는 문자의 출력을 UTF-8(조합형, 3byte)의 형태가 아닌 EUC-KR(완성형)의 형태를 이용한다.

문자형을 초기화 할 때는 ' '(작은따옴표)로 묶어서 초기화한다.

		char s1 ='가';
		System.out.println(s1);		
		s1='나';
		System.out.println(s1);

다음과 같이 글씨가 나타나게 된다.

이 때 3번째 줄부터는 자료형을 선언하지 않아도 된다. 위에서 s1 변수의 자료형을 char로 선언했기 때문이다.

왜 둘 다 다르게 나올까? 코드는 위에서부터 아래로 동작하기 때문에

s1상자에 '가'의 값을 넣음 -> 상자 안의 '가'를 보여줌 -> s1 상자 안에 '가'를 빼고 '나'를 넣음 -> 상자 속 '나'를 보여줌

의 순서로 적용되기 때문이다.

 

그렇다면, 문자들을 여러개 넣으려면 어떻게 해야할까?

가장 기본적인 방법으로는

		char c1='가';
		char c2='나';
		char c3='다';

		System.out.print(c1);
		System.out.print(c2);
		System.out.println(c3);

의 방법이 있을 것이다. 그러나 이 방법의 단점은 메모리 속 2byte 남는 부분 아무데나 집어넣어두고, 필요할때 꺼내쓰는 방식이기 때문에 연산이 느린 단점이 있다.

이를 방지하기 위해 다음과 같이 배열을 이용하여 나타내보자. 배열이란, 같은 타입의 자료형을 묶어놓은 덩어리를 말한다.

		char[] str= {'가','나','다'};
		System.out.print(str[0]);
		System.out.print(str[1]);
		System.out.print(str[2]);
		System.out.println();

와 같이 동일하게 출력되게 된다. 두 방법 다 동일하게 출력 되지만, 이 방법의 경우 메모리의 6byte가 남는 공간에 덩어리째로 저장해두었다가 필요할때 동시에 꺼내쓴다. 그렇기 때문에 메모리 공간 확보가 어렵지만 연산이 빠른 장점이 있다.

배열을 이용할 때, 이미 완성된 배열값에 새 배열을 집어넣을 수는 없다. 배열은 선언된 순간에 자신의 메모리 공간을 선언하기 때문이다. 그러나, 배열 내의 값을 바꾸는 것은 가능하다.

		str[0]='라';
		System.out.println(str[0]);

배열을 이용하는 가장 큰 단점은 배열의 크기를 미리 알아두어야 한다는 점이다. 배열이 클까봐 미리 큰 배열을 선언하면 선언한 크기만큼의 메모리 낭비가 생긴다.

이를 위한 문자열을 나타내는 자료형이 있다. 

 

 

4. 문자열

 

★String = 4byte

(이 때, string은 기본 자료형이 아닌, 일종의 class이기 때문에 대문자로 시작한다.)

 

String은 문자열이 얼만큼의 크기를 가지던 관계가 없기 때문이 가변적이다.

초기화 할때는 문자형과 다르게 문자열이기 때문에  " "(큰 따옴표)로 초기화한다.

		String s1="안녕하세요";
		System.out.println(s1);
		
		s1="반가워";
		System.out.println(s1);

다음과 같이 크기를 나타내지 않아도 얼마든지 문자열을 출력할 수 있다.

 

 

5. class 자료형

배열의 경우 반드시 같은 자료형이어야 한다는 단점이 있다. 하지만, 데이터의 자료형이 무조건 같을 수는 없다. 이를 위해 class로 자료를 묶고, 자료를 불러내는 방법이 있는데, 이것이 class 자료형이다.

class 자료형에는 두가지 방법이 있다.

 

1) static을 이용.

말했다시피 자바의 구동방법은 static 검색 후 로딩 -> main 검색 -> main 실행 -> 종료의 단계를 거친다. 그렇기 때문에 main이 시작하기 전에 미리 데이터가 있는 변수들을 초기화해두는 방법이다. 이 때, 사용할 class는 메인 밖에서 만든다.

class 동물{
	static String name="사자";
	static String color="노랑";
	static int speed=100;
	static char gender='여';
}

다음 main 함수 안에서 출력시켜보자.

 

public class VarEx05 {
	public static void main(String[] args) {
		System.out.println("동물 생성 준비");
		System.out.println(name);

이렇게 선언하면 오류가 생긴다. VarEx05 class 내부에는 name이라는 변수명이 없기 때문이다. main 밖의 class를 불러내기 위해서는 (클래스명).(변수명)을 이용해서 불러낸다.

 

public class VarEx05 {
	public static void main(String[] args) {
		System.out.println("동물 생성 준비");
		System.out.println(동물.name);
		System.out.println(동물.color);
		System.out.println(동물.speed);
		System.out.println(동물.gender);
		System.out.println(VarEx05.num);	
	}
}

다음과 같이 외부에서 초기화된 변수명도 main 내부로 불러올 수 있다.

 

2)heap를 이용.

하지만 static같은 경우는 단점이 있다. 프로그램이 로드 될 때 함께 초기화되고, 프로그램이 끝날 때까지 존재하다가 프로그램이 종료되야만 사라진다. 그렇기 때문에 class 자료형이 프로그램의 중간부터 필요한 경우라도, 프로그램의 시작부터 로드되기 때문에 메모리의 부하가 생긴다. 이를 막기 위해, class 자료를 heap에 넣어두고 중간부터 heap를 불러올 수 있다. heap는 개발자가 원하는 시점에 메모리를 띄울 수 있는 공간으로, new를 통해 heap를 띄울 수 있다. heap로 불러와진 데이터는 static로 로드된 데이터 외의 모든 데이터를 로드한다. 

예시는 다음과 같다.

class 동물{
	 String name="사자";
	 String color="노랑";
	 int speed=100;
	 char gender='여';
}

public class VarEx05 {
	public static void main(String[] args) {
		System.out.println("동물 생성 준비");
		
		동물 a=new 동물();
		System.out.println(a.color);
		System.out.println(a.name);
		System.out.println(a.speed);
		System.out.println(a.gender);
		
	}
}

main 내부에서 (클래스명) (변수)=new (클래스명)();

으로 불러낼 수 있다. 예시의 경우 동물 a=new 동물(); 로 불러내었다.

이에 따른 결과는

static으로 로드하는 것과 같은 결과를 가진다.

 

 

6. Object

데이터의 내용을 알 수 있으면 좋겠지만, 앞으로 들어올 데이터가 어떤 자료형을 가지고 있을지 모를 때에 사용하는 자료형이다.

		Object n1 = 1;
		Object n2 = '가';
		Object n3 = "문자열";
		Object n4 = 10.5;
		System.out.println(n1);
		System.out.println(n2);
		System.out.println(n3);
		System.out.println(n4);

초기화한 데이터가 그대로 나오게 된다.

하지만, Object 자료형 같은 경우 코드가 모호해진다는 단점이 있다. 자료형이 미리 선언된 경우는 각 변수 내에 어떠한 자료형이 들어가야하는지 미리 추측할 수 있지만, Object로 선언된 경우에는 들어가야할 자료형이 무엇일지 예상할수가 없어 특히 팀프로젝트 내에서 오류가 생길 수 있다. 따라서 사용을 지양하는 것이 좋다.

 

 

 

*call by value? call by reference?

int a=5;라는 값이 있다 가정하자. 이 값 같은 경우는 System.out.print(a)를 입력하면 a가 위치한 장소의 메모리를 바로 찾아 그 속의 5라는 데이터를 꺼낸다. 이렇게 변수의 위치에 자료가 함께 있어, 변수를 호출하면 바로 값이 나오는 것을 call by value 라고 한다. call by value로 값을 가져오는 자료형은 byte, int, long, short, double, float, borden, char. java의 기본 자료형들이며, 미리 메모리가 차지하는 값을 알고있는 경우이다.

그러나 String, Class 자료형, Object 같은 기본 자료형이 아니며, 값이 가변적이라 메모리를 어느정도 확보해야할지 모르는 경우 프로그램은 미리 넉넉한 공간에 자리를 지정해두고 받은 자료를 저장한다. 그리고, 변수명 위치에 값을 저장하는 것이 아닌, 값이 저장되어 있는 메모리 주소(포인터)를 정수의 형태로 넣어두는데, 이렇게 변수명 위치에 포인터가 들어있는 형태를 call by reference라고 한다. 이 때, 포인터를 정수의 형태 중 int 형태로 지정해두기 때문에 call by reference의 형태를 가지는 자료형들은 4byte의 메모리 값을 가진다.

 

반응형

'JAVA' 카테고리의 다른 글

3. 조건문  (0) 2020.03.20
2. JAVA의 연산  (0) 2020.03.20
IntelliJ 키맵을 이용한 단축키  (0) 2020.03.17
STS 설정하기  (0) 2020.03.16
java의 기초(1)  (0) 2020.03.16