목표

자바의 Input과 Ontput에 대해 학습하세요.

학습할 것 (필수)

  • 스트림 (Stream) / 버퍼 (Buffer) / 채널 (Channel) 기반의 I/O
  • InputStream과 OutputStream
  • Byte와 Character 스트림
  • 표준 스트림 (System.in, System.out, System.err)
  • 파일 읽고 쓰기

스트림 (Stream) / 버퍼 (Buffer) / 채널 (Channel) 기반의 I/O

Stream

스트림이란 데이터를 운반하는데 사용되는 연결통로

스트림은 단방향 통신만 가능하기 때문에 하나의 스트림으로 입력과 출력을 동시에 처리할 수 없다.

둘다 하려면 input stream과 output stream 2개의 스트림이 필요하다.

스트림은 먼저 보낸 데이터를 먼저 받게 되어 있으며 중간에 건너뜀 없이 연속적으로 데이터를 주고 받는다.

큐와 같은 FIFO 구조로 되어있다고 생각하면 이해하기 쉽다.

Byte기반의 스트림

  • FileInputStream , FileOutputStream

    • 파일
  • ByteArrayInputStream , ByteArrayOutputStream

    • 메모리 ( Byte 배열 )
  • PipedInputStream , PipedOutputStream

    • 프로세스 ( 프로세스간 통신 )
  • AudioInputStream , AudioOutputStream

    • 오디오장치
  • 어떤 대상에 대해서 작업을 할것인지에 따라 해당 스트림을 선택해서 사용하면 된다.

입출력스트림의 부모 inputStream, outputStream

  • InputStream

    • abstraact int read()
    • int read(byte[] b)
    • int read(byte[] b, int off, int len)
  • OutputStream

    • abstract void write(int b)
    • void write(byte[] b)
    • void write(byte[] b, int off, int len)

Buffer

CPU와 I/O의 속도차이에서 나오는 비효율성을 줄이기 위해 등장

데이터를 전송하는 상호간의 장치에서 고속의 장치 ( java api 호출 ) 와 저속의 장치 ( OS레벨에서 시스템콜 ) 간의 속도차이로 인해 저속의 장치가 작업을 추리하는 동안 고속의 장치가 기다려야 하는 현상을 줄여준다.

JAVA I/O

스트림 가반의 I/O이며 기본적으로 buffer를 사용하지 않으며 blocking 상태이다.

JAVA NIO

채널 기반의 I/O , 기본적으로 buffer를 사용하며 non-blocking을 지원한다.

출처: https://velog.io/@jaden_94/13주차-항해일지-IO

InputStream 과 OutputStream

