반응형

generic, io 작성 x

 

annotation

annotation #ex01

Exam0110 -> 애노테이션

public @interface MyAnnotation {
    String value();
}

        // 주석의 프로퍼티를 정의한다. // interface에서 메서드를 정의하는 것과 같다고 생각하자.

        // 메서드 이름은 프로퍼티(변수)명처럼 작성한다. // 자세히보면 value()라서 메서드 명이다.

@MyAnnotation(value="값") // 클래스 정의 앞에 선언할 수 있다.
public class MyClass {

    @MyAnnotation(value="값") // 변수 앞에 선언할 수 있다.
    int i;
    
    @MyAnnotation(value="값") // 메서드 정의 앞에 선언할 수 있다.
    public void m(// 파라미터 앞에 선언할 수 있다.
            @MyAnnotation(value="값")String p) {
        @MyAnnotation(value="값") int local;
        
        // 일반 문장 앞에 선언할 수 없다!
        //@MyAnnotation(value="값") if (true) System.out.println("ok"); // 컴파일 오류!
    }

        // bin/main/com/eomcs/annotation/ex/MyClass.class 확인 // 애노테이션이 Class에 붙어있는 것을 확인

 

annotation #ex02

Exam0110 -> 애노테이션 유지 정책 // @interface

        // SOURCE // 소스 파일에만 남긴다. 컴파일 후 제거된다.

        // CLASS // .class 파일에 남긴다. 그러나 실행 시에 추출할 순 없다.(기본)

        // RUMTIME // .class 파일에 남긴다. 실행 시에 추출할 수 있다.

        // SOURCE는 컴파일 시 bin/main 밑에 .class파일을 열어보면

        // 컴파일 된 파일에 애노테이션이 없어 진 것을 확인할 수 있다.

        // RUNTIME // 실행 중에 애노테이션을 꺼낼 수 있다. // CLASS는 불가능

@Retention(RetentionPolicy.CLASS)
public @interface MyAnnotation {
    String value();
}
@Retention(RetentionPolicy.SOURCE)
public @interface MyAnnotation2 {
    String value();
}
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation3 {
    String value();
}
@MyAnnotation(value="값") // 유지정책 => CLASS 
@MyAnnotation2(value="값") // 유지정책 => SOURCE 
@MyAnnotation3(value="값") // 유지정책 => RUNTIME 
public class MyClass {
}

        // MyClass에 3가지 애노테이션을 적용한다. // 하나에 애노테이션은 3개 다 붙힐 수 있다.

Class clazz = MyClass.class;
        
        // => 유지정책 : CLASS 
        MyAnnotation obj = (MyAnnotation)clazz.getAnnotation(MyAnnotation.class);
        
        // => 유지정책 : SOURCE
        MyAnnotation2 obj2 = (MyAnnotation2)clazz.getAnnotation(MyAnnotation2.class);
        
        // => 유지정책 : RUNTIME
        MyAnnotation3 obj3 = (MyAnnotation3)clazz.getAnnotation(MyAnnotation3.class);

        // MyAnnotation3 obj3 = (MyAnnotation3)clazz.getAnnotation(MyAnnotation3.class); // 애노테이션 추출

        // obj는 RUNTIME이라 애노테이션을 실행중에 추출할 수 있다.

        // obj3.value() // 값 // 실행시 MyClass에서 value=를 "값"이라고 저장해뒀기 때문에 "값"이 나온다 // ""는 안나옴

 

annotation #ex03

Exam0110 -> 애노테이션 필수 프로퍼티 // @interface

@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    String value(); // default 값을 지정하지 않으면 필수 프로퍼티
                    // 즉 애노테이션을 사용할 때 반드시 값을 지정해야 한다.
}
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation2 {
    String value() default "홍길동"; 
        // default 값이 있으면, 
        // 애노테이션을 사용할 때 값을 지정하지 않아도 된다.
}

 

package com.eomcs.annotation.ex3;

//@MyAnnotation // 필수 프로퍼티 값을 지정하지 않으면 컴파일 오류! 
@MyAnnotation2  // 선택 프로퍼티 값을 지정하지 않으면 default 값이 사용된다. 
public class MyClass {
}

        // 1번 MyAnnotation은 컴파일 오류가 발생 // default 값도 지정안하고, MyClass에서도 값을 설정하지 않아 발생

        // default 값을 MyAnnotation에서 지정하던가, // MyClass에서 @MyAnnotation(value="값") 으로 설정해야함.

 

annotation #ex04

-> 애노테이션 생략 // Class에 @애노테이션 붙힐 때

@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    String value();
}
//@MyAnnotation(value="홍길동") // OK!
@MyAnnotation("홍길동") // OK! value 프로퍼티는 이름 생략 가능!
public class MyClass {
}
//@MyAnnotation2(tel="222-2222") // OK!
@MyAnnotation2("222-2222") // value 속성이 아닌 경우 생략 불가!
public class MyClass2 {
}
//@MyAnnotation3(value="홍길동",tel="222-2222") // OK!
@MyAnnotation3("홍길동",tel="222-2222") // value 외 다른 프로퍼티 값도 지정할 경우,
                                      // value 이름 생략 불가!
                                      // value 값만 지정할 때 생략 가능!
public class MyClass3 {
}

// value라는 프로퍼티를 사용할 때에는 생략이 가능하다. // value가 아닐 경우 불가능

// value 외 다른 프로퍼티도 사용한다면 생략 불가능하다.

 

annotation #ex05

Exam01 -> 애노테이션 값 추출 // @interface

  public static void main(String[] args) {
    Class clazz = MyClass.class;
    MyAnnotation obj = (MyAnnotation) clazz.getAnnotation(MyAnnotation.class);

    System.out.println(obj.v1());
    System.out.println(obj.v2());
    System.out.println(obj.v3());

  }

        // MyAnnotation obj = (MyAnnotation)clazz.getAnnotation(MyAnnotation.class);

@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    String v1() default "가나다";
    int v2() default 100;
    float v3() default 3.14f;
}

        // obj.v1 obj.v2 obj.v3으로 호출 가능 // 가나다 100 3.14 순으로 나온다.

