java week2, 자바 데이터 타입, 변수 그리고 배열


목차



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


primitive Type

그림


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


  • Primitive type
    • byte, short, signed/unsigned int, signed/unsigned long, float, double, boolean, char
    • not object
    • 값 저장
    • 기본형 타입은 실제 값을 스택 메모리에 저장한다.
    • 컴파일 시점에 담아야 하기 때문에, 담을수 있는 크기를 벗어나면 에러를 발생시킨다. 주로 컴파일 에러가 발생한다.
  • Reference type
    • primitive type 을 제외한 나머지 type 전부
    • 주소 저장(변수의 값이 저장되어 있는 곳의 메모리 주솟값을 저장하며 heap 공간에 값을 저장한다.)

리터럴


변수에 저장된 상수 값을 literal 혹은 constant 라고 한다.

고정된 값을 갖는 소스코드 표현 형태

ex

boolean result = true; //리터럴 true
char capitalC = 'C'; //리터럴 'C'
byte b = 100;       //리터럴 100
short s = 10000;    //리터럴 10000
int i = 100000;     //리터럴 100000

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


  • C/C++ 과 동일 ```java class A{ public int a; }

class Hello{ public static void main(String[] args) { // primitive type variable declaration and initialization int value = 10;

	// reference type object declaration and initialization
    A a = new A();
} } ```

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


스코프는 변수의 사용 가능 범위이다.

우선순위는 블럭안에 있는 변수를 우선으로한다.

변수는 지역변수, 매개변수, 인스턴스 변수, 클래스 변수에 따라 라이프 타임이 나뉘게된다.

지역변수

지역변수는 블럭안에 변수를 선언하고 블럭이 끝나기 전까지 유효하다.

public void hello(){
    int localVariable; // 지역변수 {범위 : 블럭이 끝나기 전까지(hello 함수의 끝나기 전까지)}
    while(true){
        int 반복;   //지역변수{범위 : 블럭이 끝나기 전까지(while문이 끝나기 전까지)}
    }
}

매개변수

매개변수는 메소드 괄호안에 선언하고 메소드가 끝나기 전까지 유효하다.

public void hello(int parameter // 매개변수){
    return null;
}

인스턴수 변수

인스턴스 변수는 클래스 안, 메소드/블럭 밖에서 선언된 변수이며

클래스의 인스턴스가 생성되고 참조될때까지 유효하다.

public class HelloWorld{
    int instanceVariable; // 인스턴스 변수
    {
        int localVariable; // 지역 변수
    }
    public void hello(int parameter // 매개변수){
        int localVariable; // 지역변수
    }
}
public class HelloWorlds{
    public static void main(String[] args){
        //인스턴스 생성 hello.instanceVariable 생성
        HelloWorld hello = new HelloWorld(); 
        hello = null; // HelloWorld 클래스 참조 해제
        // GC... hello.instanceVariable 소멸
    }
}

클래스 변수

클래스 변수는 변수에 static 키워드를 붙여 사용하고 JVM이 클래스를 로딩할때 초기화 되고,

public class HelloWorld{
    static int staticVariable; // 클래스 변수
    int instanceVariable; // 인스턴스 변수
    static {
        staticVariable = 20;
        instanceVariable = 10; // warning
        /**
            인스턴스 변수의 라이프 타임 시작은 
            인스턴스를 생성할때이므로,
            클래스로딩 시점에 초기화 되는 
            static블럭에서 초기화가 불가능하다.
        **/
    }
    {
        int localVariable = 10;
        instanceVariable = localVariable;
    }
    public void hello(int parameter // 매개변수){
        int localVariable; // 지역변수
        staticVariable = 10;
    }
}
public class HelloWorlds{
    public static void main(String[] args){
           /**
               main 쓰레드가 main() Frame을 JVM 스택에 올렸을때 이미 
               HelloWorld의 staticVariable은 초기화 되어있으므로,
               인스턴스를 생성하지 않아도 된다.
           **/
        System.out.println(HelloWorld.staticVariable) // 20;
    }
}

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


타입 변환은 명시적(캐스팅) / 묵시적(프로모션) 타입 변환으로 나뉘게 된다. 그림

명시적 형변환(Demotion)

더 작은 범위를 나타내는 데이터 타입으로 변환되는 경우

    double avgAge = 23.86;
    int age = (int)avgAge;    // 24, 문장에서 명시적 형변환

