본문 바로가기
Java/이것이 자바다

Java 기본 개념

by k-mozzi 2023. 9. 13.
반응형
Preface

 

자주 까먹고 헷갈리는 개념들만 보기 쉽게 따로 정리해둔다.


 

- 자바는 클래스 다중 상속을 지원하지 않는다.

→ 인터페이스는 다중 상속이 가능하다.

 

 

 

- 부모 클래스에 기본 생성자가 없고 매개 변수가 있는 생성자만 존재한다면 자식 생성자에서 반드시 부모 생성자 호출을 위해 super(매개값, ...)를 명시적으로 호출해야 한다.

1) super(매개값, ...)는 반드시 자식 생성자 첫 줄에 위치해야 한다.

2) 자식 클래스 내부에서 오버라이딩 된 부모 클래스의 메소드를 호출해야 한다면 명시적으로 super 키워드를 붙여 부모 메소드를 호출할 수 있다.

 

 

 

- final 키워드

1) 클래스: 상속할 수 없는 클래스가 된다.

2) 필드: 상수가 된다.

3) 메서드: 오버라이딩할 수 없는 메서드가 된다.

 

 

 

- 클래스 타입 변환: 상속 관계에 있는 클래스 사이에서 발생

1) 자식 타입은 부모 타입으로 자동 타입 변환(Promotion)이 가능하다.

→ 바로 위의 부모가 아니더라도 상속 계층에서 상위 타입이라면 자동 타입 변환이 일어날 수 있다.

2) 부모 타입으로 자동 타입 변환된 후에는 부모 클래스에 선언된 필드와 메소드만 접근이 가능하다.

→ 단, 메소드가 자식 클래스에서 오버라이딩 되엇다면 자식 클래스의 메소드가 대신 호출된다.

3) 매개 변수의 타입이 클래스일 경우, 해당 클래스의 객체뿐만 아니라 자식 객체까지도 매개값으로 사용할 수 있다.

4) 강제 타입 변환(Casting): 부모 타입을 자식 타입으로 변환하는 것

→ 자식 타입이 부모 타입으로 자동 변환된 후, 다시 자식 타입으로 변환하는 경우에만 강제 타입 변환을 사용할 수 있다.

 

 

 

- 추상 클래스(abstract)의 특징

1) new 연산자를 이용해 객체를 생성할 순 없고, 상속을 통해 자식 클래스만 만들 수 있다.

2) new 연산자로 직접 생성자를 호출할 수는 없지만, 자식 객체가 생성될 때 super(...)를 호출해서 추상 클래스 객체를 생성하므로 반드시 생성자가 있어야 한다.

3) 추상 메서드는 하위 클래스에서의 오버라이딩을 강제한다.

 

 

 

- 인터페이스의 구성 멤버

1) 상수 필드(constant field): 인터페이스에 고정된 값으로 반드시 초기값을 대입해야 한다.

2) 추상 메소드(abstract method): 객체가 가지고 있는 메소드를 설명한 것으로, 실제 실행부는 구현 객체가 지닌다.

3) 디폴트 메소드(default method): 인터페이스 내부에서 메서드의 기본 구현을 제공하므로 구현 클래스에서 오버라이딩이 강제되지 않는다.

기존의 인터페이스를 확장해서 이전의 구현 클래스의 코드 변화 없이 새로운 기능을 추가하기 위해 사용된다.

4) 정적 메소드(static method): 디폴트 메소드와 달리 객체 없이 인터페이스만으로 호출이 가능한 메소드이다.

 

 

 

- 익명(anonymous) 객체

1) 이름이 없으므로 변수에 할당되지 않고, 생성과 동시에 사용된다.

2) 주로 한 번만 사용되는 객체로, 특정 작업을 수행하기 위해 생성된 뒤 가비지 컬렉터에 의해 수집된다.

3) 단독으로 생성할 수 없고 클래스를 상속하거나 인터페이스를 구현해야 생성할 수 있다.

→ 주로 익명 클래스와 연계된다.

4) 필드의 초기값이나 로컬 변수의 초기값, 매개 변수의 매개값으로 주로 사용된다.

5) 익명 객체 내부에서 사용된 매개 변수와 로컬 변수는 모두 final 특성을 갖는다.