InputStream try (FileInputStream fis = new FileInputStream(new File(fileName))) { int content; // 돌면서 byte를 읽고 file의 끝에 도달하면 -1을 return한다. while ((content = fis.read()) != -1) { System.out.println((char)content); } } catch (IOException e) { e.printStackTrace(); } OutputStream try (FileOutputStream outputStream = new FileOutputStream(file, false)) { int read; byte[] bytes = new byte[DEFAULT_BUFFER_SIZE]; while ((read = inputStream.read(bytes)) != -1) { outputStream.write(bytes, 0, read); } }

출처 https://mkyong.com/java/how-to-convert-inputstream-to-file-in-java/

  • NIO가 아닌 IO를 사용한 stream이여서 buffer를 자동으로 사용하지 않아 느리다.

Byte와 Character 스트림

  • inputStream과 outputStream은 대표적인 byteStream이다.

  • 1 byte 단위로 데이터를 입출력한다.

  • characterStream은 2바이트단위로 데이터를 전송한다.

  • 유니코드는 기본단위가 2바이트로 문자를 입출력할때 CharacterStream을 쓰는것이 적절하다.

  • characterStream은 클래스명에 Reader, Writer이 들어가 있다.

BufferReader // 리소스 폴더로부터 파일을 불러온다. InputStream is = InputStreamToReaderExample.class .getClassLoader() .getResourceAsStream("file/abc.txt"); // BufferedReader -> InputStreamReader -> InputStream // try-with-resources, auto close String line; try (BufferedReader br = new BufferedReader( new InputStreamReader(is, StandardCharsets.UTF_8))) { // read line by line while ((line = br.readLine()) != null) { System.out.println(line); } } BufferedWriter try (FileWriter writer = new FileWriter("app.log"); BufferedWriter bw = new BufferedWriter(writer)) { bw.write(content); } catch (IOException e) { System.err.format("IOException: %s%n", e); }

출처 https://mkyong.com/java/how-to-write-to-file-in-java-bufferedwriter-example/

표준 스트림 (System.in, System.out, System.err)

표준 스트림

  • 콘솔을 통해 데이터입력과 콘솔로의 데이터 출력을 의미

  • 자바에서는 표준 입출력을 위해 3가지 입출력 스트림 in,out,err를 제공한다.

  • 자바앱의 실행과 동시에 자동으로 생성되기 때문에 별도의 스트림없이 사용이 가능하다.

  • System.in

    • 콘솔로 부터 데이터를 입력받는데 사용
  • System.out

    • 콘솔로 데이터를 출력하는데 사용
  • System.err

    • 콘솔로 데이터를 출력하는데 사용

파일 읽고 쓰기

BufferReader와 BufferWriter의 예제 참고.

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

12주차 애노테이션  (0) 2021.02.28
10주차 멀티스레드 프로그래밍  (0) 2021.01.31
11주차 Enum  (0) 2021.01.30
9주차 - 예외 처리  (0) 2021.01.19
8주차 - 인터페이스  (0) 2021.01.16

목표

자바의 애노테이션에 대해 학습하세요.

학습할 것 (필수)

애노테이션 정의하는 방법

public @interface WhiteTest { int count(); }

  • @Override는 애노테이션 이고 Override는 애노테이션의 타입.

애노테이션의 엘리멘트

@interface WhiteTest { TestType testType(); DateTime testDate(); } @interface DateTime { String yymmdd(); }

  • 자신이 아닌 다른 애노테이션을 엘리먼트로 가질수 있다.
  • Enum 역시 가질수 있다.

@WhiteTest ( testType = TestType.First, testDate = @DateTime(yymmdd = "160101") )

  • 애노테이션의 엘리먼트들은 반환값이 있고 매개변수는 없는 추상메서드의 형태를 가진다.

  • 상속을 통해 구현하지 않아도 된다.

  • 다만 애노테이션을 적용할 때 이 요소들의 값을 다 지정해줘야 한다.

  • 요소의 이름도 같이 적어주므로 순서는 상관없다.

  • 애노테이션의 각 엘리먼트들은 기본값을 가질수 있다.

  • 배열타입의 경우 {} 를 이용해 여러개의 값을 지정할수 있다.

  • 기본값 적용시 {}로 적용할수 있다.

java.lang.annotation.Annotation

  • 모든 애노테이션의 조상은 Annotation이다.
  • 다만 애노테이션은 상속이 허용되지 않으므로 명시적으로 선언할수는 없다.

Marker Annotation

  • 값을 지정할 필요가 없는 경우 애노테이션의 필드가 하나도 없는 경우가 있다.
  • Serializable이나 Cloneable인터페이스처럼 요소가 하나도 정의되지 않은 애노테이션을
  • 마커 애노테이션이라고 한다.

애노테이션 요소의 규칙

  1. 요소의 타입은 기본형, String, enum, 애노테이션, Classs만 허용된다.
  2. () 안에 매개변수를 선언할 수 없다.
  3. 예외를 선언할 수 없다.
  4. 요소를 타입 매개변수로 정의할 수 없다.

@interface AnnoTest { int id = 100; // 상수는 선언가능 String major(int i, int j); // 에러 String minor() throws Exception; // 에러 ArrayList<T> list(); // 에러 }

@Retention

애노테이션이 유지되는 범위를 설정한다.

@Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.CLASS)

  • 3가지 범위가 존재
    • SOURCE
      • 소스파일에만 존재하고 클래스파일에는 존재하지 않음.
    • CLASS
      • 클래스 파일에 존재하며 실행시 사용불가능함 기본값
    • RUNTIME
      • 클래스 파일에 존재하며 실행시에 사용가능.

Source

@Override , @SuppressWarning 처럼 컴파일러가 사용하는 애노테이션은

유지정책이 source이다. 컴파일러가 컴파일시 해당 애노테이션의 메모리는 버림.

Runtime

실행시 리플렉션을 통해 클래스 파일에 저장된 애노테이션 정보를 읽어 처리가능

@FuntionalInterface는 @Override처럼 컴파일러가 체크해주는 애노테이션이지만

실행시에도 사용되므로 유지정책이 RUNTIME으로 되어있다.

CLASS 정책과 다르게 jvm이 로딩될때 애노테이션 정보를 같이 들고있어 애노테이션 정보를 얻을수 있다.

Class

컴파일러가 애노테이션의 정보를 클래스파일에 저장할수 있게는 하지만 클래스파일이 JVM에 로딩될때는 애노테이션의 정보가 무시되어 실행시에 애노테이션 정보를 얻을수가 없다.

CLASS가 기본정책이지만 잘 사용되지 않는 이유다.

@Target

애노테이션이 적용가능한 대상을 지정한다.

@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.CONSTRUCTOR, ElementType.LOCAL_VARIABLE}) @Retention(RetentionPolicy.SOURCE) public @interface SuppressWarnings { String[] value(); }

  • 대상타입의 종류