Exam02 -> 애노테이션 배열 값 추출 // @interface

    public static void main(String[] args) {
        Class clazz = MyClass2.class;
        MyAnnotation2 obj = (MyAnnotation2)clazz.getAnnotation(MyAnnotation2.class);
        
        System.out.println(obj.v1()[0]);
        System.out.println(obj.v2()[0]);
        System.out.println(obj.v3()[1]);
        
    }

        // obj.v3 등 리턴 값을 빈 배열에 받아서 출력해도 상관은 없다.

@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation2 {
    // 배열 프로퍼티의 기본 값을 지정할 때 중괄호를 사용한다.
	String[] v1() default {"가나다","라마바"};
    int[] v2() default {100,200};
    float[] v3() default {3.14f,5.14f};
}

        // 가나다 100 5.14 순으로 나온다.

Exam03 -> 애노태이션 배열 하나 중괄호 생략 가능 // @interface

@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation3 {
    // 배열 값이 한 개일 경우 중괄호를 생략할 수 있다.
    String[] v1() default "가나다";
    int[] v2() default 100;
    float[] v3() default 3.14f;
}

Exam04 -> 애노테이션 배열 값 지정 // Class에 @애노테이션 붙힐 때

@MyAnnotation3(
        // 배열 값을 지정할 때 중괄호를 사용한다.
        v1={"홍길동", "임꺽정", "유관순"},
        v2={1000, 2000, 3000, 4000, 5000},
        v3={1.12f, 2.23f, 3, 34f})
public class MyClass4 {
}

Exam05 -> 애노태이션 배열 하나 중괄호 생략 가능 // Class에 @애노테이션 붙힐 때

@MyAnnotation3(
        // 배열 값이 한 개일 경우 중괄호를 생략할 수 있다.
        v1="임꺽정",
        v2=1111,
        v3=1.11f)
public class MyClass5 {
}

 

annotation #ex06

-> 애노테이션 적용 범위 지정

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    String v1() default "가나다";
}
@MyAnnotation // OK!
public class MyClass {
    @MyAnnotation int i; // 컴파일 오류!
    @MyAnnotation public void m() {} // OK!
}

// 애노테이션 적용 범위 설정을 @interface 화면에 설정 할 수 있다.

// METHOD와 TYPE이 설정되어 있는 상태이다. // METHOD는 메소드를, TYPE은 Class를 의미한다.

// int i를 사용하기 위해서는 Target에, ElementType.FIELD를 추가하여야 사용 할 수 있다.

 

concurrent

concurrent #ex01

Exam0110 -> java // 자바는 main() 메서드를 실행하는 한 개의 "실행 흐름"이 있다 // 실행 흐름에 따라 실행된다.

Exam0110 -> c //

Exam0120 -> java // 동시에 실행하고 싶은 코드가 있다면 thread를 상속받아 run()메서드에 그 코드를 둔다.

                 // thread // 코드 실행 라인을 새로 만들어 따로 실행 // 스레드는 비동기로 동작(별도로)

                 // 스레드에 작업을 시킨 후, 그 스레드가 작업이 끝날 때까지 기다리지 않고 즉시 리턴

                 // 따라서 스레드 작업과 main()의 코드가 병행(concurrent)으로 실행된다. // 멀티테스킹

                 // CPU Scheduling(=프로세스 스케줄링) // CPU의 실행 시간을 쪼개 실행하는 방법 

                 // Multi-processing // Parent(프로세스)를 fork(복제)하여 Child(프로세스)를 만드는 방식

                 // Process를 복제할때 그에 해당하는 Heap(메모리)도 같이 복사한다. // 메모리 낭비가 심하다.

                 // Process별로 종료를 하여야 한다. // Parent 종료, Child 종료 별도

                 // Multi-threading // Process에서 thread로 실행을 분리한다. // heap(메모리)는 Process에 유지

                 // 작업 부분만 떼서 thread에서 처리한다. // thread는 stack(메모리)만 가져간다. // 자원 절약

                 // Multi-threading은 메인 프로세스의 메모리를 공유한다. // Multi-processing은 메모리를 복제한다.

                 // 모든 thread는 process에 종속한다. // process 종료시 thread도 종료 된다.

                 // JVM과 thread // JVM(process) 안에 thread가 기본적으로 들어있다. // 여러가지가 있다.

                 // 대표 예) main(main 메소드 호출, garbage collector, 레퍼런스 관리(인스턴스의 레퍼런스 관리)

Exam0120 -> c //

 

concurrent #ex02

Exam0110 -> Thread // JVM은 여러개의 스레드를 실행한다. 

               // Thread t = Thread.currentThread(); // 현재 실행중인 스레드 확인

               // JVM이 실행될 때 main()메서드를 호출하는 thread의 이름은 main이다.

Exam0120 -> Thread 그룹 // thread는 그룹으로 묶일 수 있다.

               // Thread main = Thread.currentThread(); // 현재 실행 쓰레드

               // ThreadGroup group = main.getThreadGroup(); // thread main의 소속 그룹을 알 수 있다.

               // 현재 상태 // main(TG) => main(T) // main이라는 쓰레드 그룹 안에 main 쓰레드가 있다.

Exam0130 -> Thread 그룹 소속 Thread 목록 확인

               // Thread[] arr = new Thread[100]; // int count = mainGroup.enumerate(arr, false);

               // thread 빈 배열을 준비해서 넘긴다 false는 하위 그룹에 소속된 쓰레드는 가져오지 않는다.

               // 즉, 현재 그룹에 소속된 스레드 목록만 가져오라는 뜻이다.

Exam0140 -> Thread 그룹 소속 Thread 그룹 목록 확인

                // ThreadGroup[] groups = new ThreadGroup[100]; // int count = mainGroup.enumerate(arr, false);

                // threadgroup 빈 배열을 준비해서 넘긴다, false는 하위 그룹에 소속된 쓰레드 그룹은 가져오지 않는다.

                // 즉, 현재 그룹에 소속된 스레드 그룹 목록만 가져오라는 뜻이다.

Exam0150 -> 스레드 그룹의 부모 그룹 확인

                // ThreadGroup parentGroup = mainGroup.getParent(); // 최상위 그룹은 System 이다.

                // System의 부모 그룹은 없다.

Exam0160 -> 시스템 그룹의 자식 그룹 확인

                // ThreadGroup[] groups = new ThreadGroup[100]; int count = systemGroup.enumerate(groups, false);

                // main(TG), InnocuousThreadGroup(TG)