interface RemoteControl {
	public void turnOn();

	public void turnOff();
}

class Anonymous2 {
	RemoteControl field = new RemoteControl() {
		@Override
		public void turnOn() {
			System.out.println("turn on the tv");
		}

		@Override
		public void turnOff() {
			System.out.println("turn off the tv");
		}
	};

	void method1() {
		RemoteControl localVar = new RemoteControl() {

			@Override
			public void turnOn() {
				System.out.println("turn on the Audio");
			}

			@Override
			public void turnOff() {
				System.out.println("turn off the Audio");
			}
		};

		localVar.turnOn();
	}

	void method2(RemoteControl rc) {
		rc.turnOn();
	}
}

 

 

 

- 자바 프로그램에서 자주 발생하는 예외

1) NullPointerException: 객체 참조가 없는 상태, 즉 null 값을 갖는 참조 변수로 객체 접근 연산자인 도트를 사용했을 때 발생하는 일반 예외

2) ArrayIndexOutOfBoundsException: 배열에서 인덱스 범위를 초과하여 사용할 경우 발생하는 실행 예외

3) NumberFormatException: 문자열을 숫자로 변환하는 메소드에서 숫자로 변환될 수 없는 문자가 포함되어있을 때 발생하는 일반 예외

4) ClassCastException: 억지로 타입 변환을 시도할 경우 발생하는 일반 예외

→ 캐스팅은 상위 클래스와 하위 클래스, 구현 클래스와 인터페이스 사이에서만 가능하며, 이를 확인하기 위해 instanceof 연산자를 사용하는 것이 좋다.

 

 

 

- 다중 catch 블록을 작성할 땐 상위 예외 클래스가 하위 예외 클래스보다 아래쪽에 위치해야 한다.

→ 상위 예외 클래스의 catch 블록이 위에 있다면, 하위 예외 클래스의 catch 블록은 실행되지 않는다.

 

 

 

- 멀티(multi) catch 기능: 하나의 catch 블록에서 여러 개의 예외를 처리할 수 있는 기능

→ catch 괄호 안에 동일하게 처리하고 싶은 예외를 '|'로 연결하면 된다.

catch(ArrayIndexOutOfBoundsException | NumberFormatException e) {
	예외 처리
}

 

 

 

- throws 키워드: 메소드 선언부 끝에 작성되어 메소드에서 처리하지 않은 예외를 호출한 곳으로 떠넘기는 역할을 한다.

1) throws 키워드 뒤에는 떠넘길 예외 클래스를 쉼표로 구분해서 나열한다.

2) 발생할 수 있는 예외의 모든 종류를 나열하는 것이 일반적이지만, thorws Exception만으로 모든 예외를 떠넘길 수도 있다.

3) throws 키워드가 붙어있는 메소드는 반드시 try 블록 내에서 호출되어야 하며, catch 블록에서 떠넘겨 받은 예외를 처리해야 한다.

4) 예외를 넘겨 받은 곳에서 다시 예외를 떠넘길 수도 있다.

5) main 메소드에서 throws 키워드를 사용하여 JVM에게 예외를 떠넘기면 예외의 내용이 콘솔 창에 출력된다.

→ 바람직하지 않은 처리 방법이다.

 

 

 

- 애플리케이션 예외(사용자 정의 예외): 애플리케이션 서비스와 관련된 예외

1) 일반 예외로 선언할 경우 Exception을 상속한다.

2) 실행 예외로 선언할 경우 RuntimeException을 상속한다.

3) 예외 클래스 이름은 Exception으로 끝나는 것이 좋다.

4) 대부분 생성자 선언만을 포함한다.

→ 보통 매개 변수가 없는 기본 생성자와, 예외 발생 원인(예외 메시지)을 전달하기 위해 String 타입의 매개 변수를 갖는 생성자 두 개를 생성하며, 후자는 상위 클래스의 생성자를 호출(super)하여 예외 메시지를 넘겨준다.

public class XXXException extends [Exception | RuntimeException] {
	public XXXException() { }
    public XXXException(String message) { super(message); }
}

 

 

 

- 예외를 발생시키는 방법: if문으로도 예외를 처리할 수 있지만, 관리의 편의성을 위해 예외 클래스를 사용한다.

