변수

kailyn·2024년 8월 14일

JAVA

목록 보기
1/17

1. 리터럴

1. 리터럴 개요

1-1. 리터럴이란?

💡 리터럴(literal)이란 변하지 않는 데이터 그 자체를 말한다. 상수와 혼동할 수 있지만 상수는 데이터가 저장되는 메모리상의 공간을 의미하고, 리터럴은 고정된 값 자체를 의미한다.
int age = 20;                // 20은 리터럴이다.
final int MAX_AGE = 100;     // 100은 리터럴이다. (MAX_AGE는 상수이다.)
String str = "java"          // "text"는 리터럴이다.

1-2. 리터럴의 종류


2. 리터럴 활용

2-1. 리터럴 출력

  1. 숫자 형태의 값 출력

    System.out.println(123);
    System.out.println(1.23);
    • 실행결과
      123
      1.23
  2. 문자 형태의 값 출력

    System.out.println('a');			     //문자 형태의 값은 홑따옴표(single-quotation)으로 감싸주어야 한다.
    //System.out.println('ab');			   //두 개 이상은 문자로 취급하지 않기 때문에 에러가 발생한다.
    //System.out.println('');			     //아무 문자도 기록되지 않는 경우도 에러가 발생한다.
    System.out.println('1');			     //숫자 값 이지만 홑따옴표로 감싸져 있는 경우 문자 '1'이라고 판단한다.
    • 실행결과
      a
      1
  3. 문자열 형태의 값 출력

    System.out.println("안녕하세요");		//문자열은 문자 여러 개가 나열된 형태를 말하며 쌍따옴표(double-quotation)으로 감싸주어야 한다.
    System.out.println("123");			    //정수 이지만 쌍따옴표로 감싸져있기 때문에 문자열로 보아야 한다.
    System.out.println("");				      //아무 값도 없는 빈 쌍따옴표도 문자열로 취급한다.
    System.out.println("a");			      //한 개의 문자도 쌍따옴표로 감싸면 문자열이다. (문자 a와는 다르다)
    • 실행결과
      안녕하세요
      123
      
      a
  4. 논리 형태의 값 출력

    System.out.println(true);
    System.out.println(false);			    //true 혹은 false 값을 논리형이라고 한다.
    • 실행결과
      true
      false

2-2. 숫자 리터럴의 연산

💡 숫자 리터럴은 모든 사칙 연산을 다 사용할 수 있으며, 정수 끼리의 연산 실행 결과는 정수로, 실수 끼리의 연산 실행 결과는 실수로 나온다. 단, 정수와 실수의 연산 실행 결과는 항상 실수로 나온다.
  1. 정수와 정수의 연산

    System.out.println(123 + 456);
    System.out.println(123 - 23);
    System.out.println(123 * 10);
    System.out.println(123 / 10);
    System.out.println(123 % 10);
    • 실행결과
      579
      100
      1230
      12
      3
  2. 실수와 실수의 연산

    실수 연산에서 오차가 생기는 이유는 실수를 표현하는 방식이 부동소수점 방식이기 때문이다.

    부동소수점(floating-point)이란 소수점 이하의 위치를 고정하지 않고 가수와 지수로 나타내는 방식의 실수 표현 방식을 말한다. 이러한 방식은 정확한 실수 표현이 어렵기 때문에, 연산 결과에 약간의 오차가 발생할 수 있다.

    System.out.println(1.23 + 1.23);
    System.out.println(1.23 - 0.23);
    System.out.println(1.23 * 10.0);
    System.out.println(1.23 / 10.0);
    System.out.println(1.23 % 1.0);			//약간의 오차가 생긴다
    • 실행결과
      2.46
      1.0
      12.3
      0.123
      0.22999999999999998
  3. 정수와 실수의 연산

    연산은 피연산자의 데이터가 서로 일치하는 형태의 데이터끼리 연산이 가능하다. (즉, 정수는 정수끼리, 실수는 실수끼리 연산해야 한다.) 하지만 정수와 실수를 연산해야 하는 경우 정수를 실수로 자동으로 변경한 뒤 연산을 처리한다. 반대의 상황인 경우 소수점 자리 이하의 데이터 손실이 발생할 수 있기 때문이다.

    System.out.println(123 + 0.5);
    System.out.println(123 - 0.5);
    System.out.println(123 * 0.5);
    System.out.println(123 / 0.5);
    System.out.println(123 % 0.5);
    • 실행결과
      123.5
      122.5
      61.5
      246.0
      0.0

2-3. 문자 리터럴의 연산

💡 문자는 내부적으로 숫자로 바꿔서 인식한다. 실제로 컴퓨터가 이해할 수 있는 것은 0과 1 뿐 이다. 어떠한 문자를 어떠한 숫자로 이해할 것인지 약속을 1963년 미국 ANSI에서 표준화한 정보 교환용 7비트 부호체계로 정의한 것을 ASCII(American Standard Code for Information Interchange, 미국 정보 교환 표준 부호) 코드 라고 하며, 0 ~ 127번 까지 문자와 숫자가 매핑되어 있다.

💡 하지만 아스키 코드만으로는 전 세계의 언어를 취급할 수 없는 한계점이 존재한다. 이러한 필요에 의해 유니코드라는 것이 정의되었다. 유니코드란 전 세계의 모든 문자를 다루도록 설계된 표준 문자 전산처리 방식이다. 전 세계 모든 문자를 담는 ISO/IEC 10646 코드표를 사용해 각 문자 충돌 문제를 해결했다. 처음에 문자 코드는 ASCII 코드가 대세였는데, 이 코드 1바이트로 문자를 표현하기 때문에 각 국의 문자가 깨지는 문제가 자주 발생하였다. 이에 2~3바이트 공간에 모든 문자를 할당하여 문제를 해결한 것이 유니코드이다.

우리가 자주 보는 UTF-8 인코딩도 유니코드에 기반한 인코딩 방식 중 하나이다.

  1. 문자와 문자의 연산

    문자는 내부적으로 숫자로 인식하기 때문에 숫자의 사칙 연산이 가능하다. 따라서 숫자의 연산을 수행하는 것과 같은 방식으로 동작한다.

    System.out.println('a' + 'b');
    System.out.println('a' - 'b');
    System.out.println('a' * 'b');
    System.out.println('a' / 'b');
    System.out.println('a' % 'b');
    • 실행결과
      195
      -1
      9506
      0
      97
  2. 문자와 정수의 연산

    System.out.println('a' + 1);
    System.out.println('a' - 1);
    System.out.println('a' * 2);
    System.out.println('a' / 2);
    System.out.println('a' % 2);
    • 실행결과
      98
      96
      194
      48
      1
  3. 문자와 실수의 연산

    System.out.println('a' + 1.0);
    System.out.println('a' - 1.0);
    System.out.println('a' * 2.0);
    System.out.println('a' / 2.0);
    System.out.println('a' % 2.0);
    • 실행결과
      98.0
      96.0
      194.0
      48.5
      1.0

2-4. 문자열 리터럴의 연산

💡 문자열은 사칙 연산 중 ‘+’ 연산만 가능하며, 연산 결과는 문자열 합치기(이어 붙이기)가 된다.
  1. 문자열과 문자열의 연산

    System.out.println("hello" + "world");
    //System.out.println("hello" - "world");			//에러 발생
    //System.out.println("hello" * "world");			//에러 발생
    //System.out.println("hello" / "world");			//에러 발생
    //System.out.println("hello" % "world");			//에러 발생
    • 실행결과
      helloworld
  2. 문자열과 다른 리터럴의 연산

    System.out.println("helloworld" + 123);
    System.out.println("helloworld" + 123.456);
    System.out.println("helloworld" + 'a');
    System.out.println("helloworld" + true);
    System.out.println("123" + "456");
    • 실행결과
      helloworld123
      helloworld123.456
      helloworlda
      helloworldtrue
      123456

2-5. 논리 리터럴의 연산

