티스토리 뷰

프리미티브 타입 종류와 값의 범위 그리고 기본값

데이터 타입을 다루기 앞서 과연 데이터 타입이 뭐고 왜 굳이 데이터 타입을 나눠서 저장하는지에 대한 의문점을 가졌다.

컴퓨터 메모리에는 비트의 패턴이 저장되며 이것이 무엇을 의미할지는 어떻게 사용되는가에 따라 달려있다.

컴퓨터에 사용되는 메모리는 "유한"하다. 만약 사용할 변수의 크기가 8bit 밖에 안되는데 64bit의 데이터 타입을 사용한다면 56 bit의 데이터 낭비가 발생한다. 물론 bit 타입의 크기가 그렇게 크지는 않지만 큰 서비스를 운영할 때 쌓이고 쌓이다보면 많은 메모리를 차지하게 되고 이는 성능 저하의 원인이 된다. 그래서 내가 사용하는 변수의 범위와 타입에 맞게 사용하는 것이 중요하다.

 

데이터 타입에는 두가지 타입이 있다.

  1. Primitive type(기본형)
  2. Reference type(참조형)

그 중 Primitive type은 기본형 타입으로 말 그대로 가장 기본이 되는 타입이다.

(기본형 타입! 하면 바로 8개 주루루룩 떠오를만큼 공부했던 기억이 있다)

 

Type Data Type Size Default Range
논리형 boolean 1 byte false true, false
정수형 byte 1 byte (8 bits) 0 -128(2^7) ~ 127(2^7-1)
  short 2 byte (16 bits) 0 - 32,768(2^15) ~ 32,767(2^15-1)
  int 4 byte (32 bits) 0 - 2,147,483,648(2^31) ~ 2,147,483,647(2^31-1)
  Long 8 byte (64 bits) 0L - 2^63 ~ 2^63-1
실수형 float 4 byte 0.0F (+/-)1.4E-45 ~ (+/-)3.4028235E38
  double 8 byte 0.0 (+/-)4.9E-324 ~ (+/-)1.7976931348623157E308
문자형 char 2 byte '\u0000' 0 ~ 2^16 (유니코드 \0000 ~ \FFFF)

 

데이터 타입을 지정해놓고 해당 타입의 범위를 넘어가면 에러가 나기 때문에 어느 정도의 범위와 default값은 항상 기억해 두는 편이 좋다고 생각한다.

 

문제는 default값보단 범위인데 저 범위를 깡으로 외우는 것이 아닌 흐름에 따라서 범위가 나오는 이유에 대해서 얘기해보면 이해하기 쉽다.

먼저 1 byte에 대해서 생각해보면 1 byte는 8 bits로 이루어진 데이터 크기로 0과 1로 된 다음과 같은 배열로 만들어져 있다.

1byte 배열 모양 예시

박스 하나에 1 bit값이 들어있고 0 혹은 1의 값을 가질 수 있다. 결국 1 byte는 길이가 8인 2진수를 뜻하는데 unsigned한 이진수를 생각했을 때는 범위가 0~2^8까지 가능하지만 정수형을 다루기 때문에 음수까지 다뤄야하기 때문에 맨 앞의 bit하나를 가지고 음수와 양수를 표현한다. 따라서 7개의 bit로만 수를 표현하기 때문에 byte형의 경우 -2^7 ~ 2^7-1 까지의 범위를 가지는 것이다.

 

실수형은 정수형이랑 다르게 소수를 가지기 때문에 또 표현 범위가 다르다. float과 double은 각각 32 bits와 64 bits를 아래와 같이 할당한다.

float  : 부호(1bit) + 지수(8bits) + 가수(23bits)
double : 부호(1bit) + 지수(11bits) + 가수(52bits)

 

char type은 앞선 정수형, 실수형과는 다르게 unsigned한 값이기 때문에 2 bytes를 부호를 따지지 않고 0~2^16으로 범위를 잡는다. 단, default는 '\u0000'으로 정수 0가 default가 아닌 값이니 default값을 사용할 때나 0을 사용할 때 주의해야한다. ('0'는 hex code로 '\u0030'이다.)

 

프리미티 타입과 레퍼런스 타입

앞서 설명했던 데이터 타입의 두 종류이다. 프리미티 타입은 실제 값(Data)를 저장하는 반면, 레퍼런스 타입은 어떤 값이 저장되어 있는 주소(memory address)를 값으로 갖는다.