→ 예외를 발생시킬 때 String 타입의 메시지를 갖는 생성자를 이용하면 메시지는 자동적으로 예외 객체 내부에 저장된다.

throws new XXXException();
throws new XXXException("메시지");

 

 

 

- 모든 예외 객체는 Exception 클래스를 상속하므로 Exception이 가지고 있는 메소드를 모든 예외 객체에서 호출할 수 있다.

1) getMessage( ): catch 블록에서 예외 메시지를 얻는 메소드

2) printStackTrace( ): 예외 발생 코드를 추적해서 모두 콘솔에 출력하는 메소드

try {
	예외 발생 문장
} catch(예외클래스 e) {
	String message = e.getMessage();
    e.printStackTrace();
}

 

 

 

- 자바에서는 작업 스레드도 객체로 생성되므로 클래스가 필요하다.

1) java.lang.Thread 클래스를 직접 객체화해서 생성: Runnable을 매개값으로 갖는 생성자를 호출해야 한다.

Thread thread = new Thread(new Runnable() {
	public void run() {
    	//스레드가 실행할 코드;
    }
});

2) Thread를 상속한 하위 클래스를 만들어 생성: Thread 클래스를 상속한 후 run 메소드를 재정의하여 스레드가 실행할 코드를 작성

Thread thread = new Thread)( {
	public void run() {
    	//스레드가 실행할 코드;
    }
};

 

 

 

- 자바에선 임계 영역 지정을 위해 동기화(syncronized) 메소드와 동기화 블록을 제공해 스레드가 객체 내부의 동기화 메소드 또는 동기화 블록에 들어가면 즉시 객체에 잠금을 걸어 다른 스레드가 임계 영역 코드를 실행하지 못하도록 한다.

1) 메소드 선언에 syncronized 키워드를 붙이면 된다. (인스턴스와 정적 메소드 어디든 가능)

public syncronized void method() {
	//단 하나의 스레드만 실행
};

2) 동기화 블록을 사용해 일부 내용만 임계 영역으로 만들 수도 있다.

public void method () {
	//여러 스레드가 실행 가능한 영역
    syncronized(공유객체: 공유 객체가 자기 자신이면 this를 넣을 수 있다.) {
    	//단 하나의 스레드만 실행
    }
    //여러 스레드가 실행 가능한 영역
}

 

 

 

- 데몬(daemon) 스레드: 주 스레드의 작업을 돕는 보조적인 역할을 수행하는 스레드

→ 주 스레드가 종료되면 데몬 스레드는 강제적으로 자동 종료된다.

 

 

 

- setDaemon(true) 메소드: 스레드를 데몬으로 만든다.

1) start( ) 메소드 호출 전에 호출해야 한다.

2) isDaemon( ) 메소드를 통해 데몬 스레드인지 아닌지 구별할 수 있다.

 

 

 

- 스레드 그룹: 관련된 스레드를 묶어서 관리할 목적으로 이용

→ 스레드는 반드시 하나의 스레드 그룹에 포함되는데, 명시적으로 스레드 그룹에 포함시키지 않으면 자신을 생성한 스레드와 같은 스레드 그룹에 속하게 된다.

 

 

 

- 스레드풀: 작업 처리에 사용되는 스레드를 제한된 개수만큼 정해 놓고 작업 큐(Queue)에 들어오는 작업들을 하나씩 스레드가 맡아 처리한다.

→ 작업 처리가 끝난 스레드는 다시 작업 큐에서 새로운 작업을 가져와 처리한다.

 

 

 

- 콜백(callback): 애플리케이션이 스레드에게 작업 처리를 요청한 후 스레드가 작업을 완료하면 특정 메소드를 실행하는 것

1) 콜백 메소드: 자동 실행되는 메소드

2) 콜백 방식은 작업 처리를 요청한 후 결과를 기다릴 필요 없이 다른 기능을 수행할 수 있다.

3) Runnable 구현 클래스를 작성할 때 콜백 기능을 구현할 수 있다.

→ java.nio.channels.CompletionHandler를 이용

4) CompletionHandler에는 작업을 정상 처리 완료했을 때 호출되는 completed( )와 작업 처리 도중 예외가 발생했을 때 호출되는 Failed( ) 메소드가 있다.

