선택문

  1. if
  • 만일 조건식이 참이면 괄호안의 문장들을 실행하라

if (true) { System.out.println(true); } if (조건식) 조건식이 true이면 {} block안의 내용을 실행하라

  • 조건식은 일반적으로 비교연산자와 논리연산자로 구성된다.

  • 조건식의 결과가 true 나 false가 되지 않는다면 에러가 발생한다.

  • 문장이 하나일경우 {} block을 생략할수 있다.

  1. if - else 문
  • if문의 변형으로 if문의 조건이 false일 경우 else {} 블럭이 실행된다.

if (true) { System.out.println(true); } else { System.out.println(false); } if (조건식) 조건식이 false일 경우 else { } block안의 내용을 실행하라

  • 문장이 하나일경우 {} block을 생략할수 있다.
  1. if - else if 문
  • 처리해야할 경우의 수가 3가지 이상일 때 사용된다.

if (true) { System.out.println(true); } else if (true){ System.out.println("else if True"); } else { System.out.println(false); } if (조건식) 조건식false 일 경우 else if (조건식) 의 조건식이 true 일 경우 else if {} block 안의 내용을 실행하라. else if (조건식) 의 조건식이 false 일 경우 else {} block 안의 내용을 실행하라.

  1. 중첩 if 문
  • if문안에 if문을 사용 할 수 있다.

if (true) { if (true) { System.out.println(true) } } if문의 조건식이 true 이고 block 안에 있는 if문의 조건식이 true 이면 {} 블록 안에 있는 System.out.println(true)을 실행하라.

  1. switch문
  • if문은 조건식의 결과가 참과 거짓 두가지 뿐이지만 switch문은 단하나의 조건으로 여러 경우의수를 처리 할 수 있다.

Switch (1) { case 1: System.out.println(1); break; case 2: System.out.println(2); break; default: System.out.println(3) } switch문의 조건식의 결과와 일치하는 case 문을 실행한다. case 값 과 같은 방식으로 이루어져 있으며 결과값은 값과 비교한다. 일치하는 결과값이 없을 경우 default문이 실행된다.

  • case문 내부에 break문을 빼먹는다면 switch {} 블럭의 모든 case들을 실행한다.

  • switch문의 제약조건

    1. switch문의 조건식 결과는 정수 또는 문자열 이어야 한다.
    2. case문의 값은 정수 상수만 가능하며, 중복되지 않아야 한다.

반복문

  • 반복문은 어떤 작업을 반복적으로 수행되도록 할 때 사용된다.
  • for문이나 while문에 속한 문장은 조건에 따라 한번 도 수행되지 않을 수 있지만
  • do while은 무조건 한번은 수행되는것이 보장된다.
  1. for문

    • for문은 반복 횟수를 알고 있을 때 적합하다.
    for (int i=1; i<=5; i++) { System.out.println("Print Number " + i); } 위의 조건문은 1부터 5까지 1씩 증가되는 for문 이며 1씩 증가될때 마다 {} block안의 내용을 실행한다. int i=1; 은 초기화 하는 부분 i<=5; 는 조건식이며 i++ 는 증감식이다. 두가지 변수 초기화 for (int i=1,j=0; i<=5; i++) { }
    • 초기화

      • 반복문에 사용될 변수를 초기화 하는 부분이며 한번만 실행된다.
      • 보통 1개만 사용되지만 2개를 사용하고 싶다면 , (콤마) 를 구분자로 변수를 초기화하면 된다.
        • 단 두 변수의 타입은 같아야 한다.
    • 조건식

      • 조건식 값이 참 이면 반복문을 계속하고 거짓이면 반복문을 중단하고 for문을 벗어난다.
    • 증감식

      • 반복문을 제어하는 변수의 값을 증가 또는 감소시키는 식
      for (int i=0; i<=10; i++) {} // i가 1씩 증가 for (int i=0; i<=10; i--) {} // i가 1씩 감소 for (int i=0; i<=10; i+=2) {} // i가 2씩 증가 for (int i=0; i<=10; i+=3) {} // i가 3씩 증가 for (int i=1, j=10; i<=10; i++, j--) // i는 1씩 증가 // j는 1씩 감소 for (; ;) // 초기화 , 조건식 , 증감식은 모두 생략 조건식은 참이되므로 무한반복된다.
    • for문 역시 중첩으로도 사용 가능하다.

  2. 향상된 for문 ( enhanced for statement)

