JAVA STUDY week2: Java data type, variable, array

목적

  • 백기선님의 java study 공부 내용을 공유하기 위함
    1주차
    2주차

목차

1. Java Data Type
2. 변수(variable) - 선언, 초기화, 스코프, 라이프타임, 타입 변환, 캐스팅
3. 배열 - 1차, 2차
4. 타입 추론

1. Java Data type

Primitive Type

자바에서 기본자료형 혹은 원시자료형이라고 불리며 값을 할당할 때 변수의 주소값에 값이 자체로 저장되는 데이터 타입이다. 해당 데이터 타입은 값이 할당되면 java의 메모리 영역 중 Stack 영역에 값이 저장된다.

종류

Reference Type

참조 자료형이라고 불리며 종류는 무한하다. 무한하다고 불리는 이유는 만들 수 있는 클래스에 대해 적용되는 타입이기 때문이다. 따라서 java의 메모리 영역 중 heap에 메모리가 할당되며 레퍼런스 타입의 변수 주소값에는 값이 아닌 heap 영역의 할당된 주소를 저장하고 있다. 배열, 클래스, 인스턴스 등이 레퍼런스 타입이다.

int a = 1;
float b = 1.0;
Coke c = New Coke("Pepsi"); // Coke라는 클래스가 있다고 가정

위와 같은 코드는 아래와 같은 그림으로 할당 되어있다.

리터럴, 상수

상수(constant)라는 것은 값을 가지는 변수지만 변수 중 한번 값이 지정되고 바꿀 수 없는 변수라고 할 수 있다.
반면에 리터럴(literal)이라는 것은 이러한 변수 및 상수에 저장되는 값 그 자체를 말한다.

public static final float PI = 3.141592f
String s = "JAVA"

위에서 보이는 PI 라는 것은 상수이고, 3.141592, "JAVA" 에 해당하는 것이 리터럴 이라고한다. 특성에 따라서 정수 리터럴, 실수 리터럴, 문자열 리터럴 등으로 부른다.

2. 변수(variable) - 선언, 초기화, 스코프, 라이프타임, 타입 변환, 캐스팅

변수 선언 및 초기화

변수라는 것은 데이터를 저장하기 위해 프로그램에 의해 이름을 할당 받은 메모리 공간이라고 할 수 있다. 즉 변수가 선언이 되면 메모리에 공간을 할당하게 되고 초기화를 하면 데이터 값이 할당된 공간에 저장이 된다.

int a; // 변수 선언(Declaration)
a = 10; // 변수 초기화(initialize)

int a =10; //변수 선언 및 초기화

변수의 스코프

프로그램상에서 사용되는 변수들은 사용 가능한 범위를 가지게 된다. 그 변수의 범위를 스코프라고 한다.

변수가 선언된 블럭이 그 변수의 사용 범위이다.

public class globalScopeClass(){
	int globalScope = 10;
    
    public void inerScopeClass(int x){
    	int localScope = 10;
        System.out.println(globalScope);
        System.out.println(localScpe);
        System.out.println(x);
    }
}
  • 클래스 속성으로 선언된 변수 globalScope의 사용 범위는 클래스 전체이다.
  • 매개변수로 선언된 int value는 블럭 바깥에 존재하기는 하지만, 메서드 선언부에 존재하므로 사용범위는 해당 메서드 블럭내이다.
  • 메서드 블럭내에서 선언된 localScope 변수의 사용범위는 메소드 블럭내이다.
public class globalScopeClass(){
	int globalScope = 10;
    static int staticVar = 10;
    public void inerScopeClass(int x){
    	int localScope = 10;
        System.out.println(globalScope);
        System.out.println(localScpe);
        System.out.println(x);
    }
	public static void main(){
    	System.out.println(globalScope); // 오류
        System.out.println(localScpe); // 오류
        System.out.println(x); // 오류
        System.out.println(staticVar); // 오류
    }
}
  • 같은 클래스 안에 있지만 globalScope 변수를 사용 할 수없다.
  • main은 정적 메서드이다. 정적메서드에서는 static field만 사용 할 수 있다.

static

  • 같은 클래스 내에 있음에도 해당 변수들을 사용할 수 없다.
  • main 메서드는 static 이라는 키워드로 메소드가 정의되어 있다. 이런 메서드를 static 메서드라고 한다.
  • static한 필드나 static한 메서드는 Class가 인스턴스화 하지 않고도 사용할 수 있다.
  • static한 변수는 모든 인스턴스 끼리 공유 된다. 즉 메모리 할당 자체가 한번만 된다.

변수 타입별 스코프와 라이프타임

  • 인스턴스 변수
    : 클래스 안에 선언 되어있는 변수지만 클래스 내에서 내부의 메서드나 내부의 블록이 아닌 곳에 선언되어있는 변수
    scope: static 메서드를 제외한 모든 클래스
    lifetime: 클래스의 오브젝트가 메모리에 남아있는 한
    - 클래스 변수
    scope: 클래스 내부에 선언 되어있으면서 클래스 내부의 블락에 밖에 static으로 선언되어 있는 변수
    lifetime: 프로그램 종료시까지
    - 로컬 변수
    클래스 변수, 인스턴스 변수가 아닌 모든 변수
    scope: 변수가 선언된 블럭 내부
    Lifetime: 선언된 블럭을 나갈 때 까지
