본문 바로가기

자바(JAVA)
[자바(Java)] 변수, 리터럴, 데이터 형, 형변환

//JVM

- method 영역 : 상수, 정적 필드(static 키워드가 붙은 것), 메서드 코드, 생성자 코드
- stack 영역
- heap 영역 : 객체, 배열이 생성되는 장소


// 변수

- 변화가 있는 데이터

- 개발자가 명령어를 사용해서 메모리에 할당 받은 공간

- 그 공간에 이름을 붙여 놓음.

- 변수명 만들기 > 모든 이름을 생성할 때의 규칙
    1. 영문자 + 숫자 + 특수문자(_)
    2. 숫자로 시작 불가능

- 변수명은 중복될 수 없다. > 유일해야 한다.
    ~ 뒤에 숫자를 붙이는 방법은 비권장.

- 그룹 선언 및 초기화가 가능하다.
    ~ int eng1, eng2, eng3;
    ~ int eng1 = 100, eng2 = 90, eng3 = 80;
    ~ int eng1 = 100, eng2, eng3;

1. 생성하기(선언하기)
    - 자료형 변수명;
        ~ int number;
        ~ char ch;
        ~ boolean isWeekDay;

2. 초기화하기
    - 변수명 = 값;
        ~ number = 10;
        ~ ch = 'h';
        ~ isWeekDay = true;

2.5 치환하기(기존의 데이터에 덮어쓰기)
    - 변수명 = 값;
        ~ number = 14;
        ~ ch = 's';
        ~ isWeekDay = false;

3. 사용하기(입출력)
    - System.out.println(number);


//변수 명명법 패턴

1. 헝가리언 표기법
    - 식별자를 만들 때 식별자의 접두어로 해당 자료형을 표시하는 방법
        ~ int int_engscore;
        ~ int intEngscore;
        ~ int iEngscore;

2. 파스칼 표기법
    - 식별자 단어의 첫문자를 대문자로 표기 + 나머지 문자는 소문자로 표기
    - 2개 이상의 단어로 만든 합성어 > 각 단어의 첫문자를 대문자로 표기
        ~ int EngScore;
    ※자바에서 클래스명에 주로 사용

3. 캐멀 표기법
    - 식별자 단어의 첫문자를 소문자로 표기 + 나머지 문자도 소문자로 표기
    - 2개 이상의 단어로 만든 합성어 > 각 단어의 첫문자를 대문자로 표기
        ~ int engScore;
        ~ int myEngScore;
    ※자바에서 메서드명, 변수명에 주로 사용

4. 스네이크 표기법
    - 되도록 전부 소문자로 표기
    - 2개 이상의 단어를 언더바(_)로 연결
        ~ int eng_score;

5. 케밥 표기법
    - 2개 이상의 단어를 하이픈(-)으로 연결 ※자바는 '-'를 연산자로 인식하기 때문에 사용 불가!
        ~ int eng-score;


// 변수의 종류

1. 지역 변수(로컬 변수)
- 메서드를 호출해서만 사용할 수 있음.
   ~ 메서드를 호출하려면 객체의 도움 필요( 객체.메서드() )
- 메서드에 의해 메모리에 할당됨.
- {} 안에 있다.
- 일반적으로 사용자가 선언과 동시에 변수 초기화를 해주어야 함.
- 장점: 메모리의 효율성이 높다.
- 단점: 사용이 불편하다.

2. 전역 변수(클래스 변수, 인스턴스 변수)
- 클래스가 가지고 있는 변수
- 클래스에 의해 메모리에 할당됨.
- {} 밖에 있다.
- 선언을 해주면 자동으로 초기화 된다.
- 장점: 사용이 편하다.
- 단점: 메모리의 효율성이 떨어진다.  =>  사용을 최소화 하는 것이 좋다.

public class Exam01 {
	static int a = 50; //전역변수
	
	static void method1() {
		int a = 100; //지역변수
		System.out.printf("method1()의 a값은 : %d\n", a);
	}

	public static void main(String[] args) {
		method1();
		System.out.printf("main()의 a값은 : %d\n", a);
			
	}

}


3. 레퍼런스 변수

** 전역변수와 지역변수의 이름이 같을 때는, 지역 변수가 우선!!!!!


//자바의 정수 리터럴
- 자바는 어떤 기수법으로 데이터를 작성하든지, 출력할 때는 무조건 10진수로 출력된다.

1. 10진수
- 0~9
- 0123456789

2. 8진수
- 0~7
- 01234567

3. 16진수
- 0~F
- 0123456789ABCDEF
- 0xNNNN


package com.test.lambda;

public class Ex89_lambda {

	public static void main(String[] args) {

		m1();

	} //main

	private static void m1() {
		
		int jumin = 980228;
		System.out.println("주민등록번호: " + jumin);
		
		int jumin2 = 020225;
		System.out.println("주민등록번호: " + jumin2);
		
		int color = 0xFF;
		System.out.println(color);
		
	}
	
}