for ( 타입 변수명 : 배열 또는 컬렉션) { //반복할 문장 } int[] arr = new int[10]; for (int a : arr) { //반복할 문장 }

  • 간결하지만 배열이나 컬렉션에 저장된 요소들을 읽어오는 용도로만 사용하는 제약이 있다.
  1. while문
  • 조건식이 참인 동안만 {} block 내의 문장을 실행하라

while (조건식) { // 조건식의 연산결과가 참인 경우만 실행 }

  • while문의 조건식은 생략 불가하다.
  1. do - while 문
  • do while문은 while문의 변형으로 while문과 구조는 같지만 앞에 do와 {} block이 붙어있어 이 block이 먼저 한번은 무조건 수행된다.

do { } while (조건식);

  • 한번은 수행되지만 그 이후로는 조건식이 참이여야 수행된다.
  1. break문
  • 자신이 포함된 가장 가까운 반복문을 벗어난다.
  • 주로 while에서 if문과 함께 while문을 탈출할때 많이 사용한다.

while (true) { System.out.println(true); if (true) { break; } }

  1. continue 문
  • continue문은 반복문 내에서만 사용될 수 있으며 반복이 진행되는 도중 continue문을 만나면 반복문의 끝으로 이동되어 다음 반복으로 넘어간다.
  • for문의 경우 증감식으로 이동되며
  • while과 do-while문은 조건식으로 이동한다.

while (true) { System.out.println(true); if (true) { continue; } } continue;를 만나면 다시 while의 조건문으로 이동한다. for (int i=0; i<10; i++) { System.out.println(true); if (true) { continue; } } continue를 만나면 증감식으로 이동한다.

출처

java의 정석

'백선생님 온라인스터디' 카테고리의 다른 글

7주차 - 패키지  (0) 2021.01.12
6주차 상속  (0) 2021.01.10
3주차 연산자  (0) 2021.01.07
연산자  (0) 2020.11.28
스터디 2주차 - 자바 데이터타입, 변수 그리고 배열  (0) 2020.11.21

목표

  • 자바가 제공하는 다양한 연산자를 학습하세요

학습할것

  • 산술 연산자
  • 비트 연산자
  • 관계 연산자
  • 논리 연산자
  • instanceof
  • assignment(=) operator
  • 화살표(->) 연산자
  • 3항 연산자
  • 연산자 우선 순위
  • (optional) Java 13. switch 연산자

산술 연산자

  • 산술연산자는 사칙연산자 ( + , - , * , / ) 4개와 나머지 연산자 ( % ) 로 이루어져 있다.

  • 사칙 연산자

    • 피 연산자가 정수 일 경우 0 으로 나눌수 없다.

    • 피 연산자가 같을 경우 결과는 피연산자와 같고

    • 피 연산자가 다를 경우 ( 정수 + 실수 ) 조합일 때 결과는 실수가 된다.

    • 피 연산자가 다를 경우에는 좀더 범위가 넓은쪽을 결과의 타입으로 쓴다.

    • 연산자 결과의 최소 타입은 int형이다.

      byte a = 1; byte b = 1; byte c = a+b; // 에러발생 provided는 int형 인데 byte에 담으려 했기 때문 byte c = (byte)(a+b); // 명시적 형변환할 경우 에러안남
      • byte+byte로 더해서 byte에 담으려 하면 에러가 난다.
        • 결과는 int로 나오는데 int ( 4byte)보다 더작은 byte에 담으려 했기 때문
        • 이때는 명시적으로 형변환을 시켜줘야 한다.
        • 하지만 큰 타입에서 작은 타입으로 변환해서 데이터를 넣을 경우
        • 값이 작은 타입의 데이터 범위를 넘을 경우 데이터 손실이 일어난다.
    int aa = 1000000; int bb = 1000000; long cc = aa*bb; // result -727379968
    • 같은 타입 피연산자의 연산결과 합이 타입의 허용 값을 넘어서 결과가 나온다면
    • 더 높은값을 담을수 있는 타입에 저장할 때 이 타입의 형태로 저장되는게 아닌 피연산자 타입의 연산결과의 합이 담긴다.
    • 그리고 연산 중 오버플로우가 일어난다면
    • 상위 타입에 저장한다고 해도 이미 오버플로우가 일어나서 오버플로우가 일어나기 전까지의 값만 저장가능하다.
  • 문자열 연산

char a = 'a'; char b = 'b'; char c = a+b; // 결과값은 Ã String a = "a"; String b = "b"; String c = a+b; final char a= 'a'; final char b = 'b'; char ccc = a+b; // 에러 안남

  • char의 문자열 연산은 해당문자의 유니코드 ( 정수 ) 로 바뀌어 저장되므로 정수간의 연산이된다.

  • 문자열 자체가 더해지는 것이 아닌 유니코드가 더해져서 char에 변수에 담는것이다.

  • 재밌게도 스트링은 따로 형변환을 안해도 되고 그자체로 더해진다.

    • 그 이유는 스트링은 리터럴이기 때문이다.
    • 리터럴 끼리의 합은 형변환을 안해도 된다.
      • 문자열 끼리만이 아닌 정수와 실수도 가능하다.
  • 리터럴 연산

    • 리터럴 연산은 컴파일시 컴파일러가 먼저 계산하고 리터럴간의 연산을 먼저 실행시킨다.
    • 그래서 형변환을 안해도 연산이 되는것이다.
    • 만약 리터럴이 아닐경우 도중에 값이 바뀔 위험이 있기에 컴파일러가 미리 연산을 하지 못한다 그래서 형변환이 필요한것이다.
  • 나머지 연산자

    • 왼쪽의 피 연산자를 오른쪽의 피연산자로 나누고 난 나머지 값을 결과로 리턴하는 연산자.
    • 나눗셈처럼 나누는 수 ( 오른쪽 피 연산자) 를 0으로 사용할수 없다.

비트 연산자

  • 피연산자를 비트단위로 논리 연산한다.

  • 피연산자를 이진수로 표현할 경우의 각 자리를 규칙에따라 연산하고 피연산자로 실수는 허용하지 않는다. 정수만 가능

  • 연산 규칙

    • | ( OR 연산자 )
      • 피연산자 중 한쪽의 값이 1이면 1로 값을 리턴한다 그 이외에는 0으로 리턴
    • & ( AND 연산자 )
      • 피연산자 양쪽이 모두 1이어야만 1로 값으로 리턴한다. 그이외에는 0으로 리턴
    • ^ ( XOR 연산자 )
      • 피연산자의 값이 서로 다를때만 1로 값을 리턴한다. 같을때는 0을 리턴한다.
  • 쉬프트 연산자 << >>

    • 피연산자의 각 자리 ( 2진수로 표현했을 때)를
    • 오른쪽 >> 또는 왼쪽 << 으로 이동한다고 해서 쉬프트 연산자 라고 불린다.
    • 예를 들어 " 8 << 2 " 는 왼쪽 피연산자인 10진수의 8의 2진수를 왼쪽으로 2자리 이동한다.
    10진수 8은 2진수로 '00001000' 8 << 2 는 10진수 8의 2진수를 왼쪽으로 2자리 이동시킨다 0 0 0 0 1 0 0 0 에서 왼쪽으로 2자리 이동되므로 가장 앞 2자리는 버려진다. 남은 값은 0 0 1 0 0 0 0 0 (10진수로 32) 빈자리는 0으로 채워진다. System.out.println((8 << 2)); // 결과값은 32
  • 비트전환 연산자 ~

    • 피연산자를 2진수로 표현했을때 0은 1로 , 1은 0으로 바꾼다.
    byte p = 10; System.out.println("~p = " + ~p); // 결과 -11 10은 이진수로 00000000000000000000000000001010이 된다. ~를 사용하여 0과 1이 뒤바뀌면 아래와 같이 -11의 이진수 값이 된다. -11은 이진수로 11111111111111111111111111110101이 된다.

관계 연산자

  • 두 연산자를 비교하는데 사용되는 연산자다.
  • 주로 조건문 과 반복문의 조건식에 사용된다.
  • 결과는 오직 true, false 단 두개뿐이다.

대소비교 연산자

  • 두 연산자의 값의 크기를 비교하는 연산자

  • 참 일 경우 true , 거짓이면 false를 리턴한다.

  • boolean형을 제외한 나머지 자료형에는 사용가능하나 참조형에는 사용할수 없다.

  • 4가지 종류가 존재한다.

      • 좌변이 크면 ture 아니면 false
    • <
      • 좌변이 작으면 true 아니면 false
    • =

      • 좌변이 크거나 같으면 true 아니면 false
    • <=
      • 좌변이 작거나 같으면 true 아니면 false

등가비교 연산자

  • 두 피연산자의 값이 같은지 또는 다른지를 비교하는 연산자

  • 대소비교 연산자와 다르게 기본형 , 참조형 , 모든 자료형에 사용 가능하다.

  • 기본형의 등가비교일 경우 저장되어있는 값이 같은지를 알수 있고

  • 참조형의 등가비교일 경우 저장되어있는 객체의 주소값을 비교한다.

  • 2가지 종류가 존재

    • ==
      • 두 값이 같으면 ture 아니면 false
    • !=
      • 두 값이 다르면 true 아니면 false

문자열의 비교

  • String으로 문자열을 비교할 경우에는 == 대신 equals를 사용 해야 한다.
  • ==로 비교하는 것은 참조주소를 비교한다는 것이기 때문에 만약 문자열이 같더라도
  • 참조주소가 다르면 다른것으로 간주하기 때문이다.
  • equals를 사용하면 문자열을 비교하기 때문에 문자열이 같으면 true를 반환한다.

논리 연산자

  • 2가지 조건으로 결합하여 참과 거짓을 구분한다.
    • && 와 ||

boolean a = true; boolean b = false; (a && a) // true (a || a) // true (a && b) // false (a || b) // true (b && b) // false (b || b) // false

  • 2가지 조건
    • && ( AND 결합 )
      • 피연산자 양쪽 모두 true 이어야 true를 리턴한다.
    • || ( OR 결합 )
      • 피연산자 중 한쪽 만 true면 true를 리턴 한다.

논리 부정 연산자

  • 피연산자가 true면 false로 false면 true로 결과를 바꿔서 리턴한다.

boolean a = true; boolean b = false; !a // false; !b // true;

instance of 연산자

  • 참조변수가 참조하고 있는 인스턴스의 실제 타입을 확인하는 연산자.
  • instanceOf 가 true 란 것은 그 타입일수도 있고 그 타입으로 형변환이 가능하다는 것이다.

void test (Car c) { if (c instanceOf SportsCar) { SportsCar sc = (SportsCar)c; } }

  • 위와 같이 사용할 경우 test 메소드의 Car c의 타입을 정확히 알수가 없다.
  • 진짜 car인지 아니면 car의 자손 클래스인지 정확히 알수가 없다.
  • 그렇기 떄문에 체크해서 사용한다.

assignment(=) operator

  • 대입 연산자

    • 변수와 같은 저장공간에 값 또는 수식의 연산결과를 저장하는데 사용
    • 오른쪽 피연산자의 값을 왼쪽 피연산자에 저장한다.
    • 대입 연산자의 왼쪽 피연산자를 lvalue ( left value ) 라고 하며
    • 오른쪽을 rvalue ( right value ) 라고 한다.
  • 복합 대입연산자

    • 다른 연산자와 결합하여 op= 와 같은 방식으로 사용가능하다.
    i = i+3; 과 같은 코드를 i +=3; 과 같이 사용 가능하다.

화살표 연산자

  • lambda를 표현식을 작성하기 위한 연산자다.

1. Interface k = new Interface() { @Override public void main() { } }; 2. Koy k = () -> { };

  • 위와 같이 인터페이스의 메소드가 1개일 경우 아래와같이 익명함수를 간단하게 람다식으로 변경할수 있다.

3항 연산자

  • 피연산자를 3개를 사용하는 연산자
  • 조건식과 결과 결과 로 이루어져 있으며 결과에 다시 3항연산자가 들어갈수도 있다.

int a = 1; int b = 2; int c = 3; boolean d = a < b ? true : false boolean d = a < b ? a < c ? true : false : false

연산자 우선순위

  • 식에 사용된 연산자가 둘 이상일 경우 연산자 우선순위에 의해 순서가 결정된다.
  • 곱셈과 나눗셈은 덧셈과 뺼셈보다 우선순위가 높다. ( 기초수학 )

x << 2 + 1 data & 0xFF == 0 x < 1 || x > 3 && x < 5

  • << 연산자는 덧셈 연산자보다 우선순위가 낮다.
  • & 연산자는 == 연산자보다 우선순위가 낮다.
  • &와 && 연산자는 |과 || 보다 우선순위가 높다.
  • and 와 or을 같이사용하는 경우에는 괄호를 사용해 우선순위를 명확하게 하는것이 좋다.

x + 3 > y - 2 x > 3 && x - 2 result = x + y * 3

  • 비교연산자는 산술 연산자보다 우선순위가 낮다

  • && 연산자는 비교 연산자보다 순위가 낮다.
  • 대입연산자는 연산자중에서 우선순위가 제일 낮다.

우선순위 결론

  • 산술 > 비교 > 논리 > 대입 의 순위이며

  • 대입은 제일 마지막에 수행된다.

  • 단항 > 이항 > 삼항

  • 단항 연산자의 우선순위가 이항 연산자보다 높다.

  • 단항 연산자와 대입연산자를 제외한 모든 연산의 진행방향은 왼쪽에서 오른쪽이다.

Java 13 Switch Operator

  • preview 기능이므로 —enable-preview 옵션을 줘야 사용할수 있다.

  • : 대신 → 를 사용할 수 있다.

  • switch가 expression으로 사용될 수 있다.

    • 타입을 지정하고 변수를 할당할수 있게 되었다.
  • yeild 키워드가 추가 되었다.

    • return과 같이 사용가능.

switch (name) { case "KKK" -> System.out.println("이름이 KKK"); case "DDD" -> System.out.println("이름이 DDD"); } String result = switch (name) { case "KKK" -> "nameKKK"; case "DDD" -> "nameDDD"; }; String result = switch (name) { case "KKK" -> "nameKKK"; case "DDD" -> "nameDDD"; default -> { String a = "newname" yield a; } };

출처

https://johngrib.github.io/wiki/jdk13/#switch-expressions-preview

자바의정석

http://blog.kurien.co.kr/495

'백선생님 온라인스터디' 카테고리의 다른 글

6주차 상속  (0) 2021.01.10
4주차 - 제어문  (0) 2021.01.09
연산자  (0) 2020.11.28
스터디 2주차 - 자바 데이터타입, 변수 그리고 배열  (0) 2020.11.21
스터디 1주차 - JVM  (0) 2020.11.15

목표

  • 자바가 제공하는 다양한 연산자를 학습하세요

학습할것

  • 산술 연산자
  • 비트 연산자
  • 관계 연산자
  • 논리 연산자
  • instanceof
  • assignment(=) operator
  • 화살표(->) 연산자
  • 3항 연산자
  • 연산자 우선 순위
  • (optional) Java 13. switch 연산자

산술 연산자

  • 산술연산자는 사칙연산자 ( + , - , * , / ) 4개와 나머지 연산자 ( % ) 로 이루어져 있다.

  • 사칙 연산자

    • 피 연산자가 정수 일 경우 0 으로 나눌수 없다.

    • 피 연산자가 같을 경우 결과는 피연산자와 같고

    • 피 연산자가 다를 경우 ( 정수 + 실수 ) 조합일 때 결과는 실수가 된다.

    • 피 연산자가 다를 경우에는 좀더 범위가 넓은쪽을 결과의 타입으로 쓴다.

    • 연산자 결과의 최소 타입은 int형이다.

      byte a = 1; byte b = 1; byte c = a+b; // 에러발생 provided는 int형 인데 byte에 담으려 했기 때문 byte c = (byte)(a+b); // 명시적 형변환할 경우 에러안남
      • byte+byte로 더해서 byte에 담으려 하면 에러가 난다.
        • 결과는 int로 나오는데 int ( 4byte)보다 더작은 byte에 담으려 했기 때문
        • 이때는 명시적으로 형변환을 시켜줘야 한다.
        • 하지만 큰 타입에서 작은 타입으로 변환해서 데이터를 넣을 경우
        • 값이 작은 타입의 데이터 범위를 넘을 경우 데이터 손실이 일어난다.
    int aa = 1000000; int bb = 1000000; long cc = aa*bb; // result -727379968
    • 같은 타입 피연산자의 연산결과 합이 타입의 허용 값을 넘어서 결과가 나온다면
    • 더 높은값을 담을수 있는 타입에 저장할 때 이 타입의 형태로 저장되는게 아닌 피연산자 타입의 연산결과의 합이 담긴다.
    • 그리고 연산 중 오버플로우가 일어난다면
    • 상위 타입에 저장한다고 해도 이미 오버플로우가 일어나서 오버플로우가 일어나기 전까지의 값만 저장가능하다.
  • 문자열 연산

char a = 'a'; char b = 'b'; char c = a+b; // 결과값은 Ã String a = "a"; String b = "b"; String c = a+b; final char a= 'a'; final char b = 'b'; char ccc = a+b; // 에러 안남

  • char의 문자열 연산은 해당문자의 유니코드 ( 정수 ) 로 바뀌어 저장되므로 정수간의 연산이된다.

  • 문자열 자체가 더해지는 것이 아닌 유니코드가 더해져서 char에 변수에 담는것이다.

  • 재밌게도 스트링은 따로 형변환을 안해도 되고 그자체로 더해진다.

    • 그 이유는 스트링은 리터럴이기 때문이다.
    • 리터럴 끼리의 합은 형변환을 안해도 된다.
      • 문자열 끼리만이 아닌 정수와 실수도 가능하다.
  • 리터럴 연산

    • 리터럴 연산은 컴파일시 컴파일러가 먼저 계산하고 리터럴간의 연산을 먼저 실행시킨다.
    • 그래서 형변환을 안해도 연산이 되는것이다.
    • 만약 리터럴이 아닐경우 도중에 값이 바뀔 위험이 있기에 컴파일러가 미리 연산을 하지 못한다 그래서 형변환이 필요한것이다.
  • 나머지 연산자

    • 왼쪽의 피 연산자를 오른쪽의 피연산자로 나누고 난 나머지 값을 결과로 리턴하는 연산자.
    • 나눗셈처럼 나누는 수 ( 오른쪽 피 연산자) 를 0으로 사용할수 없다.

비트 연산자

  • 피연산자를 비트단위로 논리 연산한다.

  • 피연산자를 이진수로 표현할 경우의 각 자리를 규칙에따라 연산하고 피연산자로 실수는 허용하지 않는다. 정수만 가능

  • 연산 규칙

    • | ( OR 연산자 )
      • 피연산자 중 한쪽의 값이 1이면 1로 값을 리턴한다 그 이외에는 0으로 리턴
    • & ( AND 연산자 )
      • 피연산자 양쪽이 모두 1이어야만 1로 값으로 리턴한다. 그이외에는 0으로 리턴
    • ^ ( XOR 연산자 )
      • 피연산자의 값이 서로 다를때만 1로 값을 리턴한다. 같을때는 0을 리턴한다.
  • 쉬프트 연산자 << >>

    • 피연산자의 각 자리 ( 2진수로 표현했을 때)를
    • 오른쪽 >> 또는 왼쪽 << 으로 이동한다고 해서 쉬프트 연산자 라고 불린다.
    • 예를 들어 " 8 << 2 " 는 왼쪽 피연산자인 10진수의 8의 2진수를 왼쪽으로 2자리 이동한다.
    10진수 8은 2진수로 '00001000' 8 << 2 는 10진수 8의 2진수를 왼쪽으로 2자리 이동시킨다 0 0 0 0 1 0 0 0 에서 왼쪽으로 2자리 이동되므로 가장 앞 2자리는 버려진다. 남은 값은 0 0 1 0 0 0 0 0 (10진수로 32) 빈자리는 0으로 채워진다. System.out.println((8 << 2)); // 결과값은 32
  • 비트전환 연산자 ~

    • 피연산자를 2진수로 표현했을때 0은 1로 , 1은 0으로 바꾼다.
    byte p = 10; System.out.println("~p = " + ~p); // 결과 -11 10은 이진수로 00000000000000000000000000001010이 된다. ~를 사용하여 0과 1이 뒤바뀌면 아래와 같이 -11의 이진수 값이 된다. -11은 이진수로 11111111111111111111111111110101이 된다.

관계 연산자

  • 두 연산자를 비교하는데 사용되는 연산자다.
  • 주로 조건문 과 반복문의 조건식에 사용된다.
  • 결과는 오직 true, false 단 두개뿐이다.

대소비교 연산자

  • 두 연산자의 값의 크기를 비교하는 연산자

  • 참 일 경우 true , 거짓이면 false를 리턴한다.

  • boolean형을 제외한 나머지 자료형에는 사용가능하나 참조형에는 사용할수 없다.

  • 4가지 종류가 존재한다.

      • 좌변이 크면 ture 아니면 false
    • <
      • 좌변이 작으면 true 아니면 false
    • =

      • 좌변이 크거나 같으면 true 아니면 false
    • <=
      • 좌변이 작거나 같으면 true 아니면 false

등가비교 연산자

  • 두 피연산자의 값이 같은지 또는 다른지를 비교하는 연산자

  • 대소비교 연산자와 다르게 기본형 , 참조형 , 모든 자료형에 사용 가능하다.

  • 기본형의 등가비교일 경우 저장되어있는 값이 같은지를 알수 있고

  • 참조형의 등가비교일 경우 저장되어있는 객체의 주소값을 비교한다.

  • 2가지 종류가 존재

    • ==
      • 두 값이 같으면 ture 아니면 false
    • !=
      • 두 값이 다르면 true 아니면 false

문자열의 비교

  • String으로 문자열을 비교할 경우에는 == 대신 equals를 사용 해야 한다.
  • ==로 비교하는 것은 참조주소를 비교한다는 것이기 때문에 만약 문자열이 같더라도
  • 참조주소가 다르면 다른것으로 간주하기 때문이다.
  • equals를 사용하면 문자열을 비교하기 때문에 문자열이 같으면 true를 반환한다.

논리 연산자

  • 2가지 조건으로 결합하여 참과 거짓을 구분한다.
    • && 와 ||

boolean a = true; boolean b = false; (a && a) // true (a || a) // true (a && b) // false (a || b) // true (b && b) // false (b || b) // false

  • 2가지 조건
    • && ( AND 결합 )
      • 피연산자 양쪽 모두 true 이어야 true를 리턴한다.
    • || ( OR 결합 )
      • 피연산자 중 한쪽 만 true면 true를 리턴 한다.

논리 부정 연산자

  • 피연산자가 true면 false로 false면 true로 결과를 바꿔서 리턴한다.

boolean a = true; boolean b = false; !a // false; !b // true;

instance of 연산자

  • 참조변수가 참조하고 있는 인스턴스의 실제 타입을 확인하는 연산자.
  • instanceOf 가 true 란 것은 그 타입일수도 있고 그 타입으로 형변환이 가능하다는 것이다.

void test (Car c) { if (c instanceOf SportsCar) { SportsCar sc = (SportsCar)c; } }

  • 위와 같이 사용할 경우 test 메소드의 Car c의 타입을 정확히 알수가 없다.
  • 진짜 car인지 아니면 car의 자손 클래스인지 정확히 알수가 없다.
  • 그렇기 떄문에 체크해서 사용한다.

assignment(=) operator

  • 대입 연산자

    • 변수와 같은 저장공간에 값 또는 수식의 연산결과를 저장하는데 사용
    • 오른쪽 피연산자의 값을 왼쪽 피연산자에 저장한다.
    • 대입 연산자의 왼쪽 피연산자를 lvalue ( left value ) 라고 하며
    • 오른쪽을 rvalue ( right value ) 라고 한다.
  • 복합 대입연산자

    • 다른 연산자와 결합하여 op= 와 같은 방식으로 사용가능하다.
    i = i+3; 과 같은 코드를 i +=3; 과 같이 사용 가능하다.

화살표 연산자

  • lambda를 표현식을 작성하기 위한 연산자다.

1. Interface k = new Interface() { @Override public void main() { } }; 2. Koy k = () -> { };

  • 위와 같이 인터페이스의 메소드가 1개일 경우 아래와같이 익명함수를 간단하게 람다식으로 변경할수 있다.

3항 연산자

  • 피연산자를 3개를 사용하는 연산자
  • 조건식과 결과 결과 로 이루어져 있으며 결과에 다시 3항연산자가 들어갈수도 있다.

int a = 1; int b = 2; int c = 3; boolean d = a < b ? true : false boolean d = a < b ? a < c ? true : false : false

연산자 우선순위

  • 식에 사용된 연산자가 둘 이상일 경우 연산자 우선순위에 의해 순서가 결정된다.
  • 곱셈과 나눗셈은 덧셈과 뺼셈보다 우선순위가 높다. ( 기초수학 )

x << 2 + 1 data & 0xFF == 0 x < 1 || x > 3 && x < 5

  • << 연산자는 덧셈 연산자보다 우선순위가 낮다.
  • & 연산자는 == 연산자보다 우선순위가 낮다.
  • &와 && 연산자는 |과 || 보다 우선순위가 높다.
  • and 와 or을 같이사용하는 경우에는 괄호를 사용해 우선순위를 명확하게 하는것이 좋다.

x + 3 > y - 2 x > 3 && x - 2 result = x + y * 3

  • 비교연산자는 산술 연산자보다 우선순위가 낮다

  • && 연산자는 비교 연산자보다 순위가 낮다.
  • 대입연산자는 연산자중에서 우선순위가 제일 낮다.

우선순위 결론

  • 산술 > 비교 > 논리 > 대입 의 순위이며

  • 대입은 제일 마지막에 수행된다.

  • 단항 > 이항 > 삼항

  • 단항 연산자의 우선순위가 이항 연산자보다 높다.

  • 단항 연산자와 대입연산자를 제외한 모든 연산의 진행방향은 왼쪽에서 오른쪽이다.

Java 13 Switch Operator

  • preview 기능이므로 —enable-preview 옵션을 줘야 사용할수 있다.

  • : 대신 → 를 사용할 수 있다.

  • switch가 expression으로 사용될 수 있다.

    • 타입을 지정하고 변수를 할당할수 있게 되었다.
  • yeild 키워드가 추가 되었다.

    • return과 같이 사용가능.

switch (name) { case "KKK" -> System.out.println("이름이 KKK"); case "DDD" -> System.out.println("이름이 DDD"); } String result = switch (name) { case "KKK" -> "nameKKK"; case "DDD" -> "nameDDD"; }; String result = switch (name) { case "KKK" -> "nameKKK"; case "DDD" -> "nameDDD"; default -> { String a = "newname" yield a; } };

출처

https://johngrib.github.io/wiki/jdk13/#switch-expressions-preview

자바의정석

http://blog.kurien.co.kr/495

'백선생님 온라인스터디' 카테고리의 다른 글

6주차 상속  (0) 2021.01.10
4주차 - 제어문  (0) 2021.01.09
3주차 연산자  (0) 2021.01.07
스터디 2주차 - 자바 데이터타입, 변수 그리고 배열  (0) 2020.11.21
스터디 1주차 - JVM  (0) 2020.11.15

www.notion.so/77b364c091ea4d81a74042331b26dc1e

 

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

목표

www.notion.so

 

목표

  • 자바의 프리미티브 타입, 변수 그리고 배열을 사용하는 방법을 익힙니다.

학습할것

  • 프리미티브 타입 종류와 값의 범위 그리고 기본 값
  • 프리미티브 타입과 레퍼런스 타입
  • 리터럴
  • 변수 선언 및 초기화하는 방법
  • 변수의 스코프와 라이프타임
  • 타입 변환, 캐스팅 그리고 타입 프로모션
  • 1차 및 2차 배열 선언하기
  • 타입 추론, var

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

  • 프리미티브 타입의 종류
    • 자바에는 8가지의 타입이 있으며 논리형, 문자형, 정수형, 실수형으로 나뉘어져있다.
      1. 논리형

        • boolean
          • true와 false중 하나를 값으로 가진다.
          • 나머지 타입들과 연산이 불가능함.
          • 크기는 1byte
          • 값의 범위는 false, true
          • 기본값은 false
      2. 문자형

        • char
          • 문자를 저장한다.
          • 변수에 하나의 문자만 저장가능
          • 다만 내부적으로 유니코드 ( 정수 ) 로 저장하기 때문에 정수형과 별반 다르지 않다.
          • 그렇기에 정수형 또는 실수형과 연산이 가능하다.
          • 크기는 2byte
          • 값의 범위는 '\u0000' ~ '\uffff'
          • 기본값은 \'u0000'
      3. 정수형

        • byte, short, int, long
          • 정수를 저장함
          • int를 주로 사용하며 ( 기본 자료형 )
            • 크기는 4byte
            • 값의 범위는 -2,147,483,648 ~ 2,147,483,647
            • 기본값은 0
          • byte는 이진데이터를 사용할때 쓰고
            • 크기는 1byte
            • 값의 범위는 -128 ~ 127
            • 기본값은 0
          • short는 C언어와의 호환을 위해 사용
            • 크기는 2byte
            • 값의 범위는 -32,768 ~ 32767
            • 기본값은 0
          • long은 int 이상의 범위가 필요할때 사용
            • 크기는 8byte
            • 값의 범위는 -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807
            • 기본값은 0L
      4. 실수형

        • 실수를 저장하는데 사용 주로 double ( 기본 자료형 ) 을 사용한다.
          • double
            • 크기는 double은 8byte 다.
            • 값의 범위는 4.9E-324 ~ 1.8E308
            • 기본값은 0.0
          • float
            • 크기는 float은 4byte
            • 값의 범위는 1.4E-45 ~ 3.4E38
            • 기본값은 0.0F

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

  • 프리미티브 타입
    • 실제 값을 저장한다.
    • 프리미티브 타입도 객체로 사용할때가 있다.
      • Boxing을 통해 프리미티브 타입을 감싼다고해서 Wrapper Class 라고 불린다.
        • 프리미티브 타입과 달리 주소를 값으로 가지고 있기 때문에
        • Null을 컨트롤 할수 있다.
  • 레퍼런스 타입
    • 값이 저장되어 있는 주소를 값으로 저장한다.
    • 위에서 본 8개의 프리미티브 타입을 제외한 나머지 타입

리터럴

  • 변수와 상수는 값을 저장할수 있는 공간을 의미

  • 하지만 상수는 변경이 불가능하다.

  • 상수는 변경이 불가능하므로 그자체로 값이라고 볼수 있다.

  • 그래서 상수의 다른이름은 리터럴

  • 리터럴은 값 그자체를 일컫기 때문이다.

  • 보통 String과 같은 불변 클래스들은 값의 변경이 가능하다.

  • 하지만 불변클래스는 값이 변할수 없는 클래스인데 어떻게 가능한 것일까 ?

    • 불변 클래스는 값이 불변이기 때문에 변경할수가 없다.
    • 그래서 새로운 스택을 만들어서 그곳에 새로 변경된 값을 저장한후
    • 불변클래스는 담고있는 주소의 값을 새로만든 스택의 주소로 바꾼다.
    • 이렇게해서 값을 변경시킨다.

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

  • 변수 선언

    • 변수의 타입과 이름을 적는다.
    • 예) int count; // int 는 변수타입 count는 변수의 이름
    • 변수타입은 변수에 저장될 값이 어떤 타입인지 정하는 것이고
    • 변수이름은 변수에 붙인 이름이다.
  • 변수 초기화

    • 예) int count = 10; // int타입의 변수를 count란 이름으로 명명하고 10으로 초기화

    • 보통 선언과 초기화를 동시에 한다.

    • 생략하는 경우도 있지만 사용하기 전에 적절한 값으로 초기화 하는것이 좋다.

    • 명시적 초기화

      • 위와 같은 설명이 바로 명시적 초기화다.
    • 초기화 블럭

      • statc 초기화 블럭이나 인스턴스 초기화 블럭에서 초기화를 하면 된다.
      • 생성자보다 인스턴스 초기화 블럭이 먼저 수행된다.
    • 생성자 초기화

      • 변수를 선언만 해놓고 초기화는 하지 않고 생성자에서 초기화 하는 방법.

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

  • 클래스 변수, 인스턴스 변수, 지역 변수 총 3가지가 있다.
    1. 클래스 변수

      • 선언 위치는 클래스 영역
      • 생성시기는 클래스가 메모리에 올라갈 때
      • 타입 앞에 static이 붙는다.
      • 클래스는 독립적인 저장공간을 갖지 않으므로 모든 인스턴스는 같은 값을 가진다.
    2. 인스턴스 변수

      • 선언 위치는 클래스 영역
      • 생성시기는 인스턴스가 생성되었을 때
      • 클래스 변수와 다르게 static이 붙지는 않는다.
      • 인스턴스는 독립적이므로 항상 다른값을 가질수 있다.
    3. 지역 변수

      • 선언 위치는 클래스 영역이 아닌 ( 메소드,생성자,초기화 블랙 내부 ) 이다.
      • 생성시기는 변수 선언문이 수행되었을 때
      • 인스턴스 변수와 마찬가지로 static이 붙지 않는다.
      • 메소드 블럭을 벗어나면 소멸한다.

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

  • 타입 변환

    • 변수 또는 상수의 타입을 다른 타입으로 변환하는 것
  • 캐스팅

    double d = 99.9; int count = (int)d;
    • 캐스팅은 이렇게 명시적으로 변경해준다.
  • 타입 프로모션

    • 조건이 맞으면 컴파일러가 자동으로 형변환을 시켜준다.
    • 조건
      • 그 값이 형변환할 타입의 값을 초과하지 않는 것
      • 그리고 서로 연산이 가능한 타입이어야 한다는 것이다.
      • 프리미티브타입과 레퍼런스타입은 서로간에 타입 변환이 안된다.
      • 값의 범위가 작은 타입에서 큰 타입으로 변경할때도 가능

