[자바기본기] 01

sameul__choi·2022년 5월 2일

[자바기본기]

목록 보기
2/3
post-thumbnail

자바 기본기 01

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

  • 자바 프로그래밍 언어는 정적으로 유형이 지정됨
  • 모든 변수를 사용하기 위해서는 먼저 선언해야함
  • ex : int i = 1;
  • 변수의 자료형은 변수에 포함될 수 있는 값과 수행할 수 있는 작업을 결정한다. 7가지의 primitive data types를 지원한다.
  • 원시형은 사전 정의되고 예약된 키워드로 이름이 지정되며, 다른 원시형과 상태를 공유하지 않는다.
이름설명범위
byte8비트 부호있는 2의 보수 정수-128 <= byte <=127
short16비트 부호있는 2의 보수 정수-32,728 <= short <= 32767
int32비트 부호있는 2의 보수 정수-2^31 <= int <= 2^31 -1
long62비트 2의 보수 정수-2^63 <= long <= 2^63 -1
float단정밀도 32비트 IEEE 754 부동 소수점논의의 범위를 벗어남
double배정밀도 64비트 IEEE 754 부동 소수점논의의 범위를 벗어남
booleantrue/ false 단순 플래그에 사용
char16비트 유니코드 문자\u0000 <= char <= \uffff

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

  • 원시형과 참조형이 있는데, 이 둘은 상호보완적이며 변수로써 저장할 수 있고, 인자를 전달할 수 있고, 메서드를 통하여 반환될 수 있다.

  • 원시형은 자바 언어에 의해 미리 정의되어있고, 사전에 예정된 키워드로 이름이 정해져있다.

  • 참조형에는 클래스 타입, 인터페이스 타입, 타입 변수, 배열 타입이 있다.

  • 클래스나 인터페이스 타입은 식별자 또는 점으로 구분된 식별자 시퀀스로 구성된다

  • 각 식별자 뒤에는 선택적으로 타입 인자가 오고 만약 타입인자가 나오면 이는 매개변수화된 타입이라고 볼 수 있다.

  • 클래스 또는 인터페이스 타입의 식별자는 패키지 이름 또는 타입으로 분류된다.

  • 출처 : https://docs.oracle.com/javase/specs/jls/se8/html/jls-4.html#jls-PrimitiveType

리터럴

boolean res = true;
char capC = 'C';
byte b = 100;
short s = 100;
int i = 10000;
  • 위와 같이 원시형 타입의 변수는 초기화 할때 new 키워드를 사용하지 않는다.
  • 원시형 타입은 특별한 데이터 타입이다. 언어 안에 내장되어 있다.
  • 클래스에서 생서된 객체가 아니다.
  • Literal은 고정 값의 소스 코드 표현이다. 계산 없이 코드에 직접 표시된다. 위와 같이 기본 유형의 변수에 리터럴을 할당할 수 있다.

(1) 정수 리터럴

  • long의 정수형 리터럴은 'l' , 'L'이 끝에 붙는다. 그렇지 않으면 int이다. upper case를 사용하는 것이 권장된다. 1과 헷갈리니까
  • byte, short, int, long은 int 리터럴로 만들어질 수 있다. int의 범위를 초과하는 long 값은 long 리터럴을 사용
  • Decimal, Hexadecimal, Binary를 사용하여 정수 리터럴을 사용할 수 있다.
//26
int decVal = 26;
int hexVal = 0x1a;
int binval = 0b11010;

(2) 부동 소수점 리터럴

  • float은 'F', 'f'를 사용한다. 이와 반대로 double은 'D'와 'd' 를 사용하는데 사용여부를 선택하여 사용할 수 있다.
double d1 = 123.4;
double d2 = 1.234e2;
// 위 둘은 같다.

float f1 = 123.4f;

(3) 문자, 문자열 리터럴

  • char, string 타입은 어느 유니코드 캐릭터라도 포함할 수 있다.