💡 논리 값은 내부적으로 숫자로 취급하긴 하지만 연산은 불가능하다. 단, 문자열과의 ‘+’ 연산은 가능하다.
  1. 논리와 논리의 연산

    //System.out.println(true + false);				//에러 발생
    //System.out.println(true - false);				//에러 발생
    //System.out.println(true * false);				//에러 발생
    //System.out.println(true / false);				//에러 발생
    //System.out.println(true % false);				//에러 발생
  2. 논리와 정수의 연산

    //System.out.println(true + 1);				//에러 발생
    //System.out.println(true - 1);				//에러 발생
    //System.out.println(true * 1);				//에러 발생
    //System.out.println(true / 2);				//에러 발생
    //System.out.println(true % 2);				//에러 발생
  3. 논리와 실수의 연산

    //System.out.println(true + 1.0);				//에러 발생
    //System.out.println(true - 1.0);				//에러 발생
    //System.out.println(true * 1.0);				//에러 발생
    //System.out.println(true / 2.0);				//에러 발생
    //System.out.println(true % 2.0);				//에러 발생
  4. 논리와 문자의 연산

    //System.out.println(true + 'a');				//에러 발생
    //System.out.println(true - 'a');				//에러 발생
    //System.out.println(true * 'a');				//에러 발생
    //System.out.println(true / 'a');				//에러 발생
    //System.out.println(true % 'a');				//에러 발생
  5. 논리와 문자열의 연산

    System.out.println(true + "a");		  		//문자열 합치기 됨
    //System.out.println(true - "a");				//에러 발생
    //System.out.println(true * "a");				//에러 발생
    //System.out.println(true / "a");				//에러 발생
    //System.out.println(true % "a");				//에러 발생
    • 실행결과
      truea

2-6. 문자열 이어붙이기

  1. 두 개의 값 이어붙이기

    System.out.println(9 + 9);
    System.out.println("9" + 9);
    System.out.println(9 + "9");
    System.out.println("9" + "9");
    • 실행결과
      18
      99
      99
      99
  2. 세 개의 값 이어붙이기

    System.out.println(9 + 9 + "9");
    System.out.println(9 + "9" + 9);
    System.out.println("9" + 9 + 9);
    System.out.println("9" + (9 + 9));
    • 실행결과
      189
      999
      999
      918
  3. 문자열 이어붙이기 응용

    기초 문법을 학습하는 파트에서 콘솔을 이용해 값을 출력하는 경우가 많이 발생할 예정이다. 너무 많은 값이 출력되면 어떤 값인지 확인하기 힘들기 때문에 문자열 이어붙이기를 이용하여 콘솔에 출력되는 값들을 보기 좋게 출력할 수 있다.

    System.out.println("=========== 10과 20의 사칙연산 결과 ===========");
    System.out.println(10 + 20);
    System.out.println(10 - 20);
    System.out.println(10 * 20);
    System.out.println(10 / 20);
    System.out.println(10 % 20);
    
    System.out.println("=========== 10과 20의 사칙연산 결과 보기 좋게 출력 ===========");
    System.out.println("10과 20의 합 : " + (10 + 20));		//주의 : 괄호를 묶지 않으면 문자열 합치기가 일어나서 결과가 1020이 된다.
    System.out.println("10과 20의 차 : " + (10 - 20));		//문자열은 마이너스 연산이 불가능하기에 앞에서 생성된 문자열과 마이너스 연산이 불가하다. (반드시 괄호 사용)
    System.out.println("10과 20의 곱 : " + (10 * 20));		//아래 부터는 동일한 방식이다.
    System.out.println("10과 20을 나누기 한 몫 : " + (10 / 20));
    System.out.println("10과 20을 나누기 한 나머지 : " + (10 % 20));
    • 실행 결과
      =========== 1020의 사칙연산 결과 ===========
      30
      -10
      200
      0
      10
      =========== 1020의 사칙연산 결과 보기 좋게 출력 ===========
      1020의 합 : 30
      1020의 차 : -10
      1020의 곱 : 200
      1020을 나누기 한 몫 : 0
      1020을 나누기 한 나머지 : 10
  • 내가 작성한 코드 실습
    //패키지는 클래스의 몸!
    
    /* 수업목표. 여러 가지 값의 형태를 출력할 수 있다.*/
    /*목차. 1. 숫자 형태의 값*/
    public class Application1 {
        public static void main(String[] args) {
            /*목차. 1-1. 정수 형태의 값 출력*/
            System.out.println(123); //한 줄 내려주기
    
            /* 목차. 1-2. 실수 형태의 값 출력*/
            System.out.println(1.234);
    
            /* 목차. 2. 문자 형태의 값 출력 */
            System.out.println('a');            // 설명. 문자는 single quatation(')을 사용
            System.out.println('1');            // 설명. 숫자도 single quatation을 붙이면 문자임
    //        System.out.println('ab');            컴파일 에러!!(문법 오류로, 실행 되기도 전에 오류나는 것)
            System.out.println('\u0000');       // 문자는 아무것도 안 넣으면 에러가 발생하지만 안 넣고 싶으면 '\u0000' 넣기
    
            /* 목차. 3. 문자열 형태의 값 출력*/
            System.out.println("안녕하세요!");   // 설명. 문자열은 double quatation(")을 사용
            System.out.println("a");
            System.out.println("");
    
            /* 목차. 4. 논리 형태의 값 출력 */
            System.out.println(true);
            System.out.println("true");         //double quatation이 붙으면 문자열
            System.out.println(false);          // 설명. true 또는 false 두 값만 논리 값이다.
        }
    }
    public class Application2 {
        public static void main(String[] args) {
            /* 수업목표. 값을 직접 연산하여 출력할 수 있다. */
    
            /* 목차. 1. 숫자와 숫자의 연산 */
            System.out.println("=========== 정수와 정수의 연산 ===========");
            System.out.println(123+456);
            System.out.println(123-23);
            System.out.println(123*10);
            System.out.println(123/10);
            System.out.println(123%10);         // modulus 연산자(mod 연산자): 제수로 나눈 나머지
    
            System.out.println("=========== 실수와 실수의 연산 ===========");
            System.out.println(1.23+1.23);
            System.out.println(1.23-0.23);
            System.out.println(1.23*10.0);
            System.out.println(1.23/10.0);
            System.out.println(1.23%1.0);       //설명. 실수는 정확하지 않고 근사값이다.
    
            /* 필기. 정수와 실수의 연산 결과는 실수가 나온다.(정수를 실수로 바꿔 연산해 준다.) */
            System.out.println("=========== 정수와 실수의 연산 ===========");
            System.out.println(123 + 0.5);
            System.out.println(123 - 0.5);
            System.out.println(123 * 0.5);
            System.out.println(123 / 0.5);
            System.out.println(123 % 0.5);
    
            /* 목차. 2. 문자의 연산 */
            /* 필기. 문자와 정수의 연산은 정수와 정수의 연산과 같다.(유니코드 기반의 숫자로 변환)*/
            System.out.println("=========== 문자와 정수의 연산 ===========");
            System.out.println('a' + 1);        //'a' = 97 결과: 98
            System.out.println('a' - 1);        // 결과: 96
            System.out.println('a' * 2);        // 결과: 194
            System.out.println('a' / 2);        // 결과: 48
            System.out.println('a' % 2);        // 결과: 1
    
            /* 필기. 정수와 실수의 연산과 같다. */
            System.out.println("=========== 문자와 실수의 연산 ===========");
    
            /* 목차. 3. 문자열의 연산 */
            System.out.println("=========== 문자열과 문자열의 연산 ===========");
            System.out.println("hello" + "world!");     // 문자열 간의 연산은 덧셈(이어붙이기)만 가능
    //        System.out.println("hello" - "world!");
    //        System.out.println("hello" * "world!");
    //        System.out.println("hello" / "world!");
    //        System.out.println("hello" % "world!");
    
            System.out.println("=========== 문자열과 다른 형태의 값 연산 ===========");
    
            /* 설명. 문자열과 정수의 연산*/
            System.out.println("helloworld" + 123);
    
            /* 설명. 문자열과 실수의 연산*/
            System.out.println("helloworld" + 123.456);
    
            /* 설명. 문자열과 문자의 연산*/
            System.out.println("helloworld" + 'a');
    
            /* 설명. 문자열과 논리값의 연산*/
            System.out.println("helloworld" + true);
    
            /* 설명. 이항연산자들의 묶음에서 좌측에서붙터 이항씩 연산하면 아래 코드의 결과를 이해할 수 있음*/
            System.out.println(123 + 3 + "helloworld" + 123 + 3);       // 결과: "126helloworld1233"
    
            /* 설명. 문자열 뒤에 숫자를 활용한 연산을 쓰게 되면 소괄호(())를 써서 우선순위를 높이고 연산해 주어야 한다. */
            System.out.println("합계: " + (123 + 456));
    
            /* 목차. 4. 논리값의 연산 */
            /* 설명. 대부분의 연산이 적용되지 않고 논리와 문자열의 연산만 가능하다. */
    //        System.out.println(true + 1);
    //        System.out.println(true * 1);
    
            System.out.println("=========== 논리값과 문자열 형태의 값 연산 ===========");
            System.out.println(true + "문자열");
        }
    }

2. 변수

1. 변수 개요

1-1. 변수란?