1차 및 2차배열 선언하기

  • 1차 배열 선언

    • 타입[] 변수이름; // 선언
    • 변수이름 = new 타입[길이]; // 생성
    int[] count; count = new int[10]; // 또는 int[] count = {1,2,3,4,5};
    • 선언만 했을경우 아직 메모리에 저장되지 않는다 왜냐면 길이가 정해지지 않았기 때문이다.
    • new에 의해 생성되거나 아예 선언과 동시에 생성할 경우에 메모리에 저장될 공간이 생성된다.
    • 그리고 각 값들은 int의 기본값인 0으로 초기화되고 ( new로 생성까지만 했을 경우 )
    • 그 이후나 값을 넣어주거나 선언과 동시에 값을 넣을 경우에는 배열에 그 값이 담긴 메모리 주소가 저장된다.
    • 배열의 길이에는 0도 포함된다.
  • 2차 배열 선언

    • 타입[][] 변수이름;
    //선언 방식은 3가지 int[][] count; //또는 int count[][]; // 또는 int[] count[]; //할당 방식은 1차배열과 비슷함 int[][] count; count = new int[10][10]; //또는 int[][] count = {{1,2},{2,3},{3,4},{1,4}}
    • 2차배열은 배열에 각각 배열의 주소가 담긴다.

