[JAVA] 변수와 타입

msung99·2022년 3월 29일
0
post-thumbnail


책 정리

정수

2진수: 0b+숫자 ex) int var = 0b0111;
8진수: 0+숫자 ex) int var = 0206;
16진수: 0x+숫자 ex) int var = 0x83;

각 타입이 저장할수 있는 범위 : -2^(n-1) ~ 2^(n-1) - 1
(n:비트)

long balance = 30000000000L; => 정수 리터럴이 int타입의 허용 범위 이내라면 꼭 L을 붙이지 않아도된다.

char 타입

  • 문자 리터럴은 유니코드로 변환되어 저장된다.
  • 유니코드란? : 세계 각국의 문자를, 2바이트로 표현할 수 있는 숫자(0~65535) 로 1대1 매핑안 규약

ex) 'A', 'B', '가', '각' 문자를 char변수에 저장하는 경우 변수에 저장되는 유니코드 값

char var1 = 'A';   // 유니코드: 65 => 문자 리터럴 'A'는 유니코드값 
                      65로 변환되어 변수에 저장된다.
char var2 = 'B';   // 유니코드: 66
char var3 = '가';  // 유니코드: 44032
char var4 = '각';  // 유니코드: 44044
  • 유니코드는 정수이므로 char도 정수 타입에 속함
  • 따라서 char 변수에 10진수 또는 16진수 형태로도 유니코드를 저장할 수 있다.
char변수에 유니코드를 정수로 저장
char a = 65;   // 10진수
char c = 0x0041; // 16진수

작은따옴표로 감싼 문자 리터럴은 유니코드로 변환되므로, int 타입 변수에도 저장할 수 있다.

  • char 타입 변수에 저장하면 자동으로 문자로 매핑되어 출력되지만,
  • int타입 변수에 저장되면 유니코드 자체가 출력된다.
char var1 = 'A';
int var2 = 'A';
System.out.println(var1);  // A를 출력
System.out.println(var2); // 65를 출력

자동타입변환

정수 타입이 실수 타입으로 저장될 경우에는 무조건 자동 타입 변환이 일어난다.
실수 타입은 정수 타입보다 범위가 더 크기때문

char타입은 int 타입으로 자동변환되면 유니코드 값이 int 타입에 저장된다.

char charValue = 'A';
int intValue = charValue;  // 유니코드 값 65가 저장됨

강제타입변환

char->int : int 타입은 char 타입보다 더 큰 범위를 가지므로, (char) 케스팅 연산자를 통해 강제 변환 해야한다.

int intValue = 65;
char charValue = (char) intValue;
System.out.println(charValue); // 'A' 출력

실수->정수 : 소수점 이하는 버려지고 정수 부분만 저장

double doubleValue = 3.14;
int intValue = (int) doubleValue;  // 정수부분인 3만 저장

연산시 자동변환 과정

  • 피연산자들이 있을때, 피연산자 중에서 타입이 가장 큰 것으로 변환되어 연산이 진행된다
int intValue = 10;
double doubleValue = 5.5;
double result = intValue + doubleValue; // intValue는 double타입으로 변환되어서 
                 // 연산이 진행된다.
System.out.println(3 == 3.0);  // 정수 3이 double 타입으로 변환되서 연산진행
System.out.println(0.1 == 0.1f); // 출력결과 : false  => 0.1 은 0.1의 근사값이다.
// 0.1f도 0.1의 근사값이지만, double 타입으로 변환되어도 둘이 표현하는 정확한 숫자값은 다르다.
  • 만일 타입이 작은 것을 기준으로 연산을 진행하고 싶다면 강제 변환을 할것!
int intValue = 10;
double doubleValue = 5.5;
int result = intValue + (int)doubleValue; // 연산결과:15

문자열 + 연산

String str1 = 1 + "2" + 3;  
=> 연산과정 : 1+"2"+3 -> "12"+3 -> "123"
 
String str2 = "1" + 2 + 3; 
=> 연산과정 : "1"+2+3 -> "12" + 3 -> "123"

String str3 = 1 + 2 + "3";
=> 연산과정 : 1+2+"3" -> 3+"3" -> 33

실수

  • 실수 타입 리터럴(숫자)는 double 타입으로 컴파일
  • 리터럴 숫자 뒤에 f(float) 나 d(double)을 명시적으로 선언할수있음
    => float 변수에 실수형 리터럴 숫자를 할당 가능해짐
double d = 0.1234;
float e = 0.1234; => 에러발생! 리터럴 숫자 0.1234는 double 타입인데 이 숫자를 float 변수에 넣으려고 함
float f = 0.1234f; => 숫자 뒤에 f나 d를 명시적으로 붙여서 타입을 변환

문자

유니코드 : '\u' 로 표현

char a = 'A';
char b = '글'
char c = \u0041;
char d = \uae00;

타입 변환

자동타입변환

  • 프로그램 실행도중에 작은 타입은 큰 타입으로 자동 타입변환 가능

강제타입변환

  • 큰 타입을 작은 타입으로 변환