char a = \u0108;
String s = "S\u00ED Se\u00F1or";
  • 자바 언어가 지원하는 몇가지 excape sequences 는 다음과 같다

    • \b (backspace), \t(tab), \n(line feed), \f(form feed), \r (carriage return), \"(double quote), \'(single quate), \(backslash)
  • null은 모든 참조유형에 대한 값으로 사용할수 있는 특수 리터럴이다.

  • 기본 유형의 변수를 제외한 모든 변수에 할당할 수 있다.

  • 출처 : https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html

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

  • 프로그램의 모든 변수는 반드시 사용되기 전에 값을 가져야 한다.
  • 클래스 변수, 인스턴스 변수, 그리고 배열 요소는 각각 default value로 생성 될때 초기화 된다.
  • 각 메소드 매개변수는 호출자가 제공한 해당 인수값으로 초기화 된다.
  • 생성자 매개변수는 명시적 생성자 호출에서 제공하는 해당 인수 값으로 초기화 된다.
  • 예외 매개변수는 예외를 나타내는 throw된 개체로 초기화된다.
  • 지역 변수 또는 할당에 의해 사용되기전에 명확한 할당 규칙을 사용하여 확인할 수 있는 방식으로 값을 명시적으로 제공해야만 한다.
  • 출처 : https://docs.oracle.com/javase/specs/jls/se8/html/jls-4.html#jls-PrimitiveType

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

  • scope의 정의는 선언된 엔터티가 표시되는 경우 이름으로 참조하여 사용할 수 있는 프로그램의 영역을 말한다.
  • 즉 변수의 스코프는 해당 변수를 사용할 수 있는 영역 범위를 말한다.
  • 클래스 변수와 인스턴스 변수는 '클래스 영역'
  • 멤버 변수는 클래스 영역에 선언된 변수로 클래스 변수와 인스턴스 변수가 이에 속한다.
  • 지역 변수는 변수를 선언한 블록이 끝나기 전까지 유효하고 매개변수는 메소드 괄호 안에 선언한 후 메소드가 끝나기 전까지 유효하다.
  • 라이프 타임은 변수가 유효한 시간을 말한다. 프로그램이 구동되는 동안 변수가 '값을 담고 있을 수 있는 주기'를 말한다.
  • 하위 패키지에 선언하는 것은 scope안에 있지 않다.
  • package java 는 항상 scope 안에 있다.
변수 종류선언위치스코프라이프타임
클래스 변수클래스 영역클래스 전체클래스가 메모리에 올라간 뒤 프로그램이 마칠 때 까지
인스턴스 변수클래스 영역static 블록과 static 메서드를 제외한 클래스 전체인스턴스가 생성 후 메모리에 살아있을 떄 까지
로컬 변수메소드, 생성자, 초기화 블록 내부변수가 선언된 블록 내부변수 선언 후 블록을 벗어날 때 까지

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

(1) 원시타입의 변환

  • 대상 유형보다 작은 원시형 타입에서의 변환에는 특별한 표기법을 사용할 필요 없음

  • 더 작은 값이 더 큰 컨테이너에 배치되고 빈 공간은 0으로 채워진다.

  • 더 넓은 컨테이너로 가는 것이기 때문에 정보 손실을 걱정하지 않아도 된다.

  • 하지만 더 좁은 컨테이너로 변환은 정보가 손실될 수 있다. 때문에 캐스트를 사용하여 상황을 알고 있음을 명시적으로 표현해야 한다.

int exInt = (int) exDouble;
  • 자바에는 기본 유형에 대한 Wrapper 클래스가 있다. 이는 오버헤드 없이 무거운 참조객체를 가지지 않도록하는 영리한 방법이다.
  • 자동적으로 원시형에서 객체로 변환이 가능하고 간단하게 사용할 수 있다.
Integer exReference = exInt;
int exOtherInt = exReference;
  • 모든 원시형은 Wrapper class를 활용하여 스트링으로 변환할 수 있다. toString() 메서드를 오버라이딩한다.

    String exString = "바보"
    int exNewInt = Integer.parseInt(exString);