💡 변수(variable)이란 데이터를 저장하기 위해 할당 받은 메모리 공간을 의미한다. 변수의 종류는 여러 가지가 있지만, 여기서 다루는 변수는 지역 변수(local variable)이라고 한다.

1-2. 변수 사용 방법

💡 변수를 사용하기 위해서는 변수를 선언하고, 변수에 값을 대입하여 사용한다. 이 때 선언한 변수에 최초 값을 대입하는 것을 초기화라고 한다. 이러한 선언과 초기화는 따로 작성할 수 도 있고, 동시에 작성할 수 있다. 동시에 작성하는 것을 선언과 동시에 초기화 라고 한다.
// 변수의 선언 예시
int age;

// 선언한 변수에 값 대입 예시
age = 20;

// 선언과 동시에 초기화 예시
int point = 100;

2. 변수의 사용

2-1. 변수의 선언과 자료형

💡 변수를 선언한다는 의미는 메모리에 공간을 생성하고 그 공간을 참조(reference)할 수 있도록 이름을 부여하는 것이다. 선언을 하기 위해서는 자료형 변수명; 위와 같은 형태로 앞에 어떠한 데이터를 저장하는 공간 인지를 알려주는 키워드를 작성하게 된다. 이렇게 예약된 키워드를 자료형이라고 한다.

자료형이란?
다양한 값의 형태별로 어느 정도의 크기를 하나의 값으로 취급할 것인지 미리 Compiler와 약속한 키워드이다.
예) int 자료형은 정수를 4byte만큼을 읽어서 하나의 값으로 취급하겠다는 약속이다.

이러한 자료형은 기본자료형(Primary type)과 참조자료형(Reference type)으로 나누어진다.
그 중 기본자료형 8가지부터 살펴보기로 한다.

  1. 정수형

    정수의 경우는 일상 생활에서 많이 사용되는 숫자의 범위는 byte와 short으로 표현이 불가능한 경우가 많다.
    따라서 int를 대표자료형으로 여기며, 특수한 경우가 아닌 이상 byte와 short은 잘 사용하지 않는다.

    정수형의 경우 양수, 음수에 해당하는 부호를 표기하기 위해 비트의 맨 앞 자리를 부호 비트로 둔다.

    타입할당되는 메모리 크기데이터 표현 범위
    byte1 바이트128-128 ~ 127127
    short2 바이트215-2^{15} ~ (2151)(2^{15} -1)
    int4 바이트231-2^{31} ~ (2311)(2^{31} -1)
    long8 바이트263-2^{63} ~ (2631)(2^{63} -1)
    byte bnum;			//1byte
    short snum;		  //2byte
    int inum;			  //4byte
    long lnum;			//8byte
  2. 실수형

    실수의 경우는 정확도를 기준으로 4byte 자료형보다 8byte 자료형이 더 정확한 실수를 표현할 수 있기 때문에 double을 대표자료형으로 사용하고 float는 특수한 목적이 있는 경우에만 사용하게 된다.
    예) 원주율 3.14 보다 3.141592.. 가 더 정확한 실수이다.

    실수의 경우도 맨 앞 비트를 부호비트로 둔다.

    타입할당되는 메모리 크기데이터 표현 범위
    float4 바이트(3.41038)(3.4 * 10^{-38}) ~ (3.41038)(3.4 * 10^{38})
    double8 바이트(1.710308)(1.7 * 10^{-308}) ~ (1.710308)(1.7 * 10^{308})
    float fnum;			  //4byte
    double dnum;		  //8byte
  3. 문자형

    문자형은 short자료형과 동일하게 2바이트의 할당 크기를 가지지만, 부호비트 없이 16개 비트를 모두 값 비트로 활용하기에 데이터 표현 범위가 short자료형과는 다르다.

    타입할당되는 메모리 크기데이터 표현 범위
    char2 바이트00 ~ 2162^{16}
    char ch;			    //2byte
  4. 논리형

    논리형은 실제 사용하는 비트가 8비트 중 가장 오른쪽 1비트만 이용을 하지만 실제 할당되는 크기는 1바이트를 할당한다.

    타입할당되는 메모리 크기데이터 표현 범위
    boolean1 바이트true 혹은 false
    boolean isTrue;	//1byte
  5. 문자열 (참조자료형)

    문자열은 기본 자료형에 해당하지 않는 참조자료형이다. 이 부분은 나중에 클래스와 객체를 배우고 난 뒤 이해 가능하기 때문에 현재는 그냥 문자열을 저장하기 위한 자료형이라고 생각하고 사용하면 된다.

    String str;			//4byte (엄밀히 이야기 하면 주소값은 4byte 정수형이다.)

2-2. 변수의 명명규칙