int a = 103029300;
byte b = (byte) a;  => 기존 데이터 값 103029300이 손실된다

연산식에서 자동변환

  • 서로 다른 타입의 연산 => 두 피연산자중 큰 타입으로 변환
int a = 10;
double b = 5.5;
double result = a + b;  => int형 변수a의 값 10이 double 타입을 자동변환

리터럴

  • 코드 상에 직접 적어준 값

  • 종류 : 실수 리터럴, 문자 리터럴, 정수 리터럴, 논리 리터럴, null 리터럴, 문자열 리터럴

    • 문자 리터럴 : 유니코드로 표현 가능
      • ex) char c = '\u0041'; => 문자 'A'의 유니코드 값 (0041) 사용
      • char d = '\uae00'; => 문자 '글'의 유니코드 값(ae00)사용
    • 정수 리터럴 종류 : 10진수, 8진수, 16진수, 2진수 리터럴
      int n = 15; int m =0x15;
    • 논리 리터럴 종류 : true, false
    • 문자열 리터럴 : 문자열 리터럴은 String 객체로 자동 처리
      ex) String str = "Good";
  • 숫자 리터럴의 아무 위치에너 언더스코어 ('_') 허용

    • ex) int price = 20100; // 20100과 동일
      int x = 15; => 오류. 리터럴 끝에 사용할 수 없다
      double pi = 3
      .14; // 오류. 소수점 앞뒤에 사용 불가능

기본 타입 종류

  • 총 8가지
    • 정수(byte,char,short,int,long) 실수(float,double), 논리(boolean)

타입 변환

  • 종류
    • 자동(암시적) 타입변환 : promotion (작은 타입 => 큰 타입으로 변환)
    • 강제(명시적) 타입변환 : casting (큰 타입 => 작은 타입으로 변환)
  • 자동 타입 변환

    • 타입 크기 : byte(1) < short(2) < int(4) < long(8) < float(4) < double(8)
      • long과 float의 바이트 크기는 4로 똑같아도, float이 표현할 수 있는 범위가 훨씬 많다.
  • 강제 타입 변환

    • 값 손실 발생 가능성o
    • ex) byte value = (byte) 1000;
  • 연산식 안에서 자동 타입 변환

    • 크기가 작은애가 큰 애로 타입이 자동변환되고 연산이 이루어짐
      ex) double result = 10 + 5.5; // 15.5가 저장

main 함수

  • 클래스 안에 main함수 생성

  • "static" 키워드를 꼭 써줄 것

    • 클래스안에 static 을 넣어두면 그 클래스 내부에 포함되지 않는다.

    • 그 클래스로부터 객체 여러개를 생성시 main함수는 여러 객체들이 함께 그냥 멤버로써 "공유하는 함수"가 된다. (c++의 static 특성과 동일)

    • 즉, main 함수는 객체 내부에 존재하는 메소드가 아닌, 외부에 존재하는 메소드가 된다.

    • 따라서 객체를 만들지 않더라도 main 함수 사용가능

    • static 함수 안에서 사용하는 멤버들 역시 static 이여여 한다.

      • 객체가 없어도 사용할 수 있는 서비스이기 떄문
public class Hello{
  public static int sum(int n, int m){
    return n + m;
  }
  
  // 만약에 main함수가 static이 아니였다면, Hello 클래스 기반의 객체가 만들어져야 이용 가능했을 것이다.
  public static void main(String[] args){
    int i = 20;
    int s;
    char a;
    
    s = sum(i,10);
    
    System.out.println(s);
  }
}

예제 분석

예제1)

byte var1 = 128; => 에러 발생

예제2

오버플로우 발생
ex) 2의보수 관점에서 접근하기! => 00000111 값에 1을 더하면 10000000 이 되고, 10000000은 음의 최댓값이다.

예제3

유니코드 사용하는 예제
유니코드를 사용할시 '\u' 를 사용할것

char c3 = '\u0041'; // 16진수 '0041'을 유니코드로 사용

예제5

long 타입 변수에다 굉장히 큰 값을 집어넣으려고 함.
100000000000 이라는 값은 int 타입으로 취급된다.
100000000000 뒤에 L 을 붙여서 long 타입 리터럴로 명시적으로 사용하기!

예제6

실수형 타입을 적으면 기본적으로 double 타입으로 취급된다.

3.14 는 double 타입으로 취급됨
그런데 float 타입 변수에 double 타입으로 취급된 3.14 를 넣으면 에러 발생함
뒤에 F 를 붙여서 float 타입임을 명시해준다

예제 10, 11

  • double 타입이 float에 비해서 정밀하게 숫자를 표현할 수 있다.

  • float 의 4바이트 부동소수점은 정확하지 못하다.

  • 실수 연산(부동소수점 방식)이 정확한 값을 가지지 않고, 근사치를 가지고 숫자를 저장한다.

    예제 12

  • double도 float에 비해 정밀한거지, 마냥 그렇게 정밀한 연산을 하지 못함

  • BigDecimal 을 사용하면 정밀한 계산 가능

0개의 댓글