JAVA 심화

강호수·2022년 9월 15일
0

Annotation

  • 컴파일러에게 문법 에러를 체크하도록 정보를 제공한다
  • 프로그램을 빌드할 때 코드를 자동 생성할 수 있도록 정보를 제공한다
  • 런타임에 특정 기능을 실행하도록 정보를 제공한다

표준 Annotation

@Overide
-> 상위 클래스의 메서드를 오버라이딩한다는 것을 컴파일러에게 알려줌 (오류 잡아줌)
@Deprecated
-> 새로운 것으로 대체되었으니 기존의 것 사용 안하길 권장할 때
@SuppressWarnings
-> 컴파일 경고 메세지가 나타나지 않도록 함
@FunctionallInterface
-> 함수형 인터페이스의 선언이 바르게 되어있는지 확인

메타 Annotation

  • Annotation을 위한 Annotation -> Annotation을 정의하는데에 사용된다

@Target
-> Annotaion 적용할 대상을 지정
@Documented
-> annotaion의 정보가 javadoc으로 작성한 문서에 포함되도록 함
@Inherited
-> 하위 클래스가 Annotaion을 상속받도록 함
@Retention
-> Annotation의 지속 시간을 결정함
@Repeatable
-> Annotaion을 여러 번 붙일 수 있도록 허용

사용자 정의 Annotation

@Target(~~)
@Documented(~~)
@interface Annotation_ex {
	타입 요소명();
}

위와 같이 메타 Annotation들을 이용하고, @interface를 쓰면서 사용자 정의 Annotation을 만들 수 있다.

Lambda

int sum(int num1, int num2){
	return num1 + num2;
}

(int num1, int num2) -> {
	num1 + num2
}

(int num1, int num2) -> num1 + num2

(num1, num2) -> num1 + num2

위의 4가지는 모두 같은 Lambda식이다.

함수형 인터페이스

public class LambdaEx {
	public static void main(String[] args) {
    	ExFucntion exFunction = (num1, num2) -> num1 + num2;
        int a = exFunction.sum(10,15);
    }
}

interface ExFunction {
	public abstract int sum(int num1, int num2);
}

위와 같이 참조변수 타입으로 함수형 인터페이스를 사용하여 원하는 메서드에 접근이 가능하다.

~~
	example = () -> {
    	System.out.println("호출!")'
    };
    example.accept();
}

매개변수와 리턴값이 없다면 위와 같이 출력이 가능하다.

메서드 레퍼런스

public class Calculator {
	public int add(int x, int y){
    	return x+y;
    }
}

public class ~~ {
	psvm {
    	IntBinaryOperator operator = Calculator::add;
        sout(operator.applyAsInt(3,5));
    }
}

정적 메서드를 참조할 경우에는 위와 같이 클래스명 :: 메서드의 형태로 쓰면 되고, 인스턴스 메서드의 경우에는 객체를 생성한 뒤 위와 같은 형태로 쓰면 된다.

Stream

스트림은 내부 반복자를 사용하게 된다. 이를 사용할 때에 이점은 어떻게 요소를 반복시킬 것인가는 컬렉션에게 맡겨두고, 개발자는 요소 처리 코드에만 집중할 수 있다는 것이다. 그리고 멀티 코어 CPU를 최대한 활용하기 위해 요소들을 분배시켜 병렬 작업을 할 수 있게 도와준다.

스트림 생성

Stream<String> = list.stream();
Stream<String> = Stream.of("a","b","c");
Stream<String> = Stream.of(new String[] {"a","b","c"});
Stream<String> = Arrays.stream(new String[] {"a","b","c"});
IntStream stream = IntStream.range(4,10) // 4~9

중간 연산

list.stream()
	.distinct() //중복 제거
    .filter(n -> n != 1) //람다식 이용한 중복 제거
	. ~~
list.stream()
	.map(s -> s.toUpperCase()) //기존 Stream 요소들 대체하는 Stream 형성
    . ~~
list.stream()
	.sorted(Comparator.reverseOrder) //기존 오름차순, reverseOrder 작성하면 내림차순
	. ~~
list.stream()
	.peek(n -> sout(n)) //요소 하나씩 돌면서 출력하지만 중간 연산자
    . ~~

최종 연산

list.stream()
	. ~~
    .forEach(n -> sout(n));
list.stream()
	. ~~ 
    .allMatch(a -> a%2 == 0); // boolean값 반환
list.stream()
	. ~~ 
    .sum(); //count, average, max, min 등이 있다.
list.stream()
	. ~~
    .collect(Collectors.toList()); //List 형태로 수집
list.stream()
	. ~~
    .collect(Collectors.toCollection(HashSet :: new));

Input / Output

~~

Thread

  • 실행 중인 애플리케이션을 의미한다
  • 하나의 코드 실행 흐름이라 볼 수 있다

스레드의 생성과 실행

public class ThreadExample {
	psvm{
    	Runnable task1 = new ThreadTask1();
        Thread thread1 = new Thread(task1);
        thread1.start();
        
        ThreadTask2 thread2 = new ThreadTask2();
        thread2.start();
	}
}

class Threadtask1 implements Runnable {
	public void run(){
    	~~
	}
}

class Threadtask2 extends Thread {
	public void run(){
    	~~
	}
}
  1. Runnable 인터페이스를 구현한 객체에서 스레드를 생성하고 실행 (thread1)
  2. Thread를 상송 받은 하위 클래스에서 스레드를 생성하고 실행 (thread2)
Thread thread1 = new Thread(new Runnable() {
	public void run() {
    	~~
    }
});

Thread thread2 = new Thread() {
	public void run() {
    	~~
	}
}

위의 방법들로 익명 객체를 이용한 스레드 생성 및 실행을 할 수도 있다.

스레드 동기화

main문에서 Thread를 2개 생성한 뒤 thread.start()를 각각 입력한다고 하자. 그렇게 되면 두 스레드가 동시에 실행 되는데, 이 때 두개의 작업 스레드가 생성되고 이것은 같은 객체를 공유하게 된다. 이때 그 안에 연산이 들어가 있다면 오류가 생길 수도 있다. 따라서 두 개의 스레드가 동시에 실행하면 안 되는 영역을 설정해 그러한 오류를 막아야 한다.

class Account {
	~~
    public synchronized boolean withdraw(int money) {
    	~~
	}
}

class Account {
	~~
    public boolean withdraw(int money) {
    	synchronized (this) {
        	~~
		}
    }
}
  1. 메서드 전체를 임계 영역으로 지정
  2. 특정한 영역을 임계 영역으로 지정

위와 같은 두가지의 방법으로 임계 영역을 지정하여 스레드의 동기화를 이뤄낼 수 있다. 이렇게 할 시에 같은 객체를 공유하는 경우 두 개의 스레드가 동시에 실행되지 않아 오류가 생기지 않게 된다.

JVM

  • 자바로 작성한 소스 코드를 해석해 실행하는 별도의 프로그램
  • Windows, Linux, Mac OS 용 JVM이 각각 따로 존재한다.

0개의 댓글