Exam0170 -> 시스템 스레드 그룹의 자식 스레드 확인

                // Thread[] arr = new Thread[100]; int count = systemGroup.enumerate(arr, false);

                // Reference Handler(T), Finalizer(T), Signal Dispatcher(T), GroupAttach Listener(T)

Exam0180 -> JVM의 전체 스레드 계층도

 

concurrent #ex03

Exam0110 -> Thread 사용 // Thread를 상속받아 사용

                 // class MyThread extends Thread { // 이미 만들어져 있는 Thread를 상속받아 만들어 사용한다.

                 // public void run() { // 새 스레드에서 실행하고픈 코드가 있다면 오버라이딩 하여 사용한다.

                 // MyThread t = new MyThread(); t.start(); // Thread를 상속받은 클래스 객체를 만들어 사용

                 // Thread의 서브 클래스는 그냥 인스턴스를 만들어 start()를 호출

                 // 다중 상속이 불가능하기 때문에 다른 클래스를 상속 받을 수 없다.

Exam0120 -> Thread 익명클래스 //

                  // new Thread() { public void run() { ... }.start(); // run을 오버라이딩해서 사용.

Exam0210 -> Thread 사용 // Runnable 인터페이스 구현 + Thread

                  // class MyRunnable implements Runnable { public void run() { ... } 

                  // Thread t = new Thread(new MyRunnable()); t.start(); // Runnable 구현체를 Thread 객체에 실어서 실행

Exam0220 -> Thread 익명클래스 // Runnable 인터페이스 구현 + Thread

                  // new Thread(new Runnable() { public void run() {... }).start(); // run을 오버라이딩해서 사용.

Exam0230 -> Thread lambda// new Thread(()-> {...}).start(); // 람다 문법 적용

Exam0310 -> Thread와 프로그램 종료 // 모든 스레드가 완료할 때까지 JVM은 종료되지 않는다.

                   // main 스레드에서 스레드 객체 생성하기 // 자식 스레드는 부모 스레드와 같은 우선 순위를 갖는다.

                   // main 스레드에서 만든 자식 스레드와 main 스레드가 다 끝나야 JVM은 종료 된다.

                   // main 스레드가 먼저 완료돼도, 자식 스레드가 끝날 때까지 JVM은 종료되지 않는다.

 

concurrent #ex04

Exam0110 -> Thread 생명 주기(Lifecycle) // 죽은 스레드는 살릴 수 없다.

Exam0111 -> Thread 생명 주기(Lifecycle) // 같은 쓰레드 객체를 또 실행할 수 없다.

Exam0120 -> Thread start, join

                  // Thread t = new Thread() { // t 스레드를 만들고

                  // t.start(); // 스레드 t를 시작한다.

                  // t.join(); // t스레드가 종료되면 t.join();을 가진 스레드가 실행된다. // 즉 t가 끝날 때까지 기다린다.

Exam0130 -> Thread sleep 

                  // Thread.currentThread().sleep(3000); // Thread.sleep(3000); // 3초 동안 not runnable 상태로 만든다.

                  // currentThread()가 스태틱 메서드라 생략이 가능하다.

                  // sleep()을 호출하면, 그 순간 실행하는 스레드를 잠들게 한다.

                  // 3초 동안 CPU가 놀고 있더라도 CPU를 사용하지 않는다.

                  // 3초가 지나면(timeout) 다시 "main" 스레드는 CPU를 받아 실행한다.

Exam0140 -> CPU 쟁탈전(racing) // 스레드를 시작하면, running 상태로 접어든다. // CPU를 받을 수 있는 상태이다

                  // CPU는 OS의 관리 정책에 따라 스레드나 프로세스에 배분된다.

                  // OS가 CPU를 임의시간 동안 배분 후, 회수하여 현재 스레드 포함한 전체 스레드나 프로세스에 배분한다.

                 // 1. Round-Robin 방식 // windowOS에서 사용

                 // CPU 실행 시간을 일정하게 쪼개서 각 코드에 분배하는 방식

                 // 2. Priority 방식 // Unix, Linux에서 사용

                 // 우선 순위가 높은 코드에 더 많은 실행 시간을 배정하는 방식

                 // 단점 : 우선 순위가 낮은 경우 CPU 시간을 배정받지 못해, 몇 년 동안 실행되지 않는 경우도 있었다.

                 // aging 기법(에이징 기법) // 위의 단점 해결책

                 // CPU 시간을 배정 받지 못할 때마다 우선 순위를 높여 언젠간 실행되게 만든 기법

                 // 컨텍스트 스위칭(context switching) // 코드마다 어디까지 실행했는지 위치 기억이라고 생각.

                 // CPU 실행 시간을 쪼개 이 코드 저 코드를 실행할 때마다,

                 // 실행 위치 및 정보(context)를 저장하고 로딩하는 과정을 말한다.

Exam0210 -> Thread 우선 순위 조회

                 // Thread.MIN_PRIORITY // 최소 우선순위(1) // Thread.MAX_PRIORITY // 최대 우선순위(10)

                 // JVM에서는 1~10까지만 관리를 한다.

                 // Thread.NORM_PRIORITY // 우선 순위 기본값(5) // main스레드 우선 순위(5)

                 // Thread.currentThread().getPriority()); // 현재 스레드 우선 순위 확인

                 // 자식 스레드는 부모 스레드의 우선 순위와 같은 값을 갖는다.

                 // 즉 main에 다른 스레드를 만들면, main이 부모 스레드이니 우선 순위 5를 갖는다.

                 // 우선 순위가 높으면 CPU 사용 배분을 더 자주 받는다.

                 // 스레드는 JVM이 관리하는게 아니라 OS가 관리한다. // 즉 OS의 스레드를 이용하는 것이다.

                 // 우선 순위에 따라 실행 스케줄을 어떻게 관리할 지는 OS따라 다르다.

                 // windowOS는 우선 순위를 크게 고려하지 않는다.

                 // Windos에서 실행시 우선 순위에 영향을 적게 받는다.

                 // Unix, Linux 계열 OS는 우선 순위를 고려한다. 

                 // Unix, Linux 계열 OS에서 실행시 우선 순위에 영향을 크게 받는다.

                 // Java는 Write Once, Run Anywhere를 캐치프라이즈로 만들어진 만큼,

                 // OS마다 우선순위에 따른 영향을 받는다는 것은 자바의 목적이 아니다.

                 // 따라서 Thread를 다룰 때 우선 순위를 고려하는 방식으로 프로그래밍 하지 말자. // 가능하면 쓰지말라