5) CompletionHandler의 V 타입 파라미터는 결과값의 타입, A는 첨부값의 타입이다.

→ 첨부값: 콜백 메소드에 결과값 이외에 추가적으로 전달되는 객체(필요 없다면 Void로 지정)

 

 

 

- 제네릭: 클래스, 인터페이스, 메소드를 정의할 때 타입을 파라미터(parameter)로 사용할 수 있게 한다.

→ 타입 파라미터: 코드 작성 시 구체적인 타입으로 대체되어 다양한 코드를 생성하도록 한다.

 

 

 

- 제네릭 타입: 타입을 파라미터로 가지는 클래스와 인터페이스

1) 클래스와 인터페이스 이름 뒤에 "< >" 부호가 붙고, 사이에 타입 파라미터가 위치한다.

2) 타입 파라미터는 일반적으로 대문자 알파벳 한 글자로 표현한다.

3) 제네릭 타입을 실제 코드에서 사용하려면 타입 파라미터에 구체적인 타입을 지정해야 한다.

4) 제네릭 타입은 두 개 이상의 멀티 타입 파라미터를 사용할 수 있다.

→ 각각의 타입 파라미터는 콤마로 구분한다.

5) 자식 제네릭 타입은 추가적으로 타입 파라미터를 가질 수 있다.

class Box<T> {
	private T t;

	public T get() {
		return t;
	}

	public void set(T t) {
		this.t = t;
	}
}

public class BoxExample {

	public static void main(String[] args) {

		Box<String> box1 = new Box<String>();
		box1.set("Hi");
		String str = box1.get();
		System.out.println(str);

		Box<Integer> box2 = new Box<>();
        	//다이아몬드 연산자를 통해 타입 파라미터 값을 생략할 수 있다.
		box2.set(2);
		int value = box2.get();
		System.out.println(value);
	}

}

 

 

 

- 제네릭 메소드: 매개 타입과 리턴 타입으로 타입 파라미터를 갖는 메소드

public <타입파라미터> 리턴타입 메소드명(매개변수) {...}

public <T> Box<T> boxing(T t) {...}

 

 

 

- 제한된 타입 파라미터 선언: 타입 파라미터 뒤에 extends 키워드를 붙이고 상위 타입을 명시

1) 상위 타입이거나 상위 타입의 하위 또는 구현 클래스만 가능

2) 메소드의 중괄호 안에서 타입 파라미터 변수로 사용 가능한 것은 상위 타입의 멤버로 제한

3) 하위 타입에만 있는 필드와 메소드는 사용 불가

public <T extends 상위타입> 리턴타입 메소드(매개변수) {...}

 

 

 

- 제네릭 타입을 매개값이나 리턴 타입으로 사용할 때 구체적인 타입 대신 와일드카드를 사용할 수 있다.

1) 제네릭타입<?>: 모든 클래스나 인터페이스 타입이 올 수 있다.

2) 제네릭타입<? extends 상위타입>: 상위 타입이나 하위 타입만 올 수 있다.

→ 자신의 타입 + 자신의 하위 타입

3) 제네릭타입<? super 하위타입>: 하위 타입이나 상위 타입이 올 수 있다.

→ 자신의 타입 + 자신의 상위 타입

 

 

 

- 타입 파라미터로 배열 생성: (T[ ]) (new Object[n]) 방식을 사용해야 한다.

→ new T[n] 형태로 배열 생성 불가

 

 

 

※ 람다식 이후의 글부턴 내용이 너무 많아 업로드한 글을 따로 보며 공부하는 것이 좋을 것 같다.

카테고리 링크

 

'Java/이것이 자바다' 카테고리의 글 목록

개발 준비 과정

k-mozzi.tistory.com

 

 

728x90
반응형

'Java > 이것이 자바다' 카테고리의 다른 글

(Fin) NIO 기반 입출력 및 네트워킹  (0) 2023.05.23
네트워킹  (0) 2023.05.12
IO 기반 입출력  (0) 2023.05.12
이자바 16장(스트림과 병렬 처리) 확인문제  (0) 2023.05.07
스트림과 병렬 처리  (0) 2023.05.07

댓글