타입추론, var

  • 타입 추론

    • 코드 작성당시 정해지지 않은 타입을 컴파일러가 유추하는 것
    • java 9버전 이하에서는 generic과 lambda를 사용할때 쓰이고
    • java 10버전부터 var이라는 local variable한 키워드가 추가되었다.
    • 이러한 타입추론 덕분에 제네릭타입에 타입을 명시하지 않아도 된다.
  • var

    • 지역변수로서만 사용가능하다.
    • 선언과 동시에 초기화가 필수
    • 다이아몬드 연산자와 같이 사용할수 없다
    • java 10버전 이상부터 사용가능하며 그 이하버전은 lombok 설치시 사용가능.
    • 예 )
    var message = "ganadaramabasa"; ~~var message = new ArrayList<>();~~

참조

'백선생님 온라인스터디' 카테고리의 다른 글

6주차 상속  (0) 2021.01.10
4주차 - 제어문  (0) 2021.01.09
3주차 연산자  (0) 2021.01.07
연산자  (0) 2020.11.28
스터디 1주차 - JVM  (0) 2020.11.15

JVM 이란 ?

  • 어느 OS 어느 환경에서 든지 java를 실행시킬수 있게 해줌.
    • bytecode가 JVM위에서 실행되기 때문이다.
  • java bytecode를 os가 읽을수 있게 바꿔줌 ( 이 작업은 인터프리터와 JIT컴파일러를 사용)
    • 특정 OS별로 네이티브 언어를 바꿔줘야 하기때문에 특정 OS에 종속적이다.