// 상수, final

- 상수명은 반드시 모두 대문자로 작성한다.

~ final double PI = 3.14; //읽기 전용 변수

- 적용 가능 범위
    1. 변수
        - 지역 변수
        - 멤버 변수
        - 변수값 수정 금지 > 안정성

    2. 메서드
        - 상속 + 오버라이딩
        - 오버라이딩 금지 > 안정성

    3. 클래스
        - 상속
        - 상속 금지 > 안정성


// DataType(데이터 형)
- 기본 타입과 참조 타입을 나누는 기준: 저장되는 값

<기본 타입>
1. 정수 타입 - short, int, long, byte
2. 실수 타입 - float, double
3. 논리 타입 - boolean(true/false)
4. 문자 타입 - char
 
int a = 10;
double grade = 82.5;

a. 숫자형
    1. 정수형
        a. byte 
            - 1byte
            - -128 ~ 127

        b. short 
            - 2byte
            - -32768 ~ 32767

        c. int★★
            - 4byte
            - -21억 ~ 21억

        d. long★
            - 8byte
            - -922경 ~ 922경

    2. 실수형
        a. float
            - 4byte
            - 단정도형(정밀도 > 유효 숫자를 저장할 범위)

        b. double★★
            - 8byte
            - 배정도형

b. 문자형
    1. 문자형
        a. char
            - 문자 저장
            - 1byte > 아스키코드(ASCII)
            - 2byte > 유니코드

c. 논리형
    1. 논리형
        a. boolean
            - 명제 > 참/거짓 (true/false > 예약 상수)
            - 1byte

<참조 타입>
1. 배열 타입
2. 클래스 (String)
3. 인터페이스
4. 열거 타입

String name = "길동";
String name1 = "순신";

Wrapper Class DataType
Integer int
Long long
Float float
Double double

// 자료형 type

1. 값의 전달(call by value) : 기본형/원시형/값형 타입(Primitive Type)

- 기본 타입은 변수 이름에 값을 저장한다.

- stack

- 복사본의 값을 변경해도 원본의 값은 변하지 않는다.


2. 주소의 전달(call by reference) : 참조형 타입(Reference Type)

- 참조 타입은 변수 이름에 주소를 저한다.

- heap

- 같은 주소값을 가지기 때문에 복사본의 값을 변경하면 원본의 값도 변한다.

기본형 타입 vs 참조형 타입

 

package ex01.sample01;

class MyChar{ // 클래스 선언
	char x; 
	char y;
}

public class Exam1004_2 { 
	static void func1(char x, char y) {
		char temp;
		temp = x; 
		x = y;
		y = temp; 
	}
	
	static void func2(MyChar ch) {
		char temp;
		temp = ch.x; // temp = 'A'
		ch.x = ch.y; // ch.x = 'X'
		ch.y = temp; // ch.y = 'A'
	}
	
	public static void main(String[] args ) {
		char x = 'A', y = 'Z'; // 기본형 변수
		System.out.printf("실행 전의 값은 : x = %c, y = %c \n", x, y);
		func1(x,y);
		System.out.printf("실행 후의 값은 : x = %c, y = %c \n", x, y);
		
		MyChar ch = new MyChar();
		ch.x = 'A'; //참조형 변수
		ch.y = 'X';
		System.out.printf("실행 전의 값은 : x = %c, y = %c \n", ch.x, ch.y);
		func2(ch);
		System.out.printf("실행 후의 값은 : x = %c, y = %c \n", ch.x, ch.y);
				
	}

}

변수 익히기

public class Example0915 {
	public static void main(String[] args) {
		int num1; //num1 정수형 변수 선언 
		int num2;
		int result;
		
		/*
		int num1, num2;
		int result; 
		라고 선언해도 가능!(같은 데이터 형끼리 묶어서)
		
		int num1, num2, result; 처럼은 잘 안 씀
		*/
		
		num1 = 100;
		num2 = 200;
		
		result = num1 + num2;
		System.out.println(num1 + "+" + num2 + "=" + result);
		
		result = num1 - num2;
		System.out.println(num1 + "-" + num2 + "=" + result);
		
		result = num1 * num2;
		System.out.println(num1 + "*" + num2 + "=" + result);
		
		result = num1 / num2;
		System.out.println(num1 + "/" + num2 + "=" + result);
		
	}

}

// (자료)형변환, Casting, Data Type Casting

- 하나의 자료형을 또다른 자료형으로 변환하는 작업

- 코드 작성을 유연하게 하기 위해서 사용

- 값형끼리만 가능(boolean 제외)

- byte, short, int, long, folat, double, char

- 정수와 실수 간의 크기 비교는 단순하게 물리 크기인 byte로 계산하는 게 아니라, 실제 표현 가능한 숫자의 범위로 비교해야 한다.
    ~ byte(1) < short(2) < int(4) < long(8) <<<<< float(4) < double(8)