묵시적 형변환(Promotion)

형변환 연산자를 사용하지 않아도 자동으로 이루어지는 경우

    int age = 25;
    double avgAge = age;    // 25.0,  (double)

객체의 형변환

객체 참조변수의 경우에도 형변환이 이루어진다. 대입규칙

  • 부모클래스(leftObjRef) = 자식클래스(rightObjRef)
  • 왼쪽 항과 오른쪽 항의 객체 유형이 서로 다른 경우 두 유형이 서로 상속 관계에 있음
  • 왼쪽 객체가 오른쪽 객체의 상위 클래스인 경우에만 묵시적 형변환 발생

  • 자식 클래스에서 부모 클래스 유형으로 할당하는 것은 가능하지만, 반대의 경우 명시적 형변환을 사용해야 함 단, 할당되는 인스턴스 유형에 따라 실행 오류 발생 내부 특정 클래스 형이 다른 클래스 형으로 변환될 수 있는지 여부를 수시로 판단해야 한다.

판단은 instance of 연산자를 통해 확인가능

class Employee {
    // ...
}
class Manager extends Employee {
    // ...
}
public class InstanceOfTest {
    public static void main(String arg[]) {
        Manager mg = new Manager();
        Employee ep = new Employee();
        System.out.println(mg instanceof Manager);    // true
        System.out.println(mg instanceof Employee);    // true
        System.out.println(ep instanceof Manager);    // false
    }
}

형변환과 멤버 변수

서로 상속 관계에 있는 두 클래스 간에는 동일한 이름의 변수가 존재하거나 메서드가 Overriding 되어 있을 수 있음

생성된 객체 변수를 통해 멤버에 접근할 때 주의해야 함

객체 참조 변수가 변수나 메서드를 참조하는 경우, 참조 관계를 결정하는 시간이 다르기 때문에 차이가 발생

class Parent {
    int num = 10;
    
    void printNum() {
        System.out.println(num);
    }
}
 
class Child extends Parent {
    int num = 20;
    
    void printNum() {
        System.out.println(num);
    }
}
 
public class ObjectCastTest {
    public static void main(String args[]) {
        Parent p = new Parent();
        p.printNum();    // 10
        System.out.println(p.num);    // 10

        Child c = new Child();
        c.printNum();    // 20
        System.out.println(c.num);    // 20

        Parent p = new Child();
        p.printNum();    // 20
        System.out.println(p.num);    // 10

    }
}

1차 및 2차 배열 선언하기


class ArrayExample {
	public static void main(String[] args) {
        //1차원 배열
        int[] oneDimensionArrayEx1 = {1, 2, 3, 4, 5};
        int[] oneDimensionArrayEx2;
        oneDimensionArrayEx2 = new int[10];

        //2차원 배열
        int[][] twoDimensionArrayEx1 = { {1, 2}, {3, 4} };
        int[][] twoDimensionArrayEx2;
        twoDimensionArrayEx2 = new int[10][10];
    }
}

1차원 배열

그림

2차원 배열

그림


타입 추론, var


10버전 이상부터 type inference 기능이 추가됨 method 호출 및 선언과 variable 혹은 object 선언을 통해 실제 타입을 추론하는 형식

Generic type

C++ 의 template 과 비슷한 개념 Generic 은 primitive type 사용 불가능하다. template 과는 다르게 type-erasure 개념이 적용되어 type safe를 최대한 보장하려고 노력함

  • type-erasure 컴파일러가 parameterized type에서는 새로운 클래스들이 생성되지 않는 걸 보장한다.
    • 컴파일러가 unbound type T 를 Object 로 변환함
        public static <T> boolean hasElement(T[] elements, T element){
        for(T e : elements){
            if(e.equals(element){
                return true;
            }
        }
        return false;
        }
      

      =>

          public static boolean hasElement(Object[] elements, Object element){
              for(Object e : elements){
                  if(e.equals(element){
                      return true;
                  }
              }
              return false;
          }
    

    결국 생성된 바이트코드에는 원래의 class, interface, method 만을 포함하고 있음

var 라는 type keyword 를 사용하여 실제 타입을 추론

var url = new URL("http://www.naver.com"); // var is URL type
var list = new ArrayList<String>(); // var is ArrayList<String> type





© 2019.04. by salmon2

Powered by theorydb