따라서 기본형에서는 정해진 데이터에 대한 타입을 선언하였지만 레퍼런스 타입을 선언할 때는 변수의 타입으로 클래스의 이름을 사용하기 때문에 클래스의 이름이 참조 변수의 타입이 된다. 새로운 클래스를 작성하는 것은 곧 새로운 레퍼런스 타입을 추가하는 것과 마찬가지다.

배열, enum, 생성한 모든 클래스, interface 등이 참조형에 포함된다.

클래스이름 변수이름;	//변수의 타입이 8가지 기본형이 아니라면 모두 참조형 변수이다.
String.java 중 일부
자주 쓰는 String은 당연히 참조형이고 클래스로서 선언이 되어있다!

 

리터럴

Literal(리터럴)은 항상 Contant(상수)랑 같이 나와서 비교되는 개념이다. 비슷비슷해보이지만 엄밀히 따지자면 둘은 다른 개념이다.

상수 : 변하지 않는 변수 (메모리 위치가 변하지 않음)
리터럴 : 변수에 넣는 변하지 않는 데이터 (메모리 위치안의 값이 변하지 않음)

 

상"수"라고 숫자가 들어간 변수가 아니라 상수에 들어가는 변수는 기본형 뿐만아니라 참조변수도 들어갈 수 있다. 주의해야할 것은 참조변수가 상수라는 것이고(참조변수의 메모리 주소값이 변하지 않음), 주소가 가르키는 데이터가 상수라는 것은 아니다.

final 제어자로 상수를 사용한다. 다음 코드를 살펴보자.

package Week2;

public class Exam1 {
    public static void main(String[] args) {
        final String t2 = "테스트";
//        t2 = "다음 테스트";

        final Test t1 = new Test(10);
        System.out.println("변경 전 주소값 : " + t1);
        System.out.println("t1.num : " + t1.num);
        t1.num = 20;
        System.out.println("변경 후 주소값 : " + t1);
        System.out.println("t1.num : " + t1.num);
//        test = new Test();
    }
    public static class Test {
        private int num;

        public Test(int num) {
            this.num = num;
        }
    }
}
//    변경 전 주소값 : Week2.Exam1$Test@60e53b93
//    t1.num : 10
//    변경 후 주소값 : Week2.Exam1$Test@60e53b93
//    t1.num : 20

기본형과 참조형의 상수 사용은 같으니 String 클래스로 먼저 테스트를 해보면 t1을 상수로 지정을 했다면 그 값을 변경했을 때 에러나 난다.

반대로 참조 변수의 경우에는 참조변수의 메모리 주소값만 변하지 않으면 되기 때문에 그 안의 값(num)이 변하는 것은 허용이 되지만 다음의 주소 초기화의 경우에는 주소값이 변하는 구문이기 때문에 에러가 발생한다.

 

리터럴은 위에서 사용했던 데이터 값 그 자체다. 위의 경우에는 "테스트"를 예로 들 수 있을 것 같다.

기본형 같은 경우에는 그냥 정해진 메모리타입에 따라 리터럴로 지정이 되었다고 보면 되는데 참조형에서 String같은 클래스 데이터가 어떻게 리터럴처럼 사용하고 있을까? 변하지 않는 데이터라면서 주소가 언제 값이 바뀔지도 모르는데?

 

객체 지향 프로그래밍에서는 이를 Immutable Object(불변 객체)를 가지고 상태를 바꿀 수 없는 클래스를 만들어서 리터럴로 사용한다. 불변 객체란 생성 후 그 상태를 바꿀 수 없는 객체를 의미한다. 무엇을 바꿀 수 없다는 것인가?

자바에서 Reference를 가지고 있는 타입은 실제 데이터는 Heap에 저장하고 그 Heap영역을 가르키는 주소 값을 Stack에 가지고 있다. 이때 "Heap에 저장된 실제 데이터를 바꿀 수 없는 것"이 불변 객체라고 한다. 위 코드에서 예를 들면 String t1 = "테스트";에서 "테스트"라는 데이터는 어디에서도 바꿀 수 없는 객체이기 때문에 String은 불변 객체라고 할 수 있고 Test t2 = new Test(20);에서 Test(20)은 바로 아래에서 t2.num값을 변동시킬 수 있었기 때문에 불변 객체라고 보기 어렵다.

불변 객체에 대한 내용은 지금 주제와는 더 멀어질 것 같아서 나중에 깊게 파보는 걸로 하자..

 

변수 선언 및 초기화하는 방법