Exam0220 -> Thread 우선 순위 설정

                  // Thread.currentThread().setPriority(1); // Thread.setPriority(1); //로 우선순위를 설정한다.

                  // Math.asin(38.567); // 부동 소수점 연산은 시간을 많이 쓰기 때문에, 시간 끌기용으로 넣어둔 것이다.

 

concurrent #ex05

Exam0110 -> 크리티컬 섹션(임계영역; critical section) 또는 크리티컬 리전(critical region)

                // 여러 스레드가 같은 메모리(balance 필드)의 값을 동시에 변경할 때 문제가 발생하는 코드

                // 뮤텍스(mutex) 또는 세마포어(1)(semaphore) // 크리티컬 섹션에 동시에 접근하지 못하게 하는 기법

                // 세마포어(n); semaphore // 크리티컬 섹션에 진입할 수 있는 스레드의 수를 지정한다.

                // 자바에서는 세마포어를 지원하지 않는다. // 개발자가 직접 처리해야 한다.

                // 뮤텍스; mutex(mutual exclusion, 상호배제) // ex) 선풍기 풍량세기, 라디오 채널, TV 채널 등

                // 한 번에 오직 한 개의 스레드만이 크리티컬 섹션에 접근할 수 있다. // semaphore(1)과 같다.

                // 자바는 synchronized 키워드를 통해 뮤텍스를 사용할 수 있다.

                // 자바에서 뮤텍스를 구현하는 방법

                // 크리티컬 섹션의 메서드나 코드 블록에 sychronized 키워드를 걸어

                // 한 번에 한 스레드만 진입할 수 있도록 lock을 건다.

                // synchronized // modifier // 변경자 클래스, 변수, 메서드의 선언부에 사용되어 부가적인 의미를 부여

                // Exam0110 Account에는 100만원이 있다. 변경자를 주석으로 막고 실행하면, 

                // 5개의 ATM기에서 총합 100만원이 넘는 금액이 출금이 가능하다 // 치명적인 오류

                // 동시에 여러 쓰레드가 접근이 가능하기 때문에 발생하는 문제이다.

                // 변경자의 주석을 풀어 변경자를 적용하고 실행하면, 한 번에 한 스레드만 접속이 가능하다.

                // ATM기별 우선순위에 따라 각 ATM기의 금액은 차이가 나지만, 총합이 100만원인 것은 변함이 없다.

                // 스레드 안전(Thread safe) // synchronized, 크리티컬 섹션하지 않게 만든다.

                // 여러 스레드가 동시에 실행해도 문제가 없는 코드 블록을 말한다.

                // 이 Thread를 Thread safe하게 만드세요. // = 여러 스레드가 조회는 가능해도, 값을 변경하게 하지 말라.

                // 실무에서는 위처럼 얘기하지 크리티컬 섹션하지 않도록 하세요 이런식으로 얘기하지 않는다.

concurrent #ex06

Exam0110 -> Thread // Dead 상태의 스레드는 다시 시작할 수 없다. // 실행중인 스레드를 다시 실행시킬 수도 없다.

Exam0120 -> Thread 재사용 // Thread가 꺼지지 않게 while (true)로 무한 반복하게 한다.

Exam0130 -> Thread 재사용 // 별도 변수 선언하여 사용하지 않으면, sleep에 들어가게 한다.

Exam0140 -> Thread 재사용 // wait(), notify() 메서드 사용 // wait()은 반드시 동기화 영역 안에서 호출해야 한다.

                // 동기화 영역? // synchronized로 선언된 메서드 //  synchronized로 선언된 블럭

                // synchronized (this) { notify() } // 

Exam0210 -> Thread 재사용 // Pooling 기법을 이용 // Thread List를 만들어 보관하여 사용한다.

                // run()상태를 유지하게 하고 wait()으로 기다리게하고 notify()로 다시 사용한다.

 

 

corelib

corelib #ex01

Exam0110 -> Object 클래스 // 자바 최상위 클래스 // 모든 메서드는 Object 클래스를 자동으로 상속받는다.

                  // finalize() 가비지 컬렉터에 의해 메모리에서 해제되기 직전에 호출된다. // 그 외에는 밑에서 다룸.

Exam0120 -> toString() // Object 클래스의 메서드 // 클래스 이름과 해시코드를 리턴한다.

Exam0121 -> toString() 오버라이딩

Exam0122 -> toString()의 리턴 값 // 인스턴스의 주소를 알려주는 것이 아닌 해시값(해시코드)을 리턴한다.

Exam0123 -> toString() 오버라이딩

Exam0130 -> equals() // Object 클래스의 메서드 // 같은 인스턴스인지 검사한다.

Exam0131 -> equals() 오버라이딩 // 사용할때 꼭 클래스에 맞게 오버라이딩 하라.

Exam0132 -> equals() 오버라이딩 // String wrapper클래스는 오버라이딩이 자동으로 되어있다.

Exam0133 -> equals() 오버라이딩 

                  // equals는 기본적으로 인스턴스가 같은지만 비교한다, 데이터가 같은지는 비교하지 않는다.//

Exam0134 -> equals() 오버라이딩 // StringBuffer 클래스는 오버라이딩이 자동으로 되어있지 않다.

Exam0140 -> hashCode() // Object 클래스의 메서드 // 인스턴스를 식별하는 값을 리턴한다.

Exam0141 -> hash value? // 매우 낮은 확률이지만 데이터가 다르더라도 같은 정수 값이 나올 수 있다.

                  // 해시 알고리즘 SHA, MD, PGP

Exam0142 -> hashCode() 오버라이딩 // Map에 값을 저장하는 key로 사용할 때 hashCode()를 오버라이딩

Exam0143 -> hashCode() // 인스턴스의 고유 값을 리턴한다. 데이터가 같더라도 다른 값을 리턴한다.

Exam0144 -> '디지털 지문' // 해시코드를 데이터를 구분하는 지문과 같다고 해서 부른다.

Exam0145 -> hashCode() 오버라이딩 // String 클래스는 오버라이딩이 자동으로 되어있다.

Exam0150 -> HashSet // 저장할 객체에 대해 hash 코드로 중복 여부를 검사

                  // hash 코드로 값을 저장할 인덱스를 결정하기 때문에 값을 꺼낼 때 저장한 순서대로 꺼낼 수 없다.