💡 변수를 선언할 시 자료형과 변수명을 명시하여 선언을 한다. 이 때 사용하는 변수명을 명명하는 규칙에는 컴파일 에러를 발생시키는 규칙과, 컴파일 에러를 발생시키지는 않지만 개발자들끼리의 암묵적인 규칙이 존재한다. 이러한 변수의 명명 규칙을 따르는 것은 매우 중요하다.
  1. 컴파일 에러를 발생시킬 수 있는 규칙

    1. 동일한 범위 내에서 동일한 변수명을 가질 수 없다.
    2. 변수의 이름에는 자바에서 사용중인 키워드(keyword)를 사용할 수 없다.
      ex) int, float, while, continue, 등등
    3. 변수의 이름은 영문자 대소문자를 구분한다.
      ex)** age와 Age는 다르다.
    4. 변수의 이름은 숫자로 시작할 수 없다.
      ex) 123abc - 사용불가
    5. 특수기호는 '-'와 '$'만 사용 가능하다.
      ex) abc_zxc, abc$123, _abc123, 등등
    /* 1-1. 동일한 범위 내에서 동일한 변수명을 가질 수 없다. */
    int age = 20;
    //int age = 20; 		   //동일한 변수명을 가지므로 에러 발생함
    
    /* 1-2. 예약어는 사용이 불가능하다. */
    //int true = 1;			//예약어 사용 불가
    //int for = 20;			//예약어 사용 불가
    
    /* 1-3. 변수명은 대소문자를 구분한다. */
    int Age = 20;			//위에서 만든 age와 다른 것으로 취급한다.
    int True = 10;     //예약어 True와 다른 것으로 취급한다.
    
    /* 1-4. 변수명은 숫자로 시작할 수 없다. */
    //int 1age = 20;		//숫자로 시작해서 에러 발생
    int age1 = 20;			//숫자가 처음에 시작하지 않으면 섞어서 사용도 가능함
    
    /* 1-5. 특수기호는 '-'와 '$'만 사용 가능하다. */
    //int sh@rp = 20;		//사용 가능한 특수문자 외에는 사용 불가능
    int _age = 20;				//언더스코어는 사용 가능함. 처음도 가능하고 중간이나 끝에도 가능함
    int $harp = 20;			//$도 사용 가능함. 처음도 가능하고 중간이나 끝에도 가능함
  2. 컴파일 에러를 발생시키지는 않지만 개발자들끼리의 암묵적인 규칙

    1. 변수명의 길이 제한은 없다. (하지만 적당히 해야 한다.)
    2. 변수명이 합성어로 이루어진 경우 첫 단어는 소문자, 두 번째 시작 단어는 대문자로 시작한다. (camel-case)
      ex) int memberAddress;
    3. 단어와 단어 사이의 연결을 언더스코어( _ )로 하지 않는다. (타 언어 네이밍 규칙이다.)
    4. 한글로 변수명을 짓는 것이 가능하지만, 권장하지 않는다. (한글을 취급하는 다양한 방식들이 존재하기 때문에 에러를 유발할 수 있다.)
    5. 변수 안에 저장된 값이 어떤 의미를 가지는지 명확하게 표현하도록 한다.
    6. 전형적인 변수 이름이 있다면 가급적 사용하도록 한다.
    7. 명사형으로 작성할 수 있도록 한다.
    8. boolean 형은 의문문으로 가급적 긍정 형태로 네이밍한다.
     /* 2-1. 변수명의 길이 제한은 없다. */
    int sadjfsadkjhfkjsadhfkjhsafkjhsdfjkhsafkjhsdjkfhsdajkfhdsakjfhsdakjfhasdjkfhsdafkjhfsdakj;
    
    /* 2-2. 변수명이 합성어로 이루어진 경우 첫 단어는 소문자, 두 번째 시작 단어는 대문자로 시작한다. */
    /* 자바에서는 클래스명만 유일하게 대문자로 시작한다. */
    int maxAge = 20;
    int minAge = 10;
    
    /* 2-3. 단어와 단어 사이의 연결을 언더스코어(_)로 하지 않는다. */
    String user_name;			//에러가 발생하지 않지만 이렇게 하면 안된다.
    String userName;			  //이게 올바른 표현이다.
    
    /* 2-4. 한글로 변수명을 짓는 것이 가능하지만, 권장하지 않는다. */
    int 나이;						  //가능하지만 권장하지 않음
    
    /* 2-5. 변수 안에 저장된 값이 어떤 의미를 가지는지 명확하게 표현하도록 한다. */
    String s;					    //변수가 어떤 의미인지 파악하기 힘들다.
    String name;				    //문자열 형태의 이름이 저장되겠구나 하는 의도가 파악이 된다.
    
    /* 2-6. 전형적인 변수 이름이 있다면 가급적 사용하도록 한다. */
    int sum = 0;
    int max = 10;
    int min = 0;
    int count = 1;
    
    /* 2-7. 명사형으로 작성할 수 있도록 한다. */
    String goHome;				    //가능하긴 하지만 가급적 명사형으로 짓는다.
    String home;
    
    /* 2-8. boolean 형은 의문문으로 가급적 긍정형태로 네이밍한다. */
    boolean isAlive = true;
    boolean isDead = false;	//부정형보다는 긍정형이 더 나은 방식이다.
    • 내가 작성한 코드
      package com.ohgiraffers.section02.variable;
      
      import java.lang.reflect.Type;
      
      public class Application2 {
          public static void main(String[] args) {
              /* 수업목표. 변수를 선언하고 값을 할당하여 사용할 수 있다.(feat. 자료형(type)) */
              /* 필기.
               *  변수를 사용하는 방법
               *  1. 변수를 준비한다.(선언)
               *  2. 변수에 값을 대입한다. (값 대입 및 초기화)
               *  3. 변수를 사용한다.
              */
      
              /* 목차. 1. 변수 선언 */
              /* 설명. 자료형이란?
              *   다양한 값의 형태별로 어느 정도의 크기를 하나의 값으로 취급할 것인지 미리 Complier와 약속한 키워드이다.
              *   이러한 자료형들은 기본자료형(Primitive Type)과 참조자료형(Reference Type)으로 나누어진다.
              *   먼저, 기본자료형 8가지부터 살펴보자.
              * */
      
              /* 설명. 정수를 취급하는 자료형*/
              byte bnum;      // 1 byte
              short snum;     // 2 byte
              int inum;       // 4 byte
              long lnum;      // 8 byte
      
              /* 설명. 실수를 취급하는 자료형 */
              float fnum;     // 4 byte
              double dnum;    // 8 byte
      
              /* 설명. 문자를 취급하는 자료형 */
              char ch;        // 2 byte
      
              /* 설명. 논리값을 취급하는 자료형 */
              boolean isTrue; // 1 byte
      
              /* 설명. 문자열은 참조 자료형이다.(feat. 대문자로 시작) */
              String str;     // 4 byte
      
              /* 목차. 2. 변수에 값 대입(초기화) */
              bnum = 1;
              snum = 2;
              inum = 4;
              lnum = 2200000000L;
              // 정수의 기본 int
              // 21억 5천만이 넘어가는 순간부터 Long, 그래서 숫자 뒤에 L써주기
      
              fnum = 4.0f;
              dnum = 8.0;
              // 실수의 기본 double
      
              ch = 'a';
              ch = 97;            // char 자료형은 문자를 숫자로 취급
      //        ch = 97;          // char 자료형은 0부터 양수만 취급
      
              isTrue = true;
      
              /* 목차. 3. 변수 활용 */
              System.out.println("isTrue = " + isTrue);
              System.out.println("long과 int의 합: " + (lnum + inum));
      
              /* 설명. 변수의 선언 및 초기화는 한 번에 가능하다. */
              int kor = 90;
              int math = 80;
              int eng = 75;
      
              int sum = kor + math + eng;
              double avg = sum / 3;           // int / int = int
              double avg2 = sum / 3.0;        // 나눗셈을 할 때는 소수점을 고려해야 함(하나라도 float 또는 double 형이어야 한다.)
              double avg3 = sum / (float)3;    // int / double =  double
      
              System.out.println("총합: " + sum);
              System.out.println("평균: " + avg);
              System.out.println("평균: " + avg2);
      
          }
      }

2-3. 변수에 값 대입 및 초기화

💡 변수에 값을 대입하기 위해서는 대입연산자(=)를 사용한다. 대입연산자는 연산 방향이 오른쪽에서 왼쪽 방향이다. 변수에 값을 대입할 때는 대입하는 값의 리터럴 형태와 선언된 자료형이 일치해야 한다.
  1. 정수를 취급하는 변수에 값 대입

    byte bnum = 1;
    short snum = 2;
    int inum = 4;
    //long lnum = 8;			//아무 문제 없는 것 같지만 사실 뒤에 대문자 L을 붙여야 한다. 그 이유는 뒤에 형변환에서 다루게 될 것이다.
    long lnum = 8L;			  //소문자로 'l'을 써도 되지만 글꼴에 따라 숫자 1과 혼선이 빚어질 수 있어서 대문자로 하는 것이 권장이다.
    
    System.out.println("bnum의 값 : " + bnum);
    System.out.println("snum의 값 : " + snum);
    System.out.println("inum의 값 : " + inum);
    System.out.println("lnum의 값 : " + lnum);
    • 실행결과
      bnum의 값 : 1
      snum의 값 : 2
      inum의 값 : 4
      lnum의 값 : 8
  2. 실수를 취급하는 변수에 값 대입

    //float fnum = 4.0;		  //실수 형태의 값을 fnum에 사용하는 것은 불가능하다.
    float fnum = 4.0f;		  //실수 뒤에 'f'를 붙여야 한다. 대문자 'F'도 가능하지만 소문자를 사용하는 것이 일반적이다.
    double dnum = 8.0;
    
    System.out.println("fnum의 값 : " + fnum);
    System.out.println("dnum의 값 : " + dnum);
    • 실행결과
      fnum의 값 : 4.0
      dnum의 값 : 8.0
  3. 문자를 취급하는 변수에 값 대입

    char ch = 'a';			//문자 형태의 값을 저장할 수 있다.
    char ch2 = 97;			//'a'는 97이라는 숫자이다. 그래서 숫자로도 저장할 수 있다.
    
    System.out.println("ch의 값 : " + ch);
    System.out.println("ch2의 값 : " + ch2);
    • 실행결과
      ch의 값 : a
      ch2의 값 : a
  4. 논리를 취급하는 변수에 값 대입

    boolean isTrue = true;
    isTrue = false;		//true 혹은 false 중 한 가지의 값만 사용 가능하다.
    
    System.out.println("isTrue의 값 : " + isTrue);
    • 실행결과
      isTrue의 값 : false
  5. 문자열을 취급하는 변수에 값 대입

    String str = "안녕하세요";
    
    System.out.println("str의 값 : " + str);
    • 실행결과
      str의 값 : 안녕하세요