@Target({ ElementType.PACKAGE, // 패키지 선언시 ElementType.TYPE, // 타입 선언시 ElementType.CONSTRUCTOR, // 생성자 선언시 ElementType.FIELD, // 멤버 변수 선언시 ElementType.METHOD, // 메소드 선언시 ElementType.ANNOTATION_TYPE, // 어노테이션 타입 선언시 ElementType.LOCAL_VARIABLE, // 지역 변수 선언시 ElementType.PARAMETER, // 매개 변수 선언시 ElementType.TYPE_PARAMETER, // 매개 변수 타입 선언시 ElementType.TYPE_USE // 타입 사용시 })

출처 : https://jdm.kr/blog/216

@Documented

애노테이션의 정보가 javadoc로 작성한 문서에 포함되도록 한다.

자바에서 제공하는 기본 애노테이션중에 @Override와 @SuppressWarnings를 제외하면 다 붙어 있다.

@Documented @Retention(RetentionPolicy.RUNTIME) @Target({ANNOTATION_TYPE, CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE, TYPE_PARAMETER, TYPE_USE}) public @interface WhiteTest { int id = 100; }

@Inherited

애노테이션이 자손 클래스에 상속되도록 한다.

@Inherited가 붙으 ㄴ애노테이션을 조상클래스에 붙이면 자손클래스도 이 애노텡션이 붙은것과 같이 인식된다.

@Repeatable

보통 하나의 대상에 하나의 애노테이션을 붙이는데 @Repeatable 애노테이션이 붙은 애노테이션은 여러번 붙일수 있다.

애노테이션 프로세서

리플렉션에서 사용하는 애노테이션이 아닌 컴파일시점에 수행된다.

컴파일시점에 hook하여 용자가 정의한 어노테이션에 대한 소스코드를 분석하고 처리한다.

애노테이션 프로세서를 사용하여 코드를 생성해주는 lombok같은것이 존재함.

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

13주차 I/O  (0) 2021.03.01
10주차 멀티스레드 프로그래밍  (0) 2021.01.31
11주차 Enum  (0) 2021.01.30
9주차 - 예외 처리  (0) 2021.01.19
8주차 - 인터페이스  (0) 2021.01.16

학습할 것 (필수)

  • Thread 클래스와 Runnable 인터페이스
  • 쓰레드의 상태
  • 쓰레드의 우선순위
  • Main 쓰레드
  • 동기화
  • 데드락

Thread 클래스와 Runnable 인터페이스

프로세스와 쓰레드

프로세스

  • 프로그램을 실행하면 OS로 부터 실행에 필요한 메모리를 할당받아 프로세스가 된다.
  • 이 프로그램을 실행하는데 필요한 데이터와 메모리등의 자원 그리고 쓰레드로 구성되어 있다.
  • 모든 프로세스에는 한개이상의 쓰레드가 존재한다.
  • 둘 이상의 쓰레드를 가진 프로세스를 멀티쓰레드 프로세스라고 칭함.

쓰레드

  • 프로세스 내에서 작업을 수행하는 역할

쓰레드를 구현하는 방법 중 두가지

Thread 클래스를 상속

class TestThread1 extends Thread { public void run() { //내용 } } thread 클래스를 상속받아 run을 오버라이딩하여 구현함.

Runnable 인터페이스를 구현

class TestThread2 implements Runnable { public void run() { //내용 } } Runnable 인터페이스의 run을 구현함.

두가지 방식의 차이점

  1. 인스턴스의 생성법이 다르다.

    TestThread1 thread = new TestThread1(); // Thread 클래스를 상속받았을 경우 Runnable r = new TestThread2(); Thread t = new Thread(r); // Runnable 인터페이스를 구현한 경우
  2. 호출이 다르다.

    • Thread클래스를 상속받으면 서브클래스에서 슈퍼클래스의 메소드를 직접 호출가능
    • Runnable을 구현할 경우 static 메소드인 currentThread()를 호출하여 쓰레드의 참조를 가져와야 호출이 가능함.

쓰레드의 상태

  1. NEW
    • 아직 thread가 생성은 됬지만 실행되지 않은 상태.
  2. RUNNABLE
    • jvm이 thread를 실행중인 상태
    • 실행중이므로 CPU에서 자원을 할당받은 상태이고
    • 운영체제의 자원 분배로 인해 WAITING 상태가 될수 있다.
  3. BLOCKED
    • Monitor를 획득하기 위해 다른 스레드가 락을 해제하기를 기다리는 상태
    • Java thread 동기화 모델은 모니터란 개념을 적용 중이다.
    • 모니터는 하나의 데이터 ( 객체 ) 마다 하나의 모니터를 결합 할수 있으며
    • 그것이 결합된 데이터 가 동시에 두개 이상의 스레드에 의해 접근할수 없도록 막는 락을 제공함
    • 결국 BLOCKED 상태는 다른사용자가 사용하고 있는 데이터를 사용하기위해 기다리고 있는 상태
  4. WAITING
    • 다른 스레드가 특정 작업을 수행할떄까지 무기한으로 대기중인 상태
    • wait() , join() , park() 메소드 등을 이용해 대기중임.
  5. TIMED_WATING
    • 다른 스레드가 지정된 대기 시간까지 작업을 수행하기를 기다리는 상태
    • sleep() , wait(), join(), park() 메소드등을 사용해 대기중인 상태
    • WAITING 상태와의 차이점은 메서드의 인수로 최대 대기 시간을 명시할 수 있어 외부적인 변화뿐만 아니라 시간에 의해서도 WAITING 상태가 해제될 수 있다는 것
    • 출처 d2.naver
  6. TERMINATED
    • 스레드가 종료된 상태

쓰레드의 우선순위

  • 쓰레드는 우선순위라는 속성 ( 멤버변수) 를 가지고 있는데 이 값에 따라 쓰레드가 얻는 실행시간이 달라진다.
  • 쓰레드가 수행하는 작업의 중요도에 따라 우선순위를 서로 다르게 지정하여 특정 쓰레드가 더 많은 작업시간을 갖게 할수 있다.
  • setPriority 메소드로 우선순위를 지정할수 있음.
  • getPriority로 우선순위를 반환함.

메인 쓰레드

  • main 메소드에서 작업을 수행하는 것
  • main 메소드를 실행시 jvm에서 돌아가게 되며 이때 jvm은 프로세스가 되어 운영체제로 부터 자원을 할당받고 쓰레드가 실행되는데 이떄 main 메소드에서 실행하는게 main 쓰레드다.

데몬 쓰레드

  • 다른 일반 쓰레드의 작업을 돕는 보조적인 역할의 쓰레드
  • 일반 쓰레드가 모두 죵로되면 같이 종료된다.
  • setDaemon 메소드로 유저 쓰레드가 될지 데몬 쓰레드가 될지 정할수 있다.

동기화

  • 멀티쓰레드를 사용하는 경우 하나의 데이터를 사용하려고 할때 다른 쓰레드가 접근하지 못하게 막는 것.

public synchronized void test() { } // 메소드 전체를 임계 영역으로 지정 public void test() { synchronized() { } } // 특정 지역을 임계 영역으로 지정

주의점

  • 임계영역은 작을수록 좋음.
    • 임계영역이 클수록 어떤 오류가 발생할지 모르기 때문.
  • 임계영역은 최소한으로 줄여야함
    • 임계영역이 여러곳일 경우 A 쓰레드에서는 통과가 안될 로직이 B 쓰레드가 작동함으로써 통과되는 버그가 일어날수도 있기 떄문.

데드락

  • 두개 이상의 스레드에서 작업을 완료하기 위해 상대의 작업이 끝나기를 기다리는 상황

  • 쓰레드 A가 작업을 계속 하려면 쓰레드 B의 작업이 끝나기를 기다려야 하고

  • 쓰레드 B가 작업을 계속 하라면 쓰레드 A의 작업이 끝나기를 기다려야 하는 상황.

  • 어느 한쪽이 자신의 락을 해제하기 전까지는 데드락 상태는 해제되지 않는다.

참조

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

13주차 I/O  (0) 2021.03.01
12주차 애노테이션  (0) 2021.02.28
11주차 Enum  (0) 2021.01.30
9주차 - 예외 처리  (0) 2021.01.19
8주차 - 인터페이스  (0) 2021.01.16

목표

자바의 열거형에 대해 학습하세요.

학습할 것 (필수)

  • enum 정의하는 방법
  • enum이 제공하는 메소드 (values()와 valueOf())
  • java.lang.Enum
  • EnumSet

Enum 정의하는 방법

enum Myenum { FIRST, SECOND, THIRD }

멤버 추가하는 방법

enum Myenum { FIRST(1), SECOND(2), THIRD(3); private finla int value; Myenum(int value) { this.value = value; } }

  • 멤버 추가시 지정된 값을 저장할수 있는 인스턴스 변수와 생성자를 추가해줘야 한다.

추상메소드 추가하는 방법

enum Myenum { FIRST(1) { int add10(int value) { return value+10 } }, SECOND(2){ int add10(int value) { return value+10 } }, THIRD(3){ int add10(int value) { return value+10 } }; private finla int value; Myenum(int value) { this.value = value; } abstract int add10(int value); protected final int MY_VALUE; }

Enum이 제공하는 메소드 (values()와 valueOf())

  • values()
    • 이 메소드는 해당 enum의 모든 상수를 배열 형태로 반환한다.
  • valueOf()
    • 이 메소드는 enumType과 String을 매개변수로 받으며
    • String과 일치하는 enum의 상수를 반환한다.

java.lang.enum

  • 모든 열거형의 조상
  • values() 메소드는 모든 열거형이 가지고 있는 것으로 컴파일러가 자동으로 추가해 준다.
  • valueOf 역시 컴파일러가 자동으로 추가해준다.

그 외 enum class에 정의된 메소드들

  • Class<E> getDeclaringClass()
    • 열거형의 Class 객체를 반환
  • String name()
    • 열거형 상수의 이름을 문자열로 반환
  • int ordinal()
    • 열거형 상수가 정의된 순서를 반환 ( 0부터 시작)
  • T valueOf(Class<T> enumType, String name)
    • 지정된 열거형에서 name과 일치하는 열거형 상수를 반환한다.

EnumSet

  • EnumSet은 enum 클래스와 함께 작동하는 특수 Set 컬렉션입니다.
  • Set 인터페이스를 구현하고 AbstractSet에서 확장됩니다.

 

이미지 출처 : https://www.baeldung.com/java-enumset

  • EnumSet은 instance를 만드는 메소드를 제외하고는 다른 Set처럼 작동합니다.

EnumSet.allOf(Color.class); //Color 열거형의 모든 요소를 포함 EnumSet.noneOf(Color.class); //빈 Color 열거형 컬렉션

EnumSet의 고려사항

  1. 열거형 값만 포함 가능하다.
  2. Null을 추가할수 없다.
  3. Thread-safe 하지 않다.
  4. 열거형에 선언된 순서에 맞게 저장됩니다.
  5. EnumSet의 iterator은 ConcurrentModificationException예외를 던지지 않습니다.

출처

https://www.baeldung.com/java-enumset

자바의정석

https://docs.oracle.com/javase/8/docs/api/java/util/EnumSet.html

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

12주차 애노테이션  (0) 2021.02.28
10주차 멀티스레드 프로그래밍  (0) 2021.01.31
9주차 - 예외 처리  (0) 2021.01.19
8주차 - 인터페이스  (0) 2021.01.16
7주차 - 패키지  (0) 2021.01.12

목표

자바의 예외 처리에 대해 학습하세요.

학습할 것 (필수)

  • 자바에서 예외 처리 방법 (try, catch, throw, throws, finally)
  • 자바가 제공하는 예외 계층 구조
  • Exception과 Error의 차이는?
  • RuntimeException과 RE가 아닌 것의 차이는?
  • 커스텀한 예외 만드는 방법

java에서 예외를 처리하는 방법.

try { 로직 } catch (Exception e) { 로직을 돌다 오류 발생시 이 scope로 옴 } finally { 마지막 작업 } try catch구문을 생략하고 메소드 옆에 throws exception 을 붙이면 생략 가능함. throw new Exception으로 새로운 익셉션을 로직에서 호출할수 있음. catch (RuntimeException | IoException e) { } 이런식으로 멀티캐치를 사용할수 있다. 다만 주의할점은 사용하는 익셉션들이 서로 상속관계에 있으면 안된다는 것이다. try with resources try (SomeResource resource = getResource()) { // 로직 } catch (Exception e) { } try에 객체를 전달하면 try 코드 블록이 끝나면 자동으로 종료해줌

Java가 제공하는 예외 계층 구조

최상위에 Exception 이 존재하고

그 아래에 subclass 로는

AclNotFoundException, ActivationException, AlreadyBoundException, ApplicationException, AWTException, BackingStoreException, BadAttributeValueExpException, BadBinaryOpValueExpException, BadLocationException, BadStringOperationException, BrokenBarrierException, CertificateException, CloneNotSupportedException, DataFormatException, DatatypeConfigurationException, DestroyFailedException, ExecutionException, ExpandVetoException, FontFormatException, GeneralSecurityException, GSSException, IllegalClassFormatException, InterruptedException, IntrospectionException, InvalidApplicationException, InvalidMidiDataException, InvalidPreferencesFormatException, InvalidTargetObjectTypeException, IOException, JAXBException, JMException, KeySelectorException, LambdaConversionException, LastOwnerException, LineUnavailableException, MarshalException, MidiUnavailableException, MimeTypeParseException, MimeTypeParseException, NamingException, NoninvertibleTransformException, NotBoundException, NotOwnerException, ParseException, ParserConfigurationException, PrinterException, PrintException, PrivilegedActionException, PropertyVetoException, ReflectiveOperationException, RefreshFailedException, RemarshalException, RuntimeException, SAXException, ScriptException, ServerNotActiveException, SOAPException, SQLException, TimeoutException, TooManyListenersException, TransformerException, TransformException, UnmodifiableClassException, UnsupportedAudioFileException, UnsupportedCallbackException, UnsupportedFlavorException, UnsupportedLookAndFeelException, URIReferenceException, URISyntaxException, UserException, XAException, XMLParseException, XMLSignatureException, XMLStreamException, XPathException Exception의 subclass들

  • java8 기준으로 무수히 많은 subclass를 지니고 있음

  • 대표적으로 RuntimeException , IOException 이 있다.

AnnotationTypeMismatchException, ArithmeticException, ArrayStoreException, BufferOverflowException, BufferUnderflowException, CannotRedoException, CannotUndoException, ClassCastException, CMMException, ConcurrentModificationException, DataBindingException, DOMException, EmptyStackException, EnumConstantNotPresentException, EventException, FileSystemAlreadyExistsException, FileSystemNotFoundException, IllegalArgumentException, IllegalMonitorStateException, IllegalPathStateException, IllegalStateException, IllformedLocaleException, ImagingOpException, IncompleteAnnotationException, IndexOutOfBoundsException, JMRuntimeException, LSException, MalformedParameterizedTypeException, MirroredTypesException, MissingResourceException, NegativeArraySizeException, NoSuchElementException, NoSuchMechanismException, NullPointerException, ProfileDataException, ProviderException, ProviderNotFoundException, RasterFormatException, RejectedExecutionException, SecurityException, SystemException, TypeConstraintException, TypeNotPresentException, UndeclaredThrowableException, UnknownEntityException, UnmodifiableSetException, UnsupportedOperationException, WebServiceException, WrongMethodTypeException RuntimeException 의 subclass들 ChangedCharSetException, CharacterCodingException, CharConversionException, ClosedChannelException, EOFException, FileLockInterruptionException, FileNotFoundException, FilerException, FileSystemException, HttpRetryException, IIOException, InterruptedByTimeoutException, InterruptedIOException, InvalidPropertiesFormatException, JMXProviderException, JMXServerErrorException, MalformedURLException, ObjectStreamException, ProtocolException, RemoteException, SaslException, SocketException, SSLException, SyncFailedException, UnknownHostException, UnknownServiceException, UnsupportedDataTypeException, UnsupportedEncodingException, UserPrincipalNotFoundException, UTFDataFormatException, ZipException IoException의 subclass들

Error와 Exception의 차이

  1. Exception은 Compile , Runetime 으로 구분지을수 있지만 Error는 Runtime 에만 나타난다.
  2. Error는 Control 할수 없지만 Exception은 Control할수 있다.

RuntimeException과 RuntimeException이 아닌것의 차이

  1. RuntimeException 실행중에 따로 명시적으로 예외처리를 강제 하지 않는다.
  2. RuntimeException이 아닌것은 명시적으로 예외처리를 강제로 해줘야한다.
  3. 이 예외처리는 컴파일시 체크한다.

같은 Exception인데 예외처리를 강제하지 않는 이유는 무엇일까 ?

  • 런타임 예외는 어느곳에서나 발생할수 있는 이슈이며 이것을 일일히 런타임 익셉션을 추가하거나 예외처리를 하는것은 프로그램의 명확성을 떨어뜨리기때문

커스텀한 예외 만드는 방법

  • 자신이 원하는 예외를 상속받아 구현한다

class CustomException extends RumtimeException { CustomException() { super();} CustomException(String message) { super(message); } }

출처

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

10주차 멀티스레드 프로그래밍  (0) 2021.01.31
11주차 Enum  (0) 2021.01.30
8주차 - 인터페이스  (0) 2021.01.16
7주차 - 패키지  (0) 2021.01.12
6주차 상속  (0) 2021.01.10

목표

자바의 인터페이스에 대해 학습하세요.

학습할 것 (필수)

  • 인터페이스 정의하는 방법
  • 인터페이스 구현하는 방법
  • 인터페이스 레퍼런스를 통해 구현체를 사용하는 방법
  • 인터페이스 상속
  • 인터페이스의 기본 메소드 (Default Method), 자바 8
  • 인터페이스의 static 메소드, 자바 8
  • 인터페이스의 private 메소드, 자바 9

인터페이스 정의하는 방법

public interface 인터페이스명 { }

인터페이스 구현하는 방법

public class 클래스명 implements 인터페이스명 { } interface는 extends 와 implements 갯수에 대한 제한이 없다.

인터페이스 레퍼런스를 통해 구현체를 사용하는 방법

인터페이스명 인스턴스명 = new 인터페이스명(); **또한 메소드가 한개일 경우 익명내부 클래스로도 구현할수 있다.** 인터페이스명 인스턴스명 = new 인스턴스명() { @Override 메소드관련정보 };

인터페이스의 상속

public interface 인터페이스명 extends 인터페이스명 { }

  • 상위 인터페이스를 상속받아 하위 인터페이스에서 사용할수 있다.
  • 상위 인터페이스의 구현을 extends로 하위인터페이스에서 default method로 할수 있다.

인터페이스의 기본 메소드 ( Default Method ) java 8

  • Java 8 부터 추가된 Default Method는

  • 메소드의 내부구현이 불가능했던 interface가 내부구현도 가능하도록 변경되었다.

  • 상속을 통한 인터페이스끼리의 구현도 가능해졌다.

  • 상위 인터페이스에서 작성한 메소드를 하위 인터페이스에서 상속받아 default method로 구현하는것이 그것이다.

  • 여러 인터페이스에서의 디폴트 메소드가 동일한 경우에는 구현클래스에서 디폴트 메소드를 오버라이딩 해줘야 한다.

  • 디폴트 메소드와 조상 클래스의 메소드간에 동일하는 경우에는 조상 클래스의 메소드가 상속되고 디폴트 메소드는 무시된다.

인터페이스의 스태틱 메소드 ( Static Method ) java 8

  • Java 8부터 추가된 static 메소드
  • static 메소드를 선언하여 메소드의 내부를 구현할수 있게 되었다.
  • 기존클래스처럼 class이름 메소드로 호출하는것이 아닌 인터페이스.이름으로 호출
  • 재정의는 불가능하다.
  • 하위 인터페이스가 상위의 스태틱 메소드를 상속하지 않는다.

참고

https://atoz-develop.tistory.com/entry/JAVA-8-interface-default-키워드와-static-메소드

https://dahyeee.tistory.com/entry/JAVA-interface-default-static메소드

https://docs.oracle.com/javase/specs/jls/se8/html/jls-9.html#jls-9.1

자바의정석

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

11주차 Enum  (0) 2021.01.30
9주차 - 예외 처리  (0) 2021.01.19
7주차 - 패키지  (0) 2021.01.12
6주차 상속  (0) 2021.01.10
4주차 - 제어문  (0) 2021.01.09

목표

자바의 패키지에 대해 학습하세요.

학습할 것 (필수)

  • package 키워드
  • import 키워드
  • 클래스패스
  • CLASSPATH 환경변수
  • classpath 옵션
  • 접근지시자

package 키워드

  • 클래스들의 묶음.
  • 클래스가 물리적으로 하나의 .class 파일이라면 패키지는 하나의 디렉토리.

package 패키지명;

  • 선언 방법

    • 클래스 최상위에 패키지명을 적어준다.
  • 하나의 클래스 한번만 선언 할 수 있다.

  • 자바에서 기본적으로 unnamed package를 제공한다.

    • package를 선언하지않으면 자동으로 unnamed package가 된다.
    • 이렇게 생성된 클래스는 다른 package에 있는 자바 파일에서 import 할수 없다.
    • 같은 unnamed package에 있으면 import 가능.
  • 클래스 파일을 컴파일시 컴파일된 .class의 경로는 기본으로 지정한 경로에 컴파일러가 패키지의 계층구조에 맞게 디렉토리가 없으면 디렉토리를 생성하고 .class파일을 패키지 설정된 경로에 생성한다.

import 키워드

  • 다른 패키지의 클래스를 사용하려면 패키지명이 포함된 클래스 이름을 사용해야 한다.
  • 하지만 매번 패키지명을 적어서 쓰기엔 귀찮다.
  • 그래서 import 키워드를 사용하여 패키지명을 생략 시킬수 있다.

package 패키지명; import 패키지명.클래스명; 또는 import 패키지명.*; import 패키지명.클래스명 은 직접 그 클래스를 지정하는것이고 import 패키지명.*; 은 그 패키지의 모든 클래스를 포함하는것이다.

static import

  • import 키워드를 사용해 클래스의 패키지명을 생략 하듯이
  • static import 키워드를 사용해 static 멤버를 호출할때 클래스 이름을 생략할수 있다.

import static org.junit.Assert.assertThat; import static org.junit.Assert.*; assertThat(); assertEquals();

  • assertThat()은 import static으로 직접 선언했고
  • assertEquals는 import static으로 Assert 패키지 내의 모든 클래스를 선언했으므로 생략하고 사용할수 있다.

클래스패스

  • classpath 는 jdk tools 가 클래스를 찾을수 있게 기준이 되는 방법중 하나.

기본 방법 java -cp 경로 그외에 다른 방법들 windows 환경에서 사용방법 echo %CLASSPATH% linux 환경 echo $CLASSPATH

  • 이렇게 classpath를 등록 시켜놓으면 classpath에 설정된 경로를 생략할수 있다.

java -jar a.jar

  • classpath로 설정된 디렉토리 안에 a.jar파일이 있는 경우 classpath로 등록하면
  • 이런식으로 생략할수 있다.

CLASSPATH 환경변수

  • window 환경 , linux 환경 환경변수 설정은 클래스패스 항목에서 언급함

CLASSPATH 옵션

  • -cp 옵션은 클래스패스 항목에서 언급함.

추가로 -classpath 옵션도 -cp 옵션과 동일하게 작동한다.

접근지시자

  • 외부에서 멤버 또는 클래스에 접근할수 있는 권한을 정해주는것

  • private

    • 접근 불가
    • 같은 클래스에서만 접근할수 있음.
  • default

    • 같은 패키지내에서만 접근가능하다.
    • default 키워드는 생략 가능하다.
  • protected

    • 같은 패키지 내에서만 접근가능하다
    • 추가로 다른 패키지의 서브클래스에서 접근가능하다.
  • public

    • 어느곳에서나 접근가능하다.
  • private → default → protected → public

  • 우로 갈수록 접근범위가 넓어진다.

  • 생성자에도 접근지시자로 권한을 줘서 인스턴스 생성을 못하게 막을 수도 있다.

참고

https://docs.oracle.com/javase/specs/jls/se7/html/jls-7.html#jls-7.5

https://docs.oracle.com/javase/tutorial/essential/environment/paths.html

자바의정석

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

9주차 - 예외 처리  (0) 2021.01.19
8주차 - 인터페이스  (0) 2021.01.16
6주차 상속  (0) 2021.01.10
4주차 - 제어문  (0) 2021.01.09
3주차 연산자  (0) 2021.01.07

목표

자바의 상속에 대해 학습하세요.

학습할 것 (필수)

  • 자바 상속의 특징
  • super 키워드
  • 메소드 오버라이딩
  • 다이나믹 메소드 디스패치 (Dynamic Method Dispatch)
  • 추상 클래스
  • final 키워드
  • Object 클래스

자바 상속의 특징.

  • 단일상속

    • 클래스는 단일 상속만된다.
    • 단 인터페이스는 다중상속이 가능하다.
  • 모든 클래스는 동적으로 Object 클래스를 상속받거나 최상위 부모로 Object 클래스가 존재한다.

    • 다른 클래스를 상속받지 않아도 컴파일러가 자동으로 Object 클래스를 상속시켜준다.
    • 다른 클래스를 상속받는 경우는 결국 최상위 부모 클래스로 Object 클래스가 존재한다.

super 키워드

super

  • 서브 클래스에서 슈퍼클래스로부터 상속받은 클래스를 참조하는데 사용되는 참조 변수.
  • 서브클래스는 슈퍼클래스로 상속받으므로 this 로도 사용할수 있지만 구분을 위해 super로 사용한다.
  • super는 static메서드에서 사용할수 없고 인스턴스에서만 사용할수 있다.

super()

  • 키워드 뒤에 ()가 붙으면 슈퍼클래스의 생성자를 호출하는것을 의미한다.

  • Object클래스를 제외한 모든 클래스의 생성자 첫줄에 생성자 this() 또는 super()를 호출해야한다.

    • 안하면 컴파일러가 자동적으로 super()를 서브클래스 생성자 첫줄에 삽입한다.
    • 하지만 만약 슈퍼클래스의 생성자가 매개변수를 받고 기본생성자가 존재하지 않을 때
    • super(매개변수) 키워드를 사용하지 않는다면 에러가 발생합니다.

메소드 오버라이딩

  • 서브클래스에서 상속받은 슈퍼클래스의 메소드들을 재정의하는것.
  • 메소드 위에 @Override를 붙여 명시적으로 오버라이딩 된 메소드란것을 알린다.

오버라이딩 조건

  • 이름이 같아야 한다.
  • 매개변수가 같아야 한다.
  • 리턴타입이 같아야 한다.
    • JDK 1.5부터 return 타입이 자손 클래스의 타입으로 사용가능하게 변경되었다.
  • 슈퍼클래스의 메소드보다 접근제어자를 좁은 범위로 변경할 수 없다.
  • 슈퍼클래스의 메소드보다 많은 수의 예외를 선언할 수 없다.
  • 인스턴스메서드를 static메소드로 또는 그 반대로 변경할 수 없다.

다이나믹 메소드 디스패치

  • 런타임시에 어떤 메소드를 실행할지 정하는 과정

  • java는 싱글 디스패치 언어.

    • reciever parameter를 하나만 쓸수 있다.
  • 스태틱 디스패치와 다이나믹 디스패치가 있다.

  • 스태틱 디스패칭

    • 컴파일 되는 시점에 어떤 메소드를 실행할지 정하는 과정
    • 검증단계를 안거치기 때문에 다이나믹 디스패칭보다 빠르다.
    static class DispatchTest() { void test() { System.out.print("Test"); } } public static void main (String[] args) { new DispatchTest().test(); }
  • 다이나믹 디스패칭

    • 런타임시에 어떤 메소드를 실행할지 정하는 과정
    • 검증단계를 거치기 때문에 스태틱 디스패칭보다 느리다.
    static abstract class DispatchTest() { abstract void test(); } static class DynamicDispatchTest extends DipatchTest { @Override void test() { System.out.print("Test1"); } } static class DynamicDispatchTest2 extends DipatchTest { @Override void test() { System.out.print("Test2"); } } public static void main (String[] args) { DispatchTest dispatchTest = new DynamicDispatchTest1(); dispatchTest.test(); }
    • 호출 과정에 첫번째로 receiver parameter 란것이 들어가는데
    • 이 receiver parameter에 this에 해당하는 객체가 들어있다.
    method signature
    • name, parameter types 로 구성 되어있다.
    • 위 두가지가 같으면 오버라이딩이 가능.
    • 다르면 오버로딩이 가능.
    method type
    • (return type, method type parameter, method argument types, exception ) 로 구성되어 있다.
    • 이것이 같으면 method reference 를 쓸수 있다.

Double Dispatch

  • 다이나믹 디스패처 과정이 두번 일어나는 과정

interface Post { void postOn(SNS sns); } static class Text implements Post { public void postOn(Sns sns) { sns.post(this); } } static class Picture implements Post { public void postOn(Sns sns) { sns.post(this); } } interface SNS { void post(Text post); void post(Picture Post); } static class Facebook implements SNS { public void post(Text post) { System.out.println("text-facebook"); } public void post(Picture post) { System.out.println("picture-facebook"); } } static class Twitter implements SNS { public void post(Text post) { System.out.println("text-twitter"); } public void post(Picture post) { System.out.println("picture-twitter"); } } public static void main(String[] args) { List<Post> posts = Arrays.asList(new Text() , new Picture()); List<SNS> sns = Arrays.asList(new Facebook() , new Twitter()); posts.forEach(p -> sns.forEach((SNS s) -> p.postOn(s))) }

출처: 토비의 봄 TV 1회 - 재사용성과 다이나믹 디스패치, 더블 디스패치 https://www.youtube.com/watch?v=s-tXAHub6vg&ab_channel=TobyLee

추상클래스

  • 추상메서드를 포함하고 있는 클래스
  • 추상클래스로는 인스턴스를 생성할 수 없다.

abstract class test { }

  • 서브클래스가 상속을 통해 구현해주어야만 인스턴스를 생성할 수 있다.

  • 일반 클래스 일지라도 abstract가 붙으면 인스턴스를 생성할수 없다.

  • 상속의 계층이 점점 내려갈수록 구현도가 높아진다.

  • 상속의 계층이 올라갈수록 점점 추상적이다.

추상메소드

  • 선언부만 존재하는 메소드
  • 구현부가 존재하지 않는다.

abstract 리턴타입 메소드이름();

final 키워드

  • const와 같은 의미인 키워드.

  • 이 키워드가 붙은 변수는 변경될 수 없다. = 상수가 된다.

  • 이 키워드가 메소드에 붙으면 이 메소드는 오버라이딩을 통해 재정의 할수 없다.

  • 이 키워드가 클래스에 붙으면 확장이 불가능해진다. = 다른 클래스의 슈퍼 클래스가 될수 없다.

  • 클래스 , 메소드, 멤버변수 , 지역변수 에만 사용 가능하다.

  • 생성자를 통해 final 멤버 변수를 초기화 할수 있다.

  • 일반적으로는 선언과 초기화를 동시에 하지만 인스턴스변수의 경우 생성자에서 초기화 되도록 할 수 있다.

Object 클래스

  • java.lang 패키지에 존재한다.

  • 이 패키지들은 import가 생략 가능하다.

  • Object 클래스는 모든 클래스의 최고 조상

  • 멤버변수는 없고 오직 11개의 메소드만 갖고 있다.

1. protected Object clone() - 객체 자신의 복사본을 반환 2. public boolean equals(Object obj) - 객체 자신과 매개변수로 받는 객체가 동일한지 체크 3. protected void finalize() - 객체가 소멸될때 gc에 의해 자동적으로 호출된다. 이때 객체가 수행되어야 코드가 있을때 오버라이딩 한다. java9 부터 deprecated 됨. 4. public Class getClass() - 객체 자신의 클래스 정보를 담고 있는 Class 객체를 반환한다. 5. public int hashCode() - 객체 자신의 해쉬코드를 반환한다. 6. public String toString() - 객체 자신의 정보를 문자열로 반환한다. 7. public void notify() - 객체 자신을 사용하려고 기다리는 쓰레드를 하나만 깨운다. 8. public void notifyAll() - 객체 자신을 사용하려고 기다리는 모든 쓰레드를 깨운다. 9. public void wait() - 다른 쓰레드가 notify()나 notifyAll()을 호출할 때 까지 현재 쓰레드를 무한히 또는 지정된 시간 (timeout, nanos)동안 기다리게 한다. 10. public void wait(long timeout) 11. public void wait(long timeout, int nanos)

참조

토비의 봄 1화 https://www.youtube.com/watch?v=s-tXAHub6vg&ab_channel=TobyLee

자바의 정석 - 남궁성

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

8주차 - 인터페이스  (0) 2021.01.16
7주차 - 패키지  (0) 2021.01.12
4주차 - 제어문  (0) 2021.01.09
3주차 연산자  (0) 2021.01.07
연산자  (0) 2020.11.28

+ Recent posts