Exam0151 -> HashCode 오버라이딩 HashSet 저장 // 데이터가 같으면 같은 HashCode가 나오게 오버라이딩.

                  // HashSet에 저장하면 중복된 값은 저장되지 않는다. // equals()도 같이 오버라이딩 한다.

Exam0152 -> HashMap // 값을 저장할 때 key 객체의 해시코드를 이용하여 저장할 위치(인덱스)를 계산

Exam0153 -> HashCode오버라이딩 HashMap 저장

Exam0154 -> hashCode() 오버라이딩 HashMap 사용 // wrapper 클래스는 오버라이딩이 자동으로 되어있다.

                  // HashMap/Hashtable의 key로 사용하자. // 그 외에는 오버라이딩을 별도로 진행하여 키로 사용

Exam0155 -> Key로 HashMap 데이터 사용 // get(key, "데이터")으로 넣고, set(key)로 데이터를 받는다.

Exam0160 -> getClass() // Object 클래스의 메서드 // 인스턴스의 클래스 정보를 리턴한다.

Exam0161 -> getClass() 배열 타입의 정보

Exam0162 -> getClass() 배열의 클래스 정보, 배열 항목의 타입 정보

Exam0170 -> clone() // Object 클래스의 메서드 // 인스턴스를 복제한 후 그 복제 인스턴스를 리턴한다.

Exam0171 -> clone() // 오버라이딩 해야만 사용이 가능하다. 

                  // public Score clone() throws CloneNotSupportedException { return (Score) super.clone(); }

Exam0172 -> Cloneable 인터페이스 구현 // Clone할 클래스에 표시를 해주어야 한다.

                  // static class Score implements Cloneable // 이 표시가 안된 클래스는 clone()을 호출할 수 없다.

Exam0173 -> shallow copy // 얕은 복제 // 인스턴스 변수가 가리키고 있는 객체는 복제하지 않는다.

Exam0174 -> deep copy // 깊은 복제 // 인스턴스 변수가 가리키는 객체도 복제하는 코드를 별도로 작성한다.

                   // 데이터가 간단하다면, 복제한 인스턴스 변수의 객체에 복제할 인스턴스 변수의 객체를 넣어주면 되고

                   // 배열이라면 반복문을 사용하는 등 변수의 객체에 맞는 방법을 사용한다.

 

corelib #ex02

Exam0110 -> String 인스턴스를 생성 영역에 따른 차이 // Heap vs string constant pool

                  // new String("Hello") // heap 영역에 생성한 Hello는 추가 생성시마다 새로운 메모리 주소를 갖는다.

                  // String x1 = "Hello"; // string constant pool 영역은 데이터가 같으면 추가 메모리를 생성하지않는다.

                  // x1과 x2는 String 인스턴스의 주소를 리턴한다. // x1과 x2는 같은 인스턴스 주소를 리턴한다.

Exam0111 -> 일반 클래스와 랩퍼 클래스의 차이 // 랩퍼 클래스는 오버라이딩이 되어 있다.

                  // 일반 클래스는 hashCode() , equals() , toString()을 별도로 오버라이딩 해야한다.

Exam0120 -> 랩퍼 클래스 equals() 클래스 // 오버라이딩이 되어있다.

Exam0121 -> 일반 클래스 equals() 클래스 // StringBuffer 클래스는 오버라이딩이 되어있지 않다.

Exam0130 -> immutable 객체 // 인스턴스의 데이터를 변경할 수 없다. // 원본을 못 바꾼다. // String 클래스

Exam0131 -> mutable 객체 // 인스턴스의 데이터를 변경할 수 있다. // 원본을 바꾼다. // StringBuffer 클래스

Exam0140 -> toString() // println에는 자동으로 toString 기능이 있다.

Exam0141 -> toString() String 클래스 // toString은 String클래스에서 오버라이딩 되어 사용된다.

Exam0142 -> toLowerCase() // 모든 문자를 소문자로 적용한다.

Exam0210 -> Wrapper 클래스 // primitive data type 값을 보다 다양한 방법으로 다루기 위한 클래스

Exam0220 -> auto-boxing, auto-unboxing

Exam0221 -> auto-boxing // 원시타입 데이터를 자동으로 레퍼런스에 넣는다.

                  // int 100(primitive data type)을 자동으로 Integer.valueOf(100)로 변경하여 Integer에 저장한다.

Exam0222 -> auto-unboxing // 레퍼런스의 값을 원시 타입 데이터에 넣는다.

                  // Integer.valueOf(300);의 Integer obj를 자동으로 obj.intValue()로 변경하여 int에 저장한다.

Exam0223 -> Wrapper 클래스 적용 후// 오토박싱 언박싱을 이용하여 보다 편리하게 코딩이 가능하다.

Exam0224 -> Wrapper 클래스 적용 전 // 원래라면 일일히 정의를 하고 사용을 하여야 한다.

Exam0230 -> Wrapper 클래스의 장점 // cache에 저장함.

                  // Integer obj3 = 100; // Integer obj5 = Integer.valueOf(100); // obj3 == obj5 // true

                  // obj3과 obj5는 같은 인스턴스 주소를 리턴한다. // 메모리를 아끼기 위함.

                  // Integer obj3 = 128; // Integer obj5 = Integer.valueOf(128); // obj3 == obj5 // false

                  // 단, 정수 값이 -128 ~ 127까지만 같은 인스턴스 주소를 리턴한다.

                  // 범위를 넘어가는 값은 임시적으로 cache에 저장한다.

Exam0231 -> Wrapper 클래스의 값 비교 // Wrapper 클래스는 equals()가 오버라이딩이 다 되어있다.

                  // 값을 비교할 때에는 ==가 아닌 equals를 이용하자 // cache에 저장된 값은 ==가 false로 나옴.

 

corelib #ex07

Exam0110 -> HashSet의 사용 // hashCode와 equals의 값이 같다면, 같은 값으로 취급하여 중복 저장하지 않는다.

                  // hashCode()의 값으로 순서를 결정하기 때문에, 랜덤이다. // index() 사용 불가.

Exam0120 -> ArrayList의 같은 값의 데이터 저장 // 같은 값을 가지는 데이터를 저장 할 수 있다.

Exam0121 -> ArrayList의 같은 인스턴스 저장 // ArrayList에 포함된 인스턴스도 다시 중복하여 저장할 수 있다.