2-4. 변수를 사용하는 목적

  1. 값에 의미를 부여하기 위한 목적 (의미 전달이 쉬워야 코드를 읽기 쉬워지고, 협업 및 유지보수에 유리기 때문이다.)

    /* 아래 처럼 작성하면 어느 값이 급여인지 어느 값이 보너스 금액인지 알 수 없다. */
    System.out.println("보너스를 포함한 급여 : " + (1000000 + 200000) + "원");
    
    /* 아래 처럼 의미를 부여하게 되면 어느 값이 급여인지, 보너스인지를 명확하게 알 수 있게 한다. */
    int salary = 1000000;
    int bonus = 200000;
    System.out.println("보너스를 포함한 급여 : " + (salary + bonus) + "원");
    • 실행결과
      보너스를 포함한 급여 : 1200000원
      보너스를 포함한 급여 : 1200000
  2. 한 번 저장해둔 값을 재사용 하기 위한 목적(변수를 이용하여 코드를 작성하면, 값을 변경할 때도 보다 간편하게 변경할 수 있다.)

    /* 10명의 고객에게 100 포인트를 지급해주는 내용을 출력하도록 작성해보자 */
    System.out.println("1번 고객에게 포인트를 100포인트 지급하였습니다.");
    System.out.println("2번 고객에게 포인트를 100포인트 지급하였습니다.");
    System.out.println("3번 고객에게 포인트를 100포인트 지급하였습니다.");
    System.out.println("4번 고객에게 포인트를 100포인트 지급하였습니다.");
    System.out.println("5번 고객에게 포인트를 100포인트 지급하였습니다.");
    System.out.println("6번 고객에게 포인트를 100포인트 지급하였습니다.");
    System.out.println("7번 고객에게 포인트를 100포인트 지급하였습니다.");
    System.out.println("8번 고객에게 포인트를 100포인트 지급하였습니다.");
    System.out.println("9번 고객에게 포인트를 100포인트 지급하였습니다.");
    System.out.println("10번 고객에게 포인트를 100포인트 지급하였습니다.");
    
    /* 위 코드에서 공통적으로 사용된 100이라고 하는 값을 변수에 넣고 변수를 호출하여 코드를 개선해보자 */
    int point = 100;
    System.out.println("1번 고객에게 포인트를 " + point + "포인트 지급하였습니다.");
    System.out.println("2번 고객에게 포인트를 " + point + "포인트 지급하였습니다.");
    System.out.println("3번 고객에게 포인트를 " + point + "포인트 지급하였습니다.");
    System.out.println("4번 고객에게 포인트를 " + point + "포인트 지급하였습니다.");
    System.out.println("5번 고객에게 포인트를 " + point + "포인트 지급하였습니다.");
    System.out.println("6번 고객에게 포인트를 " + point + "포인트 지급하였습니다.");
    System.out.println("7번 고객에게 포인트를 " + point + "포인트 지급하였습니다.");
    System.out.println("8번 고객에게 포인트를 " + point + "포인트 지급하였습니다.");
    System.out.println("9번 고객에게 포인트를 " + point + "포인트 지급하였습니다.");
    System.out.println("10번 고객에게 포인트를 " + point + "포인트 지급하였습니다.");
    • 실행결과
      1번 고객에게 포인트를 100포인트 지급하였습니다.
      2번 고객에게 포인트를 100포인트 지급하였습니다.
      3번 고객에게 포인트를 100포인트 지급하였습니다.
      4번 고객에게 포인트를 100포인트 지급하였습니다.
      5번 고객에게 포인트를 100포인트 지급하였습니다.
      6번 고객에게 포인트를 100포인트 지급하였습니다.
      7번 고객에게 포인트를 100포인트 지급하였습니다.
      8번 고객에게 포인트를 100포인트 지급하였습니다.
      9번 고객에게 포인트를 100포인트 지급하였습니다.
      10번 고객에게 포인트를 100포인트 지급하였습니다.
      1번 고객에게 포인트를 100포인트 지급하였습니다.
      2번 고객에게 포인트를 100포인트 지급하였습니다.
      3번 고객에게 포인트를 100포인트 지급하였습니다.
      4번 고객에게 포인트를 100포인트 지급하였습니다.
      5번 고객에게 포인트를 100포인트 지급하였습니다.
      6번 고객에게 포인트를 100포인트 지급하였습니다.
      7번 고객에게 포인트를 100포인트 지급하였습니다.
      8번 고객에게 포인트를 100포인트 지급하였습니다.
      9번 고객에게 포인트를 100포인트 지급하였습니다.
      10번 고객에게 포인트를 100포인트 지급하였습니다.
  3. 시간에 따라 변하는 값을 저장하고 사용할 수 있다. (변하는 값을 저장하기 위한 공간이다)

    int sum = 0;
    
    sum = sum + 10;
    System.out.println("sum에 10을 더하면 현재 sum의 값은? " + sum);
    
    sum = sum + 10;
    System.out.println("sum에 10이 있었으니 10을 추가로 더하면? " + sum);
    
    sum = sum + 10;
    System.out.println("sum에 20이 있었는데 추가로 10을 더 더하면? " + sum);
    • 실행결과
      sum에 10을 더하면 현재 sum의 값은? 10
      sum에 10이 있었으니 10을 추가로 더하면? 20
      sum에 20이 있었는데 추가로 10을 더 더하면? 30
  • 내가 작성한 코드
    public class Application1 {
        public static void main(String[] args) {
            int num; // num은 박스(변수)라고 생각하기, num을 입력하면 언제든지 1이라는 값이 출력될 것임
            num = 1; // '='은 대입연산자
    
            System.out.println("num = " + num);
            System.out.println("(num + 1) = " + (num + 1));
    
            /* 수업목표. 변수의 사용 목적에 대해 이해할 수 있다. */
            /* 필기.
             *  변수의 사용 목적
             *  1. 값에 의미를 부여하기 위한 목적(의미 전달이 쉬워야 코드를 읽기 쉬워지고, 협업 및 유지보수에 유리하기 때문이다.
             *  2. 한 번 저장해둔 값을 재사용 하기 위한 목적(변수를 이용하여 코드를 작성하면, 값을 변경할 때도 보다 간편하게 변경할 수 있다.)
             *  3. 시간에 따라 변하는 값을 저장하고 사용할 수 있다.(변하는 값을 저장하기 위한 공간이다.)
            * */
    
            /* 목차. 1. 값에 의미를 부여하기 위한 목적 */
            System.out.println("================== 값에 의미 부여 테스트 ==================");
            System.out.println("보너스를 포함한 급여: " + (1000000 + 200000) + "원");
    
            int salary = 1000000;
            int bonus = 200000;
            System.out.println("보너스를 포함한 급여: " + (salary + bonus) + "원");
    
            /* 목차. 2. 한 번 저장해둔 값을 재사용하기 위한 목적 */
            System.out.println("================== 변수에 저장한 값 재사용 테스트 ==================");
    
            /* 설명. 10명의 고객에게 100포인트를 지급해주는 내용을 출력하도록 작성해보자.*/
            System.out.println("1번 고객에게 포인트를 100포인트 지급하였습니다.");
            System.out.println("2번 고객에게 포인트를 100포인트 지급하였습니다.");
            System.out.println("3번 고객에게 포인트를 100포인트 지급하였습니다.");
            System.out.println("4번 고객에게 포인트를 100포인트 지급하였습니다.");
            System.out.println("5번 고객에게 포인트를 100포인트 지급하였습니다.");
            System.out.println("6번 고객에게 포인트를 100포인트 지급하였습니다.");
            System.out.println("7번 고객에게 포인트를 100포인트 지급하였습니다.");
            System.out.println("8번 고객에게 포인트를 100포인트 지급하였습니다.");
            System.out.println("9번 고객에게 포인트를 100포인트 지급하였습니다.");
            System.out.println("10번 고객에게 포인트를 100포인트 지급하였습니다.\n");
            System.out.println();
    
            /*설명. 위 코드에서 공통적으로 사용된 100이라고 하는 값을 변수에 넣고 변수를 호출하여 코드를 개선해 보자. */
    
            int point = 200;
            System.out.println("1번 고객에게 포인트를 " + point + "포인트 지급하였습니다.");
            System.out.println("2번 고객에게 포인트를 " + point + "포인트 지급하였습니다.");
            System.out.println("3번 고객에게 포인트를 " + point + "포인트 지급하였습니다.");
            System.out.println("4번 고객에게 포인트를 " + point + "포인트 지급하였습니다.");
            System.out.println("5번 고객에게 포인트를 " + point + "포인트 지급하였습니다.");
            System.out.println("6번 고객에게 포인트를 " + point + "포인트 지급하였습니다.");
            System.out.println("7번 고객에게 포인트를 " + point + "포인트 지급하였습니다.");
            System.out.println("8번 고객에게 포인트를 " + point + "포인트 지급하였습니다.");
            System.out.println("9번 고객에게 포인트를 " + point + "포인트 지급하였습니다.");
            System.out.println("10번 고객에게 포인트를 " + point + "포인트 지급하였습니다.");
            //재사용성이 좋다. 유지보수에 좋다.
    
            /* 목차. 3. 시간에 따라 변경되는 값을 저장하고 사용 할 목적 */
            System.out.println("================== 변수에 저장된 값 변경 테스트 ==================");
            int sum = 0;
                                    // 등호 왼쪽은 공간, 오른쪽에 있는 숫자는 치환되는 숫자
            sum = sum + 10;         // 기존에 0이 담겨있던 변수에 10이 덮어씀(변수는 하나의 리터럴 값만 저장 가능)
            System.out.println("sum에 10을 더하면 현재 sum의 값은: " + sum);
    
            sum = sum + 10;
            sum = sum + 10;
            sum = sum + 10;
            sum = sum + 10;
            System.out.println("sum에 10을 4번 더 누적하면 현재 sum의 값은: " + sum);
            /* 설명. 동일한 sum이라는 하나의 변수를 어느 시점ㅇ[ 출력하느냐에 따라 출력 결과는 달라진다.(변수명은 같지만 들어있는 값은 달라짐 */
        }
    }
    public class Application2 {
        public static void main(String[] args) {
            /* 수업목표. 변수를 선언하고 값을 할당하여 사용할 수 있다.(feat. 자료형(type)) */
            /* 필기.
             *  변수를 사용하는 방법
             *  1. 변수를 준비한다.(선언)
             *  2. 변수에 값을 대입한다. (값 대입 및 초기화)
             *  3. 변수를 사용한다.
            */
    
            /* 목차. 1. 변수 선언 */
            /* 설명. 자료형이란?
            *   다양한 값의 형태별로 어느 정도의 크기를 하나의 값으로 취급할 것인지 미리 Complier와 약속한 키워드이다.
            *   이러한 자료형들은 기본자료형(Primitive Type)과 참조자료형(Reference Type)으로 나누어진다.
            *   먼저, 기본자료형 8가지부터 살펴보자.
            * */
    
            /* 설명. 정수를 취급하는 자료형*/
            byte bnum;      // 1 byte
            short snum;     // 2 byte
            int inum;       // 4 byte
            long lnum;      // 8 byte
    
            /* 설명. 실수를 취급하는 자료형 */
            float fnum;     // 4 byte
            double dnum;    // 8 byte
    
            /* 설명. 문자를 취급하는 자료형 */
            char ch;        // 2 byte
    
            /* 설명. 논리값을 취급하는 자료형 */
            boolean isTrue; // 1 byte
    
            /* 설명. 문자열은 참조 자료형이다.(feat. 대문자로 시작) */
            String str;     // 4 byte
    
            /* 목차. 2. 변수에 값 대입(초기화) */
            bnum = 1;
            snum = 2;
            inum = 4;
            lnum = 2200000000L;
            // 정수의 기본 int
            // 21억 5천만이 넘어가는 순간부터 Long, 그래서 숫자 뒤에 L써주기
    
            fnum = 4.0f;
            dnum = 8.0;
            // 실수의 기본 double
    
            ch = 'a';
            ch = 97;            // char 자료형은 문자를 숫자로 취급
    //        ch = 97;          // char 자료형은 0부터 양수만 취급
    
            isTrue = true;
    
            /* 목차. 3. 변수 활용 */
            System.out.println("isTrue = " + isTrue);
            System.out.println("long과 int의 합: " + (lnum + inum));
    
            /* 설명. 변수의 선언 및 초기화는 한 번에 가능하다. */
            int kor = 90;
            int math = 80;
            int eng = 75;
    
            int sum = kor + math + eng;
            double avg = sum / 3;           // int / int = int
            double avg2 = sum / 3.0;        // 나눗셈을 할 때는 소수점을 고려해야 함(하나라도 float 또는 double 형이어야 한다.)
            double avg3 = sum / (float)3;    // int / double =  double
    
            System.out.println("총합: " + sum);
            System.out.println("평균: " + avg);
            System.out.println("평균: " + avg2);
    
        }
    }
    public class Application3 {
        public static void main(String[] args) {
            /* 수업목표. 변수의 명명 규칙에 대해 이해할 수 있다. */
            /* 필기.
            *   변수의 명명 규칙
            *       변수의 이름을 지을 때 아무렇게나 짓는 것이 아닌 정해진 규칙이 있다.
            *       실무적으로는 굉장히 중요하기 때문에 반드시 숙지해야 한다.
            *       또한, 규칙에 맞는 올바른 변수명을 짓는 것이 좋은 프로그래밍을 하는 첫 단계이다.
            * */
    
            /* 목차. 1. 컴파일 에러를 발생시키는 규칙 */
            /* 목차. 1-1. 동일한 범위 내에서 동일한 변수명을 가질 수 있다. */
            int age = 20;
    //        int age = 30;
            age = 30;
    
            /* 목차. 1-2. 예약어는 사용이 불가능하다. */
    //        int true = 1;
    //        int for = 2;
            // java 쓰는 언어를 예약어
    
            /* 목차. 1-3. 변수명은 대소문자를 구분한다. */
    //        int age = 20;
            int aGe = 20; // 위에서 만든 age와 다른 변수로 취급
    
            /* 목차. 1-4. 변수명은 숫자로 시작할 수 없다. */
    //        int 1age = 20;
            int age1 = 20;
    
            /* 목차. 1-5. 특수기호로는 '_'와 '$'만 사용 가능하다. */
            int _age = 30;
            int $harp = 10;
    //        int #harp = 11;
    
            /* 목차. 2. 컴파일 에러를 발생시키지는 않지만 개발자들 간의 암묵적인 규칙(관례상 규칙) */
            /* 목차. 2-1. 변수명의 길이 제한은 없다. 하지만 적당히 하자. */
            int vldkshfmffmfclausdksehlqsslek;
    
            /* 목차. 2-2. 변수명이 합성어로 이루어진 경우 첫 단어는 소문자, 두 번째 시작 단어는 대문자로 시작한다. */
            int maxAge = 50; //낙타봉 표기법(camel case)
            int minAge = 10;
    
            /* 목차. 2-3. 한글로 변수명을 짓는 것은 가능하나 권장하지 않는다. */
            int 나이 = 19;
    
            /* 목차. 2-4. 변수 안에 저장될 값을 고려하여 의미있고 명확한 이름으로 작성한다. */
    //        String s;
            String name;
    
            /* 목차. 2-5. 명사형으로 작성할 수 있도록 한다. */
    //        String goHome;
            String home;
    
            /* 목차. 2-6. boolean 자료형은 긍정의문문 형태로 작성한다. */
            boolean isAlive = true;
            boolean isDead = false;
    
        }
    }