(2) 참조타입의 변환

  • 원시타입의 변환과 비슷해보이지만 완전히 다른 개념이다.

    double d = 1.1;
    int i = (int)d;
    
    assertNotEquals(d, i);

    ​ 위의 예에서 i는 1이고, 이전의 1.1값을 복원할 수 없다.

  • 참조 변수는 개체만 참조하지 객체 자체를 포함하지는 않기 때문이다.

  • 참조 변수를 캐스팅하는 것은 참조하는 개체를 건드리지 않고, 이 개체에 다른 방식으로 레이블을 지정하여 작업의 기회를 늘리거나 줄인다. 줄이면 업캐스팅, 다운캐스팅은 늘린다.

  • 참조는 객체의 리모콘 같다. 리모컨은 종류에 따라 더 많거나 적은 수의 버튼을 가지고 개체 자체는 힙에 저장된다. 캐스팅을 할 때 리모콘의 종류는 바꾸지만 객체 자체는 바뀌지 않는다고 생각하자

업캐스팅

  • 자식 클래스에서 부모 클래스로 캐스팅하는 것을 업캐스팅이라고 한다. 일반적으로 업캐스팅은 컴파일러에서 암시적으로 수행된다.
  • 상속과 밀접하게 관련되어 있는데, 구체적인 유형을 참조하기 위해 참조변수를 사용하는 것이 일반적이다.
public class Dog {
  public void eat(){
    
  }
}

// 확장해보자
public class WelshCorgi extends Dog{
  public void eat(){
    
  }
  
  public void bark(){
    
  }
}

WelshCorgi welshCorgi = new WelshCorgi();

// 암시적 업캐스팅 발생
Dog dog = welshCorgi;

//명시적으로 하기
dog = (Dog)welshCorgi;
  • 굳이 명시적으로 하지 않아도 됨, 그 이유는 참조형은 선언된 유형의 모든 하위 유형을 참조할 수 있기 때문
  • 하지만 bark()는 사용하지 못한다. 사용하려면 다운캐스팅을 해야한다.

다운 캐스팅

Dog dog = new WelshCorgi;

((WelshCorgi)dog).bark();

1차 및 2차 배열 선언하기

  • 배열은 여러개의 변수들을 한가지의 변수에 담기 위해 사용한다. 각각의 분리된 변수를 선언하는 것 대신에

  • square brackets을 사용하여 선언할 수 있다.

  • String [] rappers;
    
    String [] rappers = {"esens", "nas", "kimximya"}
    
    String [][] 
  • ArrayLiteral을 사용하여 문자열들을 ','로 구분하여 선언할 수 있다.

  • 2차원 배열도 마찬가지로 square brackets을 사용하여 선언하며, 1차원 더 들어가서 1차원 배열을 두번 선언하고 그 값을 저장한다.

  • String [][] rappsers = {{"bana", "esens"}, {"hilight", "paloalto"}, {"YngRch Records", "homies"}}
  • 출처 : https://www.baeldung.com/java-initialize-array

타입 추론, var

  • 자바 컴파일러가 타입을 추론하는 것을 type inference라고 한다. 컴파일러는 추론을 위해 method invocation과 그에 상응하는 declaration을 살핀다.

  • 추론 알고리즘이 인자의 타입을 결정하고, 가능한 경우에 결과가 할당되는 타입 또는 리턴 타입까지 결정한다. 추론 알고리즘은 모든 인자와 어울리는 선에서 가장 구체적인 타입을 찾는다.

  • 타입 추론 덕분에 generic 메소드를 사용할 때 보통의 메소드와 마찬가지로 특정 타입을 명시하지 않은 채로 호출할 수 있다.

  • generic 메소드를 호출할 때 type witness와 함께 type parameter를 명시할 수 있지만, Java Compiler가 메소드의 인자로부터 자동으로 type 매개변수가 추론해주기 때문에 type witness를 생략할 수 있다.

  • generic 클래스 객체를 생성할 때엔 type inferene의 이점을 이용하고 싶다면 다이아몬드 <>를 반드시 이용해야 한다.

  • 출처 : https://docs.oracle.com/javase/tutorial/java/generics/genTypeInference.html

0개의 댓글