Exam0210 -> HashSet에서 값을 꺼내는 방법 // iterator에게 맡긴다. // hasNext() next() 사용

Exam0220 -> LinkedList도 iterator 사용 가능.

Exam0230 -> Stack도 iterator 사용 가능.

Exam0240 -> Queue도 iterator 사용 가능.

Exam0310 -> HashSet 오버라이딩 // 오버라이딩 하지 않고서는 원하는 결과를 얻기 힘들다.

Exam0320 -> HashSet equals만 오버라이딩 // equals만 오버라이딩 해서는 원하는 결과를 얻기 힘들다.

Exam0330 -> HashSet hashCode만 오버라이딩 // hashCode만 오버라이딩 해서는 원하는 결과를 얻기 힘들다.

Exam0340 -> HashSet 오버라이딩 // HashSet은 equals와 hashCode 모두 오버라이딩 하여야 한다.

 

corelib #ex08

Exam0110 -> HashMap의 사용 // HashMap은 key와 value로 저장한다. // put(key, value)  get(key)

                  // 같은 key로 다른 value를 추가하면 덮어쓴다.

                  // 존재하지 않는 key를 지정하면, null을 리턴한다.

Exam0111 -> Key는 Object를 상속하여, 어떠한 값도 저장이 가능하다.

Exam0120 -> 사용자 정의 데이터 타입을 key로 사용할 때 // key의 데이터가 같더라도, 저장이 된다.

                  // hashCode()와 equals() 오버라이딩을 하여야 한다.

Exam0130 -> HashMap equals만 오버라이딩 // equals만 오버라이딩 해서는 원하는 결과를 얻기 힘들다.

Exam0140 -> HashMap hashCode만 오버라이딩 // hashCode만 오버라이딩 해서는 원하는 결과를 얻기 힘들다.

Exam0150 -> HashMap 오버라이딩 // HashSet은 equals와 hashCode 모두 오버라이딩 하여야 한다.

                  // 모두 오버라이딩 하기 싫다면, 이미 되어있는 Wrapper 클래스를 이용하자. ex) String 클래스

Exam0210 -> HashMap에서 key 목록을 꺼내는 방법 // 1. Iterator 사용 2. 배열 사용 3. Collection 규칙 따를 때

                  // java.util.Set keys = map.keySet(); // keySet()을 통해 key의 목록을 받는다. 

                  // key는 값이 중복되어서는 안되기 때문에 Set에 담아서 리턴한다.

Exam0220 -> HashMap에서 key와 value의 목록을 꺼내는 방법 // java.util.Set entrySet = map.entrySet(); 이용

Exam0230 -> HashMap에서 value의 목록을 꺼내는 방법 // java.util.Collection values = map.values();

                  // value는 값이 중복되어도 되기 때문에 Collection에 담아서 리턴한다.

Exam0310 -> HashMap과 Hashtable // null을 key나 value로 사용하여야 하면, HashMap을 사용한다.

                  // HashMap은 null을 key와 value로 사용이 가능하다. // Hashtable은 불가능.

                  // HashMap은 동기화를 지원하지 않아 속도가 빠르다. // Hashtable은 지원, 속도 느림.

Exam0320 -> HashMap에서 keySet()호출 // Set keys = map.keySet();

                  // keySet()의 값은 실제 호출할 때 저장이 된다. 

                  // keySet() 객체 생성 후, 값을 변경하고 호출하면, 값을 변경한 key의 목록이 출력된다.

Exam0321 -> HashMap에서 keySet()호출과 Iterator호출 // Set keys = map.keySet();

                  // Iterator iterator = keys.iterator(); // Iterator는 객체 생성 시 값이 저장이 된다.

                  // 객체 생성 후, keySet()의 값을 변경하면 Iterator는 객체 생성 당시 값을 기억하고 있으므로,

                  // Iterator는 무효한 목록의 값을 가지고 있다. // 무효한 Iterator는 실행 오류가 발생한다.

                  // 즉, Iterator에 목록을 넘겨주고 값을 수정하면 오류가 발생한다.

Exam0330 -> Hashtable에서 keySet()호출 // Set keys = table.keySet(); // Exam0320 HashMap과 같다.

Exam0331 -> Hashtable에서 keySet()호출과 Iterator호출 // Set keys = map.keySet(); // Exam0321 HashMap과 같다

 

 

 

exception

exception #ex1

Exam0110 -> 원래 리턴 값으로 예외처리 문법을 확인하였다.

Exam0120 -> 리턴 값을 검사하여 오류를 판단하였다.

Exam0121 -> 리턴 값을 검사하는 것의 문제점 // 정상적인 계산 결과의 값이 검사 값과 같다면 오류로 처리한다.

Exam0130 -> Exam0121의 경우를 예로 들어 예전에는 희귀한 값을 리턴하도록 했다.

Exam0131 -> 아무리 희귀한 값이라도 그 값이 정상 값일 수 있다라는 오류가 있다.

Exam0210 -> 예외처리의 필요성 // 실행 오류를 내버리면 실행이 종료되어 버린다.

 

exception #ex2

Exam0110 ->예외처리 적용 전

Exam0120 -> try catch 문법 // try안에서 예외가 발생하더라도 catch에서 받아주며, 프로그램은 진행한다.

                  예외처리 문법이란 ? // 프로그램을 실행하던 중에 예외 상황이 발생하더라도

                   // 시스템을 멈추지 않고 계속 실행되게 도와주는 문법

 

exception #ex3

Exam0110 -> try catch 사용 // 오류가 발생해도, 진행이 계속 된다. // throws [Throwable 객체]

                 // Throwable 객체는 Exception 를 말한다. // try catch를 이용해 예외 발생한 이유를 출력할 수 있다.

Exam0111 -> try catch 미사용 // 오류가 발생하면 실행이 멈춰버린다.

Exam0210 -> Throwable의 종류 // 1. java.lang.Error (시스템 오류) 2. java.lang.Exception (애플리케이션 오류)

                  // 1. 오류가 발생하면 현재의 시스템 상태를 즉시 백업하고, 실행을 멈춰야 한다.

                  // 오류의 예 : 스택 오버 플로우 오류, VM 관련 오류, AWT 윈도우 관련 오류, 스레드 종료 오류 등

                  // 2. 적절한 조치를 취한 후 계속 시스템을 실행하게 만들 수 있다.

                  // 오류의 예 : 배열의 인덱스가 무효한 오류, I/O 오류, SQL 오류, Parse 오류, 데이터 포맷 오류 등

                  // 메서드 선언부에 반드시 어떤 오류를 던지는 지 throws [Throwable 객체]로 알려줘야 한다.