public class scope_and_lifetime {
    int num1, num2;   //Instance Variables
    static int result;  //Class Variable
    int add(int a, int b){  //Local Variables
        num1 = a;
        num2 = b;
        return a+b;
    }
    public static void main(String args[]){
        scope_and_lifetime ob = new scope_and_lifetime();
        result = ob.add(10, 20);
        System.out.println("Sum = " + result);
    }
}

타입 변환 및 캐스팅

캐스팅

여러 변수가 있고 변수간의 타입이 다를 수 있다. 예를 들면 int와 float타입의 변수가 존재한다고 하면
두개의 변수가 저장하는 방식이 다를 수 있다. 그럴 경우 캐스트 연산자라는 것을 사용하게 되는데 이것 하나의 변수를 다른 변수의 저장 방식으로 바꿔주는 연산자이다. 즉 이런 특정 자료형을 다른 자료형으로 변경하는 방법을 타입 캐스팅, 한국말로 형변환이라고 한다.

기본적으로 프리미티브 타입들의 타입캐스팅은 모두 형변환이 가능하다. 물론 데이터의 손실 및 오차가 발생할 수는 있다.
하지만 클래스 타입들은 조금 다르다. 일반적인 클래스끼리는 타입캐스팅이 불가능하다.

상속관계를 가지고 있는 클래스끼리의 타입캐스팅이 가능하다. (추후 상속 관련에서 자세히 다루도록하자)
간단한 규칙만을 알고 넘어가자.

클래스의 타입캐스팅 규칙
1. 부모클래스는 명시적인 타입캐스팅 없이 자식과 연결 할 수 있다. 업캐스팅(Up-Casting)
2. 자식클래스는 명시적인 타입캐스팅이 있다면 부모와 연결 할 수 있다. 다운캐스팅(Down-Casting)이라 한다.
3. 상속관계가 아니면 타입캐스팅은 불가능하다.

3. 배열 - 1차원, 2차원

배열은 동일한 자료형의 데이터를 연속된 공간에 저장하기 위한 자료구조이다. 즉, 연관된 데이터를 그룹화하여 묶어준다고 생각할 수 있다.

배열의 선언

 //int 타입 배열 선언
int[] array;
int array[]; 
		
//배열 생성후 초기화하면 배열의 주소가 할당된다.
int[] i = new int[20]; //초기값 0
String[] s = new String[20]; //초기값 ""
		
//배열 선언만 해놓고 나중에 초기화를 시킬수도 있다.
int[] x;
x = new array[8];

위와 같이 다양한 방식으로 배열을 선언, 초기화 할 수 있다.
즉, 요약하면 배열은
타입 [] 변수명;
타입 변수[];
두가지 방식으로 선언이 가능하다.

2차원 배열

위에서 사용하게 된 배열은 1차원 배열이다. 기본적으로는 1차원 배열을 주로 사용하지만 그것을 넘어서 여러 다차원의 배열을 사용하게 되는 경우가 있다.
예를 들어 int[][] arr = new int[3][4]라는 배열을 생각 해보자.
3개의 배열이 각각 4개의 값을 가지고 있다라고 생각할 수 있다.
와 같이 생각 할 수있다.

1차원 배열과 마찬가지로 선언시 []위치는 자유롭게 설정할 수 있다.
int [][]arr;
int []arr[];
int arr[][];
위와 같은 형태로 선언이 가능하다는 것을 알아두면 좋다.
실제 사용은 첫 번째를 사용하는 것이 좋다.

4. 타입 추론, var

Java 9이하

자바 버전 9이하에서는 Generic과 lambda를 사용할 때 타입추론을 이용한다.
타입추론이란 코드 작성시 타입이 지정되지는 않지만, 컴파일러가 그 타입을 유추하는 것이다.

Java 10이상

var

자바 10부터 타입 추론을 지원하는 var 키워드가 추가되었다. 이 키워드는 local variable 이면서 선언과 동시에 initializer가 필수적으로 요구된다.

// java 9 이하
String msg = "abcd";
// java 10 이상
var msg = "abcdefg";

주의 요구

  • 자바 7에서 다이아몬드 연산자라는 방식이 추가되었는데, 자바 10에서 나온 var와 같이 사용시 오류가 발생함.
// 컴파일러가 타입을 유추할 수 있는 정보 X
var msg = new ArrayList<>(); 
  • 가독성에 있는 측면에 있어서 다른 개발자가 읽을 때 좋을 수 있을까 고민이 필요하다. 만약 어떤 타입이 들어가는지 확인이 바로 되는 경우면 좋지만, 근접해 있지 않거나 한 경우는 가독성이 많이 떨어질 수도 있다.

참조

좋은 웹페이지 즐겨찾기