변수의 선언은 선언할 변수의 타입 + 변수의 이름을 선언하는 것으로 할 수 있다. 선언이 되는 순간 선언한 변수의 타입에 맞는 메모리가 할당된다.

  • 변수 타입 : 변수에 저장될 값의 타입을 지정 (int, long, String ...)
  • 변수 이름 : 값을 저장할 수 있게 할당된 메모리 공간에 이름을 붙여준 것
package Week2;

public class Exam2 {
    public static void main(String[] args) {
        int a;	// int type 변수인 a 선언
      	int b, c; // 같은 타입의 선언 시 쉼표(,)로 연달아 선언 가능
    }
}

초기화는 등호(=)인 대입 연산자를 사용해서 초기화할 수 있다.

선언하면서 같이 초기화할 수도 있고 선언한 다음 초기화할 수 도 있다.

package Week2;

public class Exam3 {
    public static void main(String[] args) {
        int a = 0;  //선언과 동시에 초기화
        int b;
      	// System.out.println(b);
        b = 1;      //선언 후 초기화
      	System.out.println(b);
        int c = 2, d = 3;   //같은 타입의 경우 쉼표로 초기화
    }
}
// 출력
// 1

물론 선언할 때와 마찬가지로 같은 타입의 변수는 쉼표로 선언과 초기화를 같이 해줄 수 있다.

 

변수의 선언과 초기화에서 주의해야할 점은 지역변수에 대한 초기화를 필수로 해야한다는 것이다. 지역변수란 메소드 내에서 선언한 변수로 인스턴스 변수와 클래스 변수와는 다르게 default값이 자동으로 지정되지 않는다.

위의 코드에서 b=1;로 초기화하기 전에 b의 값을 출력하면 어떻게 될까? int의 default값이 0이니까 0이 출력될까?

java: variable b might not have been initialized

에러가 난다..! (Initialized(선언)되지 않았다) 지역변수의 변수가 초기화되지 않았을 때 발생하는 에러로 멤버 필드가 아닌 경우에는 반드시 변수를 초기화해주어야한다. (멤버 필드는 자바에서 알아서 해당 타입의 default값으로 초기화해준다.)

그래서 항상 메소드 안에서 변수를 선언할 때는 같이 초기화를 해주어야 에러가 나지 않는다.

지역 변수는 대부분 일부 계산을 수행하기 위해 선언됩니다. 따라서 변수의 값을 설정하는 프로그래머의 결정이며 기본값을 사용해서는 안됩니다. 프로그래머가 실수로 로컬 변수를 초기화하지 않았고 기본값을 사용하면 출력이 예상치 못한 값이 될 수 있습니다. 따라서 지역 변수의 경우 컴파일러는 정의되지 않은 값의 사용을 피하기 위해 프로그래머가 변수에 액세스하기 전에 일부 값으로 초기화하도록 요청합니다.

출처 : https://qastack.kr/programming/415687/why-are-local-variables-not-initialized-in-java

라는 구체적인 좋은 답변도 있다.

 

변수의 스코프와 라이프타임

프로그램에서 사용되는 변수들은 각각 사용 가능한 범위를 가지는데 그 범위를 스코프라고 한다. 범위에 대해서 정말 단순하게 바라봤을 때 {} 안에 선언이 된 변수는 그 영역이 끝나기 전에는 어디서든 사용이 가능하다.

package Week2;

public class Exam4 {    //class 영역
    String name = "라이언";	//인스턴스 변수
    static String country = "대한민국"; //클래스 변수는 클래스 내에서 어디서든 사용 가능
    int age = 10;
    int value;

    public void MethodArea() {  //method 영역
        String methodValue = "method value";
        System.out.println(methodValue);
        System.out.println(age);
        System.out.println(country);
    }

    public static void main(String[] args) {  //Main method 영역
//        main method는 static 변수가 아닌 경우 객체화해야 사용 가능
//        System.out.println(name);
        Exam4 person = new Exam4();
        System.out.println(person.name);
        System.out.println(person.value);   //지역변수가 아니기 때문에 초기화하지 않아도 결과값이 나옴

        System.out.println(country);    //static 변수의 경우 사용 가능
    }
}

먼저 가장 큰 범위가 되는 Class 영역부터 알아보자.

 Class 영역에서 static으로 정의한 변수는 전역 변수 (Global Variable)라고 한다. Global이라는 이름에서 알 수 있듯이 class영역의 모든 메소드에서 사용할 수 있기 때에 전역 변수라고 불려진다. 실제로 MethodArea() 메소드에서 전역 변수인 country를 출력하는 것으로 잘 호출이 되는 것을 알 수 있다.