Exam0211 -> Error 계열의 예외 // JVM 관련 오류일 때 사용하는 클래스 // 가급적 예외처리를 사용하지 않는다.

                  // 메서드 선언부에 예외를 선언하지 않아도 된다.

Exam0212 -> Exception 계열의 예외 // 메서드 선언부에 예외를 선언해야 한다.

Exam0220 -> RuntimeException 예외 // Exception의 서브클래스 // 메서드 선언부에 예외를 선언하지 않아도 된다.

Exam0310 -> 메서드에서 발생되는 예외는 메서드 선언부에 모두 나열해야 한다.

Exam0320 -> 메서드에서 발생되는 예외들을 예외들의 수퍼클래스 선언 하나로 퉁 칠 수 있다.

                  // 유지보수에 도움이 되기 위해 메서드에서 발생되는 예외는 다 나열하자.

Exam0410 -> 예외처리를 한 메소드를 호출할 때, 호출한 메서드에도 예외처리가 되어있어야 한다.

Exam0420 -> main 메소드의 선언부에 예외처리를 하는 것은 가장 마지막으로 사용되어야 한다.

                  // main 메소드 선언부에 예외처리시 예외 발생시 실행이 멈춰버리기 때문이다.

                  // 사용이 불가능 한 것은 아니나 사용하지 말자.

Exam0430 -> Exam0410 방법 // 예외처리된 메소드를 호출하는 곳에서 try catch로 받자.

                  Exam0420 방법 // main메소드에서도 try catch로 받으면 선언부에 예외를 선언하지 않아도 된다.

Exam0440 -> 여러개의 예외를 받을 때, 슈퍼클래스의 예외처리는 가장 나중에 받자.

                  // 슈퍼클래스의 예외처리부터 받아버리면 오류가 발생한다.

Exam0450 -> 여러개의 예외를 받을 때, 슈퍼클래스 예외처리 하나로 예외처리가 가능하다.

                  // 단 슈퍼클래스 예외처리 후, 서브클래스 예외처리를 선언한다면 오류가 발생한다. // Exam0440

Exam0460 -> 다형적 변수를 활용한 예외처리 받기 // (RuntimeException | SQLException | IOException e)

Exam0470 -> Error 예외는 정상적으로 프로그램이 당장 실행 불가능할 때를 말한다 // 함부로 선언 하지마라.

Exam0471 -> 예외처리 가장 상위 클래스인 Throwable를 예외처리로 사용하지 마라. 

Exam0472 -> Error 예외는 굳이 예외처리하지 않아도 된다.

Exam0510 -> finally 블록 // 정상적이던 예외가 발생하던, finally 블록은 무조건 실행한다.

Exam0520 -> finally 블록 // catch 블록이 없어도, try 블록을 나가기 전 실행해야 한다면 finally 블록을 이용하자.

Exam0610 -> close를 사용하여야 하는 이유 // close()로 연결했던 것을 풀어주는 것을 자원해제라 한다.

                // 24시간 365일 유지되는 서버에서는 다른 프로그램이 해당 자원을 쓸 수 있도록 자원 해제를 해야한다.

Exam0620 -> finally 블록을 이용해, close()를 실행한다. // 예외가 발생해도 정상적으로 자원해제 되게끔 한다.

Exam0630 -> java.lang.AutoCloseable // 매번 모든 자원을 일일히 close()하지 말자

                  // try-with-resources 문법 // try() {} ()안에 자원을 선언하면 try문이 끝나고 자동으로 해제된다.

                  // try (java.lang.AutoCloseable 구현체) {...} // 단 AutoCloseable 구현체만 자동 해제가 가능하다.

Exam0640 -> AutoCloseable 구현체 // implements AutoCloseable 상속 받아 구현하자.

                  // static class B implements AutoCloseable { public void close() throws Exception { } }

Exam0641 -> AutoCloseable 예외발생

                  // try문에서 오류가 발생했다면, try문을 나가기 전에 close()가 실행된다. 그 이후 catch 실행

Exam0650 -> try() // ()안에는 변수 등 변동이 있는 값에 대한 코드를 넣을 수 없다.

Exam0710 -> 필수 예외처리 // File 패키지의 getCanonicalPath() 메서드처럼 예외처리를 필수로 해야하는 경우가 있다.

 

exception #ex4

Exam0110 -> 메서드 호출 // 예외처리 아예 적용 전

Exam0120 -> 예외처리 호출 // 예외처리 된 메서드를 호출하려면, 호출하는 메서드도 예외처리 되어야 한다.

                  // ex) m1() -> m2() -> m3() -> m4() 순으로 호출하고, m4이 예외처리된 메서드라면,

                  // m1(), m2(), m3() 모두 예외처리를 해주어야 한다. // throws Exception

Exam0130 -> RuntimeException // RuntimeException와 서브클래스들은 예외처리 하지 않아도 된다.

 

exception #ex5

Exam0110 -> 예외 처리 전 //

Exam0120 -> 예외처리 // RuntimeException의 경우에 예외처리 하지 않아도 된다.

                  // 하지만 개발자의 편의를 위해, RuntimeException도 예외처리를 해주자.

                  // } catch (RuntimeException e) { e.printStackTrace(); }

                  // printStackTrace()은 예외처리가 난 이유를 Println해주는 메서드이다.

Exam0130 -> Exam0120의 단점 // RuntimeException라고 선언하면 직관적이지 않다.

                  // public class BoardException extends RuntimeException {

                  // RuntimeException을 상속받고 그대로 RuntimeException을 구현하는 예외처리 클래스를 만들자.

                  // static Board read() throws BoardException { // BoardException class를 따로 만듦으로써 직관적이다.

 

generic

generic #ex01

 

 

httpcomponents

httpcomponents 