3. 상수

1. 상수 개요

1-1. 상수란?

💡 상수(constant**)**는 변수와 동일하게 데이터를 저장할 수 있는 공간이다. 다만, 변수와 다른 점은 한 번 메모리에 저장된 데이터를 변경할 수 없다.

처음엔 변수였는데, 초기화 하면서 상수화 되고 변수가 될 수 없는 경우

오염되면 안되는 것(환경변수 설정, 파이 3.14159 등)

1-2. 상수 사용 목적

  1. 변경되지 않는 고정된 값을 저장할 목적으로 사용한다.
  2. 초기화 이후 값 대입 시 컴파일 에러를 발생시켜 값이 수정되지 못하도록 한다.
    예) 수학 공식에 사용되는 수치, 프로그램의 기본적인 환경설정 정보(DB 정보, IP 주소정보 등)

2. 상수의 사용

💡 상수를 사용하는 방법은 변수와 거의 동일하다. 다만 차이점은 선언 시 `final` 키워드를 사용한다는 부분이 다르다.

2-1. 상수의 선언 및 초기화

/* 1. 상수 선언 
* 상수 선언 시 자료형 앞에 final 키워드를 붙인다. */
final int AGE;

/* 2. 초기화 */
AGE = 20;
//AGE = 30;		//한 번 초기화 한 이후 값을 재 대입하는 것은 불가능하다.

/* 3. 필요한 위치에 상수를 호출해서 사용한다. */
/* 3-1. 출력 구문에서 사용 */
System.out.println("AGE의 값 : " + AGE);
/* 3-2. 필요시 연산식에 호출해서 사용 */
System.out.println("AGE의 2배 : " + (AGE * 2));
  • 실행 결과
    AGE의 값 : 20
    AGE의 2: 40

2-2. 상수의 명명 규칙

  1. 모든 문자는 영문자 대문자 혹은 숫자만 사용한다.

    final int AGE1 = 20;
    final int AGE2 = 30;
    final int age3 = 40;		//소문자로 사용은 가능하지만 변수와 구분하기 힘들기 때문에 만들어진 규칙이다.
  2. 단어와 단어 연결은 언더스코어( _ )를 사용한다.

    final int MAX_AGE = 60;
    final int MIN_AGE = 20;
    final int minAge = 30;		//camel case 사용이 가능하지만 역시 변수와 구분되지 않는다.
  • 내가 작성한 코드
    public class Application1 {
        public static void main(String[] args) {
            /* 수업목표. 상수에 대해 이해하고 사용할 수 있다. */
    
            /* 목차. 1. 상수 선언 */
            final int AGE;
    
            /* 목차. 2. 초기화 */
            AGE = 20;
    //        AGE = 21;
    
            /* 목차. 3. 필요한 위치에 상수를 호출해서 사용 */
            System.out.println("AGE의 값: " + AGE);
    
            /* 설명. 상수값도 리터럴로 치환된다. */
            int myAge = AGE;
    
        }
    
    }
    public class Application2 {
        public static void main(String[] args) {
            /* 수업목표. 상수의 명명 규칙에 대해 이해할 수 있다. */
    
            /* 목차. 1. 모든 문자는 영문자 대문자 혹은 숫자만 사용한다.(특수기호X)*/
            final int AGE1 = 20;
            final int AGE2 = 30;
            final int AGE3 = 40; // 소문자로 사용은 가능하나 변수와 구분하기 힘들기 때문에 지양함
    
            /* 목차. 2. 단어와 단어 연결은 언더스코어(_)를 사용한다.  */
            final int MAX_AGE = 60;
            final int MIN_AGE = 20;
            final int minAGE = 30; //낙타봉 표기법 역시 사용은 가능하나 변수와 구분하기 힘들기 때문에 지양함
    
        }
    }