컴파일 하는 방법.

  • javac.exe 를 사용하여 컴파일 한다.

실행하는 방법

  • java.exe 를 사용하여 클래스파일을 실행시킨다.

바이트코드란 무엇인가 ?

  • jvm이 이해할수 있는 상태인 코드
  • 이 바이트 코드는 인터프리터와 JIT 컴파일러가 읽을 수 있다.

JIT 컴파일러란 무엇이며 어떻게 동작하는지 ?

  • 중복된 바이트코드를 네이티브 언어로 모두 바꿔주는 컴파일러

  • 인터프리터가 읽으면서 컴파일시키고 실행하다가 중복되는 부분을 발견하면

  • JIT컴파일러로 보낸다 그럼 JIT 컴파일러가 중복된 바이트코드를 모두 네이티브 언어로 바꿔준다.

JVM 구성요소

  • 클래스 로더 시스템 , 메모리 , 실행엔진 , 네이티브 메소드 인터페이스, 네이티브메소드 라이브러리로 나뉘어져 있다.
  1. 클래스로더 시스템

    • 컴파일된 class 파일들을 읽어서 메모리에 적절히 배치시킨다.
    1. 로딩

      • 클래스에서 바이트코드를 읽어오는 과정

      • 클래스 로더가 class파일을 읽고 그 내용에 따라 바이너리 데이터를 만들고 메소드 영역에 저장

      • 이떄 저장하는 데이터는

        • FQCN ( 패키지, 풀 패키지 경로와 클래스 이름 )
        • 클래스 , 인터페이스, 이늄 ( 클래스가 어떤 타입인지 저장 )
        • 메소드와 변수
      • 로딩이 끝나면 해당 클래스 타입의 class 객체를 생성하여 힙 영역에 저장.

      • 처음에 bootstrap classloader에서 찾아서 없으면 자식인 platform classloader가 찾고

      • 또 없으면 application classloader가 찾아서 없으면 class not found 익센션을 호출

      • bootstrap classloader는 네이티브 코드로 구현되어 있어 JVM마다 구현이 다 다르다.

    2. 링크

      • 레퍼런스를 연결하는 과정
      • verify , prepare, revolve 3단계로 나뉘어져 있다.
        • verify
          • .class파일이 유효한지 확인
            • 파일이 유효하지 않으면 JVM에러로 종료됨.
        • prepare
          • static변수와 기본값에 필요한 메모리를 준비하는 과정
        • Resolve ( Optional )
          • 심볼릭 메모리 레퍼런스를 메소드 영역에 있는 실제 레퍼런스로 교체하는 과정.
          • 심볼릭 메모리 레퍼런스란 ?
            • 다른 객체를 참조할때 논리적으로만 연결시켜놓고 실제론 연결되어 있지 않음.
    3. 초기화

      • statc 값들 초기화 및 변수에 할당
  2. 메모리

    1. 스택
      • JVM 쓰레드가 생길때 해다 쓰레드를 위한 스택도 같이 생긴다.
      • 이때 프레임이 스택에 들어가며 이 프레임은 메소드가 호출될때마다 만들어지며
      • 메소드의 상태 정보를 저장한다.
      • 쓰레드를 종료하면 런타임 스택도 사라진다.
    2. PC
      • 쓰레드마다 쓰레드 내 현재 실행할 스택 프레임을 가리키는 포인터가 생성된다.
    3. 네이티브 메소드 스택
      • 쓰레드 마다 생기는 스택인데 native method가 호출될때 쌓인다.
      • JNI를 사용하는 메소드는 여기에 스택이 쌓인다.
      • 객체를 저장, 공유
    4. 메소드
      • 클래스 수준의 정보를 저장, 공유
      • (클래스 이름 , 풀패키지 경로 , 부모 클래스 이름 , 메소드 , 변수)
      • 다른 영역에서 참조 가능
  3. 실행 엔진

    1. 인터프리터
      • 바이트코드를 한줄마다 읽음과 동시에 네이티브 코드로 변경시키면서 실행시킴.
    2. JIT 컴파일러
      • 인터프리터가 반복되는 코드를 찾으면 JIT 컴파일러로 보내서 JIT 컴파일러가 반복되는 코드를 모두 네이티브 코드로 바꿔둔다.
      • 그러면 인터프리터는 네이티브 코드를 바로 실행시킨다.
    3. GC
      • 더이상 참조되지 않은 객체를 메모리에서 해제시킨다.
  4. 네이티브 메소드 인터페이스

    • 자바에서 C나 C++된 함수를 사용할수 있는 방법을 제공하는 인터페이스
  5. 네이티브 메소드 라이브러리

    • C , C++로 작성된 라이브러리

JDK와 JRE의 차이

  • JRE는 단순히 자바를 실행할수 있게만 해줌

    • JVM과 라이브러리들이 포함.
    • 자바 런타임 환경에서 사용되는 프로퍼티 세팅이나 리소스 파일을 가지고 있다.
  • JDK는 JRE와 개발툴들이 같이 포함되어 있음.

출처

'백선생님 온라인스터디' 카테고리의 다른 글

6주차 상속  (0) 2021.01.10
4주차 - 제어문  (0) 2021.01.09
3주차 연산자  (0) 2021.01.07
연산자  (0) 2020.11.28
스터디 2주차 - 자바 데이터타입, 변수 그리고 배열  (0) 2020.11.21

+ Recent posts