Exam0110 client -> ApacheHttpClient 라이브러리 사용 // 

        // mvnmvnrepository.com 또는 search.maven.org 접속 - 'httpclient5' 검색

        // org.springframework:spring-context // 버전 클릭 // Gradle Groovy DSL 복사

        // - 라이브러리 정보를 dependencies {} 블록에 추가 - 'gradle cleanEclipse' - 'gradle eclipse'

        // CloseableHttpClient httpClient = HttpClients.createDefault(); // HTTP 요청을 수행할 객체를 준비

        // HttpGet get = new HttpGet("https://www.daum.net"); // HTTP GET 요청 정보를 준비

        // CloseableHttpResponse response = httpClient.execute(get); //  HttpClient 객체를 사용하여 GET 요청을 실행

        //  리턴 값은 웹 서버의 응답 데이터를 다루는 도구

        //  HttpEntity entity = response.getEntity(); // 응답 도구를 이용하여 서버가 보낸 데이터를 꺼낸다.

Exam0120 client -> 도우미 클래스 사용 // HttpEntity에서 응답데이터 꺼낼 때

        //  EntityUtils.toString(entity)

Exam0130 client -> try-with-resources 문법 적용

Exam0140 client -> 더 간결하게 HTTP 요청하기

 




httpcomponents #server

Exam0110 ->

 

io

io #ex1

Exam0110 -> 폴더 정보 확인

        // File class // 파일이나 디렉토리 정보를 관리 // 파일이나 디렉토리를 생성,삭제,변경

        // 현재 폴더 정보 조회 // "." 으로 경로를 표시

        // File class 메소드 //

        // getName() : 이름 // getPath() : 경로

        // getAbsolutePath() : 절대경로 // ex) C:\Users\heusw\git\bitcamp-study\bitcamp-java\.

        // getCanonicalPath() : 계산된 절대경로 // ex) C:\Users\heusw\git\bitcamp-study\bitcamp-java

        // getTotalSpace() : 총 크기 // getFreeSpace() : 남은크기 // getUsableSpace() : 가용크기

        // isDirectory() : 디렉토리 여부 // isFile() : 파일 여부 // isHidden() : 감춤여부

        // exists : 존재여부 // canExecute() : 실행가능 여부 // 

Exam0120 -> 상위 경로는 ".."으로 표시

Exam0130 -> 존재하지 않는 폴더

        // getTotalSpace, getFreeSpace, getUsableSpace는 존재하지 않은 폴더인 경우,

        // 크기를 알아낼 수 없어, 0으로 표시한다.

        // isDirectory, isFile, isHidden, exists, canExecute는 존재하지 않은 폴더인 경우,

        // 정보를 알아낼 수 없어, false로 표시된다.

Exam0210 -> 파일 정보 확인 // Exam0110과 동일

Exam0220 -> 존재하지 않는 파일 // Exam0130과 동일

Exam0310 - > 디렉토리 생성

File dir = new File("temp");
dir.mkdir();

          // File에 경로를 넘겨주고, mkdir()을 호출한다. // 경로를 지정하지 않으면 현재 폴더에 생성된다.

Exam0320 -> 하위 디렉토리 생성

File dir = new File("temp/a");
dir.mkdir();

          // File에 경로&하위폴더명을 넘겨주고 mkdir()을 호출한다,

Exam0321 -> 하위 디렉토리 생성 // 없는 경로 전달

          // mkdir() // mkdir()은 없는 경로를 전달하면 하위 디렉토리를 생성할 수 없다.

Exam0322 -> 하위 디렉토리 생성 // 없는 경로 전달

           // mkdirs() // mkdirs는 없는 경로를 전달하면, 경로 생성 후, 하위 디렉토리를 생성한다,

Exam0330 -> 디렉토리 삭제

File dir = new File("temp");
dir.delete();

          // File에 경로&하위폴더명을 넘겨주고 delete()를 호출한다,

Exam0410 -> 파일 생성

File file = new File("temp2/a/test.txt");
file.createNewFile();

          // File에 경로&파일명을 넘겨주고 createNewFile()를 호출한다, // 이미 파일이 존재한다면 다시 생성할 수 없다.

 

Exam0411 -> 파일 생성 // 없는 경로 전달

          // createNewFile() // createNewFile는 없는 경로를 전달하면, 파일을 생성할 수 없다.

Exam0420 -> 파일 삭제

File file = new File("temp2/a/test.txt");
file.delete();

          // File에 경로&파일명을 넘겨주고 delete()를 호출한다,

Exam0430 -> 안봐도 됨

Exam0431 -> 없는 경로의 파일 생성법 // mkdirs 호출 경로 생성 후, createNewFile() 호출

Exam0510 -> 현재 폴더의 정보 확인

    File dir = new File(".");
    String[] names = dir.list();

          // File dir = new File(".");  // 현재 파일의 정보를 알아낸다.

          // list() // 넘겨준 경로의 파일이나 하위 디렉토리의 이름 정보를 String으로 가져온다.

Exam0510 -> 현재 폴더의 정보 확인

    File dir = new File(".");
    File[] files = dir.listFiles();

           // listFiles() // 넘겨준 경로의 파일이나 하위 디렉토리의 정보를 File 객체로 가져온다.

Exam0610 -> File 필터 적용 // Exam0611을 확인하자

Exam0611 -> Filename 필터 적용 

    class JavaFilter implements FilenameFilter {
      @Override
      public boolean accept(File dir, String name) {
        File file = new File(dir, name);
        if (file.isFile() && name.endsWith(".java"))
          return true;
        return false;
      }
    }

            // 인터페이스 FilenameFilter 구현할 class에서 accept를 오버라이딩 한다.

 

            // 오버라이딩 하여 원하는 필터 결과를 리턴할 수 있도록 한다.

    File dir = new File(".");
    JavaFilter javaFilter = new JavaFilter();
    String[] names = dir.list(javaFilter);

 

            // File을 호출할 때, javaFilter를 넘겨주어 원하는 결과만 리턴 받는다.

            // list를 호출하기 때문에 FilenameFilter를 설정한다.

Exam0620 -> File 필터 적용 

    class JavaFilter implements FileFilter {
      @Override
      public boolean accept(File file) {
        if (file.isFile() && file.getName().endsWith(".java"))
          return true;
        return false;
      }
    }

            // 인터페이스 FileFilter 구현할 class에서 accept를 오버라이딩 한다.

    File dir = new File(".");
    JavaFilter javaFilter = new JavaFilter();
    File[] files = dir.listFiles(javaFilter);

            // File을 호출할 때, javaFilter를 넘겨주어 원하는 결과만 리턴 받는다.

            // listFiles를 호출하기 때문에 FileFilter를 설정한다.

 

반응형

+ Recent posts