4. 오버플로우

1. 오버플로우 개요

💡 오버플로우(overflow)란 변수가 담을 수 있는 값의 범위를 벗어나는 데이터를 담았을 때 발생하는 현상을 오버플로우라고 한다. 자료형 별 값의 최대 범위를 벗어나는 경우 발생한 carry를 버림처리 하고 sign bit를 반전시켜 최소값으로 순환시키는 현상이다.

1-1. 오버플로우란

System.out.println("byte 값의 범위 : " + Byte.MIN_VALUE + " ~ " + Byte.MAX_VALUE);
System.out.println("char 값의 범위 : " + (int)Character.MIN_VALUE + " ~ " + (int)Character.MAX_VALUE);
System.out.println("short 값의 범위 : " + Short.MIN_VALUE + " ~ " + Short.MAX_VALUE);
System.out.println("int 값의 범위 : " + Integer.MIN_VALUE + " ~ " + Integer.MAX_VALUE);
System.out.println("long 값의 범위 : " + Long.MIN_VALUE + " ~ " + Long.MAX_VALUE);
System.out.println("float 값의 범위 : " + Float.MIN_VALUE + " ~ " + Float.MAX_VALUE);
System.out.println("double 값의 범위 : " + Double.MIN_VALUE + " ~ " + Double.MAX_VALUE);
  • 실행결과
    byte 값의 범위 : -128 ~ 127
    char 값의 범위 : 0 ~ 65535
    short 값의 범위 : -32768 ~ 32767
    int 값의 범위 : -2147483648 ~ 2147483647
    long 값의 범위 : -9223372036854775808 ~ 9223372036854775807
    float 값의 범위 : 1.4E-45 ~ 3.4028235E38
    double 값의 범위 : 4.9E-324 ~ 1.7976931348623157E308

1-2. 오버플로우 발생 확인과 해결 방법

  1. 오버플로우

    byte num1 = 127;
    System.out.println("num1 : " + num1);						      //127 : byte의 최대 저장 범위
    
    num1++;														                    //1 증가
    System.out.println("num1 overflow : " + num1);				//-128 : byte의 최소 저장 범위
    • 실행결과
      num1 : 127
      num1 overflow : -128
  2. 언더플로우

    byte num2 = -128;
    System.out.println("num2 : " + num2);						      //-128 : byte의 최소 저장 범위
    
    num2--;														                    //1 감소
    System.out.println("num2 underflow : " + num2);				//127 : byte의 최대 저장 범위
    • 실행결과
      num2 : -128
      num2 underflow : 127
  3. 논리적 문제 발생과 해결 방법

    1. 문제 발생

      int firstNum = 1000000;			//100만
      int secondNum = 700000;			//70만
      
      int multi = firstNum * secondNum;		//7천억이 나와야 함
      
      System.out.println("firstNum * secondNum = " + multi);			//--79669248 이 나온다.
      • 실행결과
        firstNum * secondNum = -79669248
    2. 해결 방법

      /* 오버플로우를 예측하고 더 큰 자료형으로 결과값을 받아서 처리한다. */
      long longMulti = firstNum * secondNum;
      
      System.out.println("longMulti : " + longMulti);		//여전히 오버플로우가 발생한다.
      
      /* 이미 오버플로우 처리 된 결과를 가지고 변수에 담기 때문에 위에 결과랑 별 차이가 없다.
      * 그럼 어떻게 해결을 해야 하나?
      * 계산이 처리 되기 전에 long 타입으로 자료형을 변경해주어야 한다. (강제형변환 이용)
      * 강제 형변환은 바로 다음 섹션에서 다루게 될 예정이다.
      * */
      long result = (long) firstNum * secondNum;
      
      System.out.println("result : " + result);			//정상적으로 7천억이 출력될 것이다.
      • 실행결과
        longMulti : -79669248
        result : 700000000000
  • 내가 작성한 코드
    public class Application1 {
        public static void main(String[] args) {
            /* 수업목표. 오버플로우에 대해 이해할 수 있다. */
            /* 필기.
             *  자료형 별 값의 최대 범위를 벗어나는 경우
             *  발생한 carry를 버림처리 하고 sign bit를 반전시켜 최소값으로 순환시킴
            * */
    
            /* 목차. 1. 오버플로우 */
            byte num1 = 126;        // byte 자료형의 양의 최대 저장 범위 값
    
            num1++;                 // num1 = num1 + 1과 의미상 같다.
            System.out.println("num1 = " + num1);
    
            num1++;
            System.out.println("num1 = " + num1);
    
            num1++;
            System.out.println("num1 = " + num1);
    
            /* 목차. 2. 언더플로우 */
            byte num2 = -127;                           // byte의 최소 저장 범위
    
            num2--;
            System.out.println("num2 = " + num2);       // num2 = num2 - 1과 의미상 같다.
    
            num2--;
            System.out.println("num2 = " + num2);
    
            num2--;
            System.out.println("num2 = " + num2);
    
            /* 설명.
             *  일반적으로 많이 사용하는 int형의 최대값은 대략 21억 정도이다.
             *  이 범위를 벗어난 계산은 오버플로우를 발생시켜 원하지 않는 결과값이 나오게 될 수 있다.
            * */
    
            int firstNum = 1000000;                                       // 100만
            int secondeNum = 700000;                                      // 70만
    
            int multi = firstNum * secondeNum;                            //7천억이 나와야 함
            int multi2 = 1000000 * 700000;
    
            System.out.println("firstNum * secondNum = " + multi);        // firstNum * secondNum = -79669248 런타임 에러 나옴
        }
    }

5. 형변환

  1. 형변환 개요

1-1. 형변환이란?

💡 자바 형변환(casting) 이란 변수 또는 리터럴을 다른 타입으로 변환하는 것을 말한다. 형변환을 하는 이유는 프로그램에서 변수에 값을 넣거나 연산을 수행할 때는 같은 타입끼리만 가능하기 때문이다.