반대로 Class 영역에서 static으로 정의되지 않은 변수는 인스턴스 변수 (Instance Vairable)라고 한다. 얘도 일단은 MethodArea에서 age가 출력하는 것으로 호출이 됨을 알 수 있는데 전역 변수와 인스턴스 변수는 밑에 main method에서 다시 얘기하자. (큰 문제가 있다)

 

다음으로는 Class 영역에서 선언되는 Method 영역이다.

Method 영역에서 정의한 변수는 지역 변수(Local Variable)이다. Method 내에서 선언된 지역 변수는 다른 메소드에서 사용되지 못하고 선언된 Method 안에서만 사용해야한다.

(앞에서 이야기했던대로 지역 변수는 반드시 초기화해야한다는걸 잊으면 안된다.)

 

 근데 문제는 이놈의 Main method다...

 인스턴스 변수인 name이라도 Main method는 static 타입이 아니라면 값을 호출할 수 가 없다. 그래서 인스턴스 변수를 받아오려면 위에서 나와있듯이 객체화(인스턴스화)를 한 다음 변수를 받아와야한다. 아니면 country처럼 static으로 변수를 지정해야한다. 왜 이럴까? 답은 static의 성격에 대한 이해를 먼저하면 알기 쉽다.

static

객체 생성을 하지 않고 클래스 변수나 메소드를 호출하도록 하는 제어자

static을 공부하기전에 JVM에서 static이 저장되어있는 영역을 이해하면 알기 쉽다. JVM에서 ByteCode를 모아서 저장한 Runtime Data Area에는 5가지 저장 영역이 있는데, static 변수는 패키지 클래스, 인터페이스, 상수, final 변수, 클래스 멤버 변수와 함께 Method Area에 저장된다. Method Area는 로드된 후 모든 쓰레드가 공유하며 항상 상주하고 있는 영역이다. 추가적으로 Heap Area는 변수의 데이터 값을 저장하고 Stack Area는 Heap Area에 저장된 데이터의 주소를 저장한다.

 

static은 그래서 Class Loader가 ByteCode를 탐색할 때 보게되면 항상 메모리를 할당해야하는 영역으로 판단하여 객체를 생성하지 않고 Method Area에 메모리를 할당한다. 그래서 static은 클래스 스코프에 소속된 값이기 때문에 클래스 변수(Class Variable)라고 한다.

같은 이유로 static method가 클래스를 읽게될 때 가장 먼저 읽어들여지기 때문에 변수가 static이 달려있지 않으면 static method안에서 사용할 때는 객체화하여야 한다.

package Week2;

public class Exam5 {    //class method
    private String name = "라이언";
    private static int age = 10;

    public static int getAge() {    //static method
        return age;    //static method 에서는 객체화하거나 static 변수만 들어갈 수 있다.
    }
    public String getName() {     //method
        return name;
    }
    public static void main(String[] args) {    //main method
//        System.out.println(age);
        Exam5 exam5 = new Exam5();
        System.out.println(exam5.getName());
        System.out.println(exam5.getAge());
    }
}

연결해서 위에서 봤던 것처럼 Main method안에 static 변수가 들어갈 수 없는 이유를 알 수 있게 된다. 자바에서 Main method는 static method로 설정되어 class파일을 읽을 때 가장 먼저 읽는 method이기 때문에 같이 static으로 선언된 변수가 아니면 읽을수 없기 때문에 반드시 객체화를 해서 읽어야 한다.

 

변수의 종류 정리

마지막으로 변수의 종류를 다시 한번 정리하면 다음과 같다.

변수의 종류 스코프 생성 시기
클래스/전역 변수(class variable) class 영역 내부 클래스가 메모리에 올라갔을 때
인스턴스 변수(instance vairable) class 영역 내부 인스턴스가 생성되었을(객체화 되었을) 때
지역 변수(local variable) method 영역 내부 변수의 선언문이 수행되었을 때

 

라이프타임

변수의 라이프타임은 클래스 변수의 경우 프로그램이 종료될 때까지 유지되고, 지역 변수는 메소드가 끝나면 자동으로 소멸된다. 인스턴스 변수가 조금 특이한데 인스턴스가 참조되고 있을 때는 유지되다가 참조하는 변수가 없을 경우 GC가 판단 후 제거 한다.

 

 

타입 변환, 캐스팅 그리고 타입 프로모션

타입변환