- char: 문자코드 값 > 실제로는 숫자 자료형.
    ~ char를 문자코드로 변환하려면 int를 사용해야 한다.

- 기본형과 참조형 간에는 형변환이 절대 불가능!!

1. 기본형 형변환
    a. 암시적 형변환(implicit type casting)
        - 큰형 = 작은형
        ~ long number = 5;

    b. 명시적 형변환(explicit type casting)
        - 작은형 = 큰형
        - (자료형) > 형변환 연산자
        ~ byte number = (byte)1000;
        - 에러가 발생하지 않기 때문에 더욱 위험! > 원본의 값이 복사본의 영역을 벗어나는지 항상 확인해야 한다.
        ※ 오버플로우(overflow): 명시적 형변환 시 발생하는 데이터가 넘치는 현상 (아래로 넘치는 현상: 언더플로우(underflow))
            > 오버플로우가 발생할 만한 상황을 미리 예측하고 관리하는 것이 필수

2. 참조형 형변환
    - 상속 관계에 있는 클래스끼리의 형변환 > 직계만 가능(방계는 불가능)

    a. 업캐스팅, Up Casting
        - 암시적인 형변환
        - 100% 안전
        - 자식 클래스 > 부모 클래스
        - 부모 클래스 = 자식 클래스;
        - 형변환은 되지만, 자식 클래스에는 있고 부모 클래스엔 없는 메서드는 호출할 수 없다.
                > 자식 클래스에 있는 메서드를 사용하고 싶다면, 부모 클래스에서 같은 이름의 메서드의 구현부를 비우고 선언한다. > 오버라이딩 기능 이용

    b. 다운캐스팅, Down Casting
        - 명시적인 형변환
        - 다운캐스팅만 하는 것은 100% 불가능하지만 업캐스팅 후 다시 다운캐스팅 하는 경우는 가능
                > 평소에는 형제들과 같이 부모 배열에 넣어서 관리하다가 자식만이 가지는 고유 기능을 사용해야 할 때 다운 캐스팅을 사용해서 원래 타입 참조 변수로 형변환
        - 부모 클래스 > 자식 클래스
        - 자식 클래스 = 부모 클래스


package com.test.java;

public class Ex15_Casting {
    public static void main(String[] args) {

	int n1;
	int n2;

	n1 = 100; // 100이라는 데이터를 n1이라는 공간에 넣어라(오른쪽에서 왼쪽으로 할당)
	n2 = n1; // n1이라는 공간의 데이터를 가져와서, n2라는 공간에 넣어라(변수끼리의 복사)

	System.out.println(n2);

	//암시적 형변환

	short a = 10;	//2byte, 원본
	int b;		//4byte, 복사본

	b = a; //b = (int)a; > short였던 a가 자동으로 int a로 바뀐 후 b에 대입
	System.out.printf("b = %d\n",b);


	int c = 200;
	long d;

	d = c;

	System.out.printf("d = %d\n", d);

	//명시적 형변환 > 형변환 연산자 생략 불가

	int e = 32767;	//4byte, 원본
	short f;	//2byte, 복사본

	f = (short) e;
	System.out.printf("f = %d\n", f);


	long g = 3000000000L;
	int h;

	h = (int) g;
	System.out.printf("h = %d\n", h);

    }
}

package com.test.java;

public class Ex16_Casting {
    public static void main(String[] args) {

	//정수형 리터럴: int
	//실수형 리터럴: double
	//대입 연산자는 좌우 자료형이 동일해야 함

	byte m1 = 10;	//byte = int > 명시적 형변환을 해야하는 상황이지만 예외적으로 암시적 형변환이 되도록 처리해줌

	short m2 = 10;	//short = int > 명시적 형변환을 해야하는 상황이지만 예외적으로 암시적 형변환이 되도록 처리해줌

	int m3 = 10;	//int = int

	long m4 = 10;	//long = int > 암시적 형변환


	float f1 = 3.14F; //float f1 = (float)3.14;

	double f2 = 3.14; //double = double


	// 정수 <-> 실수
	long n1 = 100;	//원본 (8byte)
	float n2;	//복사 (4byte)

	n2 = n1 + 1F; //암시적 형변환 - float이 long보다 큼.
	System.out.printf("n2 = %f\n", n2);


	double n3 = 3.14;
	int n4;

	n4 = (int)n3; //소수점 이하 절삭

	System.out.println(n4);

	System.out.printf("A의 문자코드: %d\n",(int)'A');
	System.out.printf("Z의 문자코드: %d\n",(int)'Z');

	System.out.printf("a의 문자코드: %d\n",(int)'a');
	System.out.printf("z의 문자코드: %d\n",(int)'z');

	System.out.printf("0의 문자코드: %d\n",(int)'0');
	System.out.printf("9의 문자코드: %d\n",(int)'9');

    }
}