1-2. 형변환의 종류 및 규칙

  1. 자동 형변환 (묵시적 형변환)

    컴파일러가 자동으로 수행해주는 타입 변환이다. 데이터 손실 가능성이 없는 경우 자동으로 타입을 맞춰준다.

    1. 작은 자료형에서 큰 자료형으로는 자동 형변환 된다.

      /* 1. 정수끼리의 자동 형변환 */
      /* 점점 더 큰 자료형으로 데이터를 옮겨도 문제 없이 자동 형변환 처리 된다. */
      byte bnum = 1;
      short snum = bnum;
      int inum = snum;
      long lnum = inum;
      
      /* 연산 시에도 자동으로 큰 쪽 자료형에 맞춰서 계산한다. */
      int num1 = 10;
      long num2 = 20;
      
      //int result1 = num1 + num2;		//자동으로 큰 쪽 자료형인 long으로 변경 후 계산하기 때문에 int형 변수에 값을 담을 수 없다.
      long result1 = num1 + num2;			//int + long은 서로 다른 자료형이라 데이터 손실이 발생하지 않는 int-> long 변환을 자동 수행 후 연산한다.
      
      System.out.println("result1 : " + result1);
      
      /* 2. 실수 끼리의 자동 형변환 */
      float fnum = 4.0f;
      double dnum = fnum;
      
      /* 연산 시에도 자동으로 큰 쪽 자료형에 맞춰서 계산된다. */
      double result2 = fnum + dnum;
      
      System.out.println("result2 : " + result2);
      • 실행결과
        result1 : 30
        result2 : 8.0
    2. 정수는 실수로 자동 형변환 된다.

      /* 정수를 실수로 변경할 때 소수점 자리수가 없어도 실수형태로 표현이 가능하다. 이 때 데이터 손실이 없기 때문에 자동 형변환이 가능하다.
      * 실제 값을 저장하는 매커니즘을 가진 것과 달리 실수형은 지수부와 가수부를 따로 나눠서 작성하기 때문에
      * 바이트 크기 보다 훨씬 더 많은 값을 표현할 수 있다.
      * */
      //long eight = 888888888888888888888;					//이것도 지동으로 형변환 된 것이다. (int 범위 벗어나면 에러 발생)
      long eight = 8;
      float four = eight;
      
      System.out.println("four : " + four);
      
      /* 따라서 실수와 정수의 연산은 실수로 연산 결과가 반환된다. */
      float result3 = eight + four;
      
      System.out.println("result3 : " + result3);
      • 실행결과
        four : 8.0
        result3 : 16.0
    3. 문자형은 int형으로 자동 형변환 된다.

      char ch1 = 'a';
      int charNumber = ch1;
      
      System.out.println("charNumber : " + charNumber);
      
      /* int로 type이 정해지지 않은 리터럴 형태의 정수는 char 형 변수에 기록 가능하다. */
      char ch2 = 65;
      
      System.out.println("ch2 : " + ch2);
      • 실행결과
        charNumber : 97
        ch2 : A
    4. 논리형은 형변환 규칙에서 제외된다.

      /* 어느 자료형이든 boolean을 형변환 해서 담을 수 없다. */
      boolean isTrue = true;
      //byte b = isTrue;
      //short s = isTrue;
      //int i = isTrue;
      //long l = isTrue;
      //char c = isTrue;
      //float f = isTrue;
      //double d = isTrue;
  2. 강제 형변환 (암시적 형변환)

    형변환(casting) 연산자를 이용한 강제적으로 수행하는 형변환이다.

    자동형변환의 조건과 정 반대인 경우 강제 형변환을 사용한다.

    1. 큰 자료형에서 작은 자료형으로 변경 시 강제 형변환이 필요하다.

      /* 1. 정수 끼리의 강제 형변환 */
      long lnum = 8;
      //int inum = lnum;			//데이터 손실 가능성을 컴파일러가 알려준다. (에러남)
      int inum = (int) lnum;		//변경하려는 자료형을 명시하여 강제 형변환을 해야 함
      
      short snum = (short) inum;
      byte bnum = (byte) snum;
      
      /* 2. 실수 끼리의 강제 형변환 */
      double dnum = 8.0;
      //float fnum = dnum;			//데이터 손실 가능성을 컴파일러가 알려준다. (에러남)
      float fnum = (float) dnum;
      
      System.out.println(fnum);
      • 실행결과
        8.0
    2. 실수를 정수로 변경 시 강제 형변환이 필요하다.

      float fnum2 = 4.0f;
      //long lnum2 = fnum2;				    //float는 4byte, long은 8byte임에도 자동 형변환 불가능 (소수점 자리 이하 데이터 손실 가능성)
      long lnum2 = (long) fnum2;			//강제 형변환의 의미는 '내가 데이터 손실을 감안할테니 형변환 해줘~' 라는 의미이다.
    3. 문자형을 int미만 크기의 변수에 저장할 때 강제 형변환이 필요하다.

      char ch = 'a';
      byte bnum2 = (byte) ch;				//당연히 char 자료형보다 작은 크기이니 강제형변환을 해야 한다.
      short snum2 = (short) ch;			//같은 2byte이지만 부호비트(sign bit)로 인한 값의 범위가 다르기 때문에 강제 형변환을 해 주어야 한다.
      
      /* 추가적으로 정수를 char 자료형에 강제 형변환해서 대입하기 테스트 */
      int num1 = 97;
      int num2 = -97;
      
      char ch2 = (char) num1;
      char ch3 = (char) num2;				//음수도 강제 형변환 하면 대입할 수 있다.
      
      System.out.println("ch2 : " + ch2);
      System.out.println("ch3 : " + ch3);
      • 실행결과
        ch2 : a
        ch3 :
    4. 논리형은 강제 형변환 규칙에서도 제외된다

      boolean isTrue = true;
      // byte b = (byte) isTrue;
      // short s = (short) isTrue;
      // int i = (int) isTrue;
      // float f = (float) isTrue;
      // double d = (double) isTrue;
      // char c = (char) isTrue;

1-3. 자동형변환과 강제형변환을 이용한 연산

  1. 서로 다른 자료형끼리의 연산

    /* 다른 자료형 끼리 연산은 큰 자료형으로 자동 형변환 후 연산 처리 된다. */
    int inum = 10;
    long lnum = 100;
    
    /* 자바에서는 같은 자료형끼리만 연산이 가능하다.
    * 따라서 서로 자료형이 다른 두 자료를 연산할 때 자료형이 같아지도록 형변환을 해 주어야 한다.
    * */
    
    /* 방법1. 두 수의 연산 결과를 int 형으로 변환 후 int 자료형 변수에 리턴받는다. */
    //int isum = inum + lnum;		//그냥은 안된다. 두 자료형의 연산 결과는 큰 쪽 자료형인 long이 되고, long형 값은 int형 변수에 담길 수 없다.
    int isum = (int) (inum + lnum);
    
    System.out.println("isum : " + isum);
    
    /* 방법2. long 형 값을 int로 강제 형변환 한다. */
    int isum2 = inum + (int) lnum;
    
    System.out.println("isum2 : " + isum2);
    
    /* 방법3. 결과 값을 long형 자료형으로 받는다(자동 형변환 이용) */
    long lsum = inum + lnum;
    
    System.out.println("lsum : " + lsum);
    • 실행결과
      isum : 110
      isum2 : 110
      lsum : 110
  2. 형변환을 이용한 연산 시 주의사항

    /* 주의! int 미만의 연산의 처리 결과는 int형 이다. */
    byte byteNum1 = 1;
    byte byteNum2 = 2;
    short shortNum1 = 3;
    short shortNum2 = 4;
    
    int result1 = byteNum1 + byteNum2;
    int result2 = byteNum1 + shortNum1;
    int result3 = shortNum1 + byteNum1;
    int result4 = shortNum1 + shortNum2;
    
    System.out.println("result1 : " + result1);
    System.out.println("result2 : " + result2);
    System.out.println("result3 : " + result3);
    System.out.println("result4 : " + result4);
    • 실행결과
      result1 : 3
      result2 : 4
      result3 : 4
      result4 : 7
  3. 의도하지 않은 데이터 손실

    int inum = 290;
    byte bnum = (byte) inum;
    
    System.out.println("inum : " + inum);
    System.out.println("bnum : " + bnum);		//비트 앞부분 손실로 예측 어려움
    • 실행결과
      inum : 290
      bnum : 34
  4. 의도한 데이터 손실

    double height = 175.5;
       int floorHeight = (int) height;
    
       System.out.println("height : " + height);
       System.out.println("floorHeight : " + floorHeight);		//소수점 절삭에 이용할 수 있다.
    • 실행결과
      height : 175.5
      floorHeight : 175
    • 내가 작성한 코드
      public class Application1 {
          public static void main(String[] args) {
              /* 수업목표. 자동 형변환(implicit coercion) 규칙에 대해 이해할 수 있다. */
      
              /* 설명. 점점 더 큰 자료형으로 데이터를 옮겨도 문제 없이 자동형변환 되어 대입이 이루어 진다. */
              byte bnum = 1;          // 리터럴이 정수일 때 자바는 int로 받아들이지만 int -> byte, int -> short는 자동 형변환 됨
              short snum = bnum;
              int inum = snum;
              long lnum = inum;
      
              /* 설명. 연산 시에도 자동으로 큰 쪽 자료형에 맞춰서 낮은 자료형이 자동형변환 된다. */
              int num1 = 10;
              long num2 = 20L;
      
              long result1 = (long) num1 + num2;
              System.out.println("result1 = " + result1);
      
              /* 설명. 문자형은 int형으로 자동 형변환 된다.(그 반대도 가능함) */
              int ch1 = 'a';
              int charNumber = ch1;
              System.out.println("charNumber = " + charNumber);
      
              char ch2 = 65;
              System.out.println("ch2 = " + ch2);
          }
      }
      public class Application2 {
          public static void main(String[] args) {
              /* 수업목표. 강제 형변환 규칙에 대해 이해할 수 있다. */
              /* 필기.
               *  강제형변환
               *  바꾸려는 자료형으로 캐스팅 연산자 ((자료형))를 이용하여 형변환한다.
              * */
      
              long lnum = 80000000000L;
              int inum = (int)lnum;                   // 데이터 손실을 감수하고 다운캐스팅 시에는 주의해야 한다.
              System.out.println("inum = " + inum);   //int로 다운 캐스팅 할 경우 오버플로우 발생
      
              float avg = 31.235f;                    // 실수 변수에서
              int flownum = (int) avg;                // 정수로 다운캐스팅 시에는 소수점 이하가 제거(버림) 된다. 데이터 손실
              System.out.println("flownum = " + flownum);
      
          }
      }
profile
나는 할 수 있다...!

0개의 댓글