앞서 기본형과 같은 type을 고정시켜서 사용을 했을 때 다른 type으로 변환해야하는 경우가 생긴다. 막상 타입을 바꾸려니 type마다 데이터 크기가 다르기 때문에 값이 미세하게 달라 쉽지만은 않다. 이때 변환을 할 수 있는 두가지 타입 변환이 캐스팅(강제 형변환), 타입 프로모션(자동 형변환)이다.

 

캐스팅의 경우 단순하다. 타입이 다르다면 변환할 변수 바로 앞에 (변환할 타입)을 입력하면 된다. 하지만 아래와 같은 에러가 날 수 있으니 주의사항이 있다.

package Week2;

public class Exam6 {
    public static void main(String[] args) {
        double a = 123.456;
        int b = (int) a;

        short c = 1234;
        byte d = (byte) c;

        System.out.println("a : " + a);
        System.out.println("b : " + b);
        System.out.println("c : " + c);
        System.out.println("d : " + d);
    }
}
//[출력]
//a : 123.456
//b : 123
//c : 1234
//d : -46

double > int로 변환했을 때는 0.456이 없지만 표현범위가 다르니 조금 다른 값이 나왔지만 문제는 short > byte다. byte의 표현 범위에서 훨씬 넘은 값이 short에서 들어오니 1234에서 -46으로 전혀 다른 값이 나오게 되었다. 이처럼 강제 형변환을 진행할 때는 변환되는 타입의 범위를 신중하게 고려해서 진행해야한다.

 

타입프로 모션의 경우 직접 캐스팅처럼 사용자가 입력하지 않아도 컴파일러가 자동으로 형변환을 추가해주는 것을 말한다.

package Week2;

public class Exam7 {
    public static void main(String[] args) {
        byte a = 12;
        int b = a;

        System.out.println("a : " + a);
        System.out.println("b : " + b);
    }
}
//[출력]
//a : 12
//b : 12

굳이 int b = (int) a;로 캐스팅하지 않아도 알아서 형변환을 컴파일러가 해주는 모습을 볼 수 있다. 단, 자동 형변환은 표현할 수 있는 범위가 클 때만 사용할 수 있으므로 자동 형변환 순서에 유의해야한다.

byte(1) < short(2), char(2) < int(4) < long(8) < float(4) < double(8)

위 순서와 반대로 동작했을 경우 다음과 같이 IDE에서 캐스팅을 요구한다.

 

1차 및 2차 배열 선언하기

배열이란 내가 원하는 타입의 변수들을 집합체라고 보면 된다. 같은 타입의 변수들을 여러 개 선언했을 때보다 하나의 배열에 묶어서 저장하는 것이 나중에 사용하기 더 편하기 때문이다.

 

배열의 선언에는 두 가지 방법이 있다. (int형으로 예를 들었다.) 어떻게하든 본인이 편한 방법을 사용하면 된다.

int[] array;
int array[];

위처럼 선언만 해두었을 때는 배열은 null값을 가진 채 어떤 주소나 배열을 저장하고 있지 않은 상태이다. 따라서 이후 초기화를 하여야 배열에 주소가 배정되어 사용할 수 있다. 한번 선언한 배열의 크기는 정적이기 때문에 크기를 늘리기 위해서는 새로운 배열을 생성하여야 한다.

package Week2;

public class Exam8 {
    public static void main(String[] args) {
        // 선언과 동시에 배열 크기 할당
        int[] array1 = new int[5];

        // 선언과 동시에 배열 크기 할당 및 초기화
        int[] array2 = new int[]{1,2,3,4,5};
        int[] array3 = {1,2,3,4,5};

        // 기존 배열에 참조 변수 초기화
        int[] array4;
        array4 = new int[]{1,2,3,4,5};
        array4 = new int[5];
//        array4 = {1,2,4,5,6};
    }
}

나머지 배열 초기화 방법의 경우 편한 방법으로 사용하면 되는데 문제는 제일 마지막 코드이다. 선언과 동시에 초기화를 할 때에는 가능했던 방법이 기존 배열에 참조 변수 초기화를 할 때는 에러가 나므로 조심해야한다.

 

2차원 배열은 1차원 배열의 연장선이다. 기존에있던 배열값에 새로운 배열을 넣는 것이다. 배열 선언은 1차원과 마찬가지로 변함이 없다.

int[][] array;
int array[][];

다음은 초기화방법이다.

package Week2;

public class Exam9 {
    public static void main(String[] args) {
        // 선언과 동시에 배열 크기 할당
        int[][] array1 = new int[3][4];
        
        // 선언과 동시에 배열 크기 할당 및 초기화
        int[][] array2 = new int[][]{{1,2,3}, {4,5,6}, {7,8,9}};
        int[][] array3 = {{1,2,3}, {4,5,6}, {7,8,9}};
        
        // 기존 배열에 참조 변수 초기화
        int[][] array4;
        array4 = new int[][]{{1,2,3}, {4,5,6}, {7,8,9}};
        array4 = new int[3][4];
    }
}

단 주의해야할 점은 기존 배열에 새로운 배열을 추가하는 것이기 때문에 2차원 배열의 1차원값에는 주소가 들어간다는 것이다.

1차원 배열에서는 배열에 주소를 저장하고 배열 각 값이 변수가 되었다. 하지만 2차원 배열에서는 배열안에 배열을 또 넣는다는 개념이기 때문에 array는 2차원 배열 자체의 주소를 나타내며 array[]값들은 또 각각의 배열의 주소를 나타내게 된다. 따라서 우리가 원하는 변수를 받아내기 위해서는 확실한 배열 값을 입력해야 한다.

 

타입 추론, var

타입 추론(Type Integerface)이란 코드 작성 당시에는 타입이 정해지지 않았지만, 컴파일러가 그 타입을 유추하는 것을 말한다. 일단 Java 9 이하에서는 var 키워드를 제공하지 않고 Generic이나 lambda에서 타입 추론이 사용되었다.

 

Generic

객체의 타입을 컴파일 시에 체크하여 객체의 타입 안정성을 높이고 형변환의 번거로움이 줄어들도록 한 것

제너릭 타입이란 타입을 파라메터로 가지는 클래스와 인터페이스를 말하며 선언된 클래스 또는 인터페이스 뒤에 <>가 붙는다. <> 사이에는 타입 파라메터가 위치한다.

public class 클래스<T> {...}

public interface 인터페이스<T> {...}

다음 코드가 단적으로 제너릭의 작동을 볼 수 있는 코드이다.

package Week2;

public class Exam10<T> {
    private T t;
    public T get() {
        return t;
    }
    public void set(T t) {
        this.t = t;
    }
    public static void main(String[] args) {
        Exam10<String> A = new Exam10<>();
        A.set("ABC");
        System.out.println(A.get());
        System.out.println("A타입 : " + A.get().getClass().getName());

        Exam10<Integer> B = new Exam10<>();
        B.set(123);
        System.out.println(B.get());
        System.out.println("B타입 : " + B.get().getClass().getName());
    }
}
//[출력]
//ABC
//A타입 : java.lang.String
//123
//B타입 : java.lang.Integer

제너릭을 이용해서 타입을 굳이 정해두지 않았음에도 불구하고 각각 다른 타입을 넣었을 때 제너릭이 알아서 Integer와 String으로 변환하였음을 확인할 수 있다.

제너릭과 관련된 자세한 공부는 14주차에 진행하는 것으로 한다.

 

자바 10부터는 Generic이나 lambda가 아닌 타입 추론을 지원하는 var이라는 키워드가 추가가 되어서 자바에서도 타입 추론이 가능하게 되었다.

String value = "테스트";

var value = "테스트";

컴파일러가 오른쪽 초기화 값으로 제공되는 리터럴을 통해서 타입을 유추하게 된다.

var을 사용하는데에는 제약사항이 발생하는데 다음 제약 사항을 지키지 않으면 컴파일 에러가 발생한다.

  1. 로컬 변수에 사용되어야 한다.
  2. 선언과 동시에 초기화 되어야 한다.
컴파일 에러난 부분을 확인할 수 있다.

위 두가지 조건을 충족시키지 못했을 때 a(case 1), b(case 2)와 같이 컴파일러가 에러로 받아들인다.

자바 10부터 지원하는만큼 현재 대부분의 서비스에서 사용되어지는 자바 8에서는 사용이 불가능하다.

(언제부터 자바 11로 기술전환이 될지는 모르지만 지금 당장은 제너릭과 람다를 더 공부하는 것이 좋을 듯 하다..)

 

 

'JAVA > whiteship-livestudy' 카테고리의 다른 글

상속  (0) 2021.03.28
클래스  (0) 2021.03.24
제어문  (0) 2021.03.17
연산자  (0) 2021.03.16
JVM은 무엇이며 자바 코드는 어떻게 실행하는 것인가  (0) 2021.03.11
댓글
최근에 올라온 글
Total
Today
Yesterday