예외 처리 (Handling Exceptions)

오류와 예외

  • 프로그램이 동작 중에 비정상 종료가 발생하는 상황
  • 심각도에 따라 오류와 예외로 분류할 수 있음

오류 (Errors)

  • 시스템의 메모리가 부족하거나, 무한히 메소드 호출이 발생하는 등 프로그램 복구가 불가능한 상황
  • 오류가 발생하는 원인을 찾아서 제거하는 방법으로 해결

예외 (Exceptions)

  • 오류에 비해 심각도가 낮으며, 프로그램의 정상적인 흐름을 방해
    ex) 파일명으로 파일을 읽으려 하는데, 파일을 찾을 수 없음
  • 문제 상황을 해결하는 로직을 별도로 구성하여 해결 가능

예외 처리

  • 예외가 발생했을 때, 이 상황을 감지하고 해결하기 위해 동작하는 코드
  • try ~ catch 구문과 Exception 클래스와 그 자식 클래스를 활용

Throwable 클래스

  • Throwable 클래스는 Exception과 Error 클래스에 의해 상속
    • Exception
      • Checked Exceptions: 예외 처리되지 않으면 컴파일이 되지 않는 예외 - Exception Class 상속
      • Unchecked Exception: 예외 처리되지 않아도 컴파일이 되는 예외 - RuntimeException Class 상속
    • Error: 프로그램이 복구 불가능한 상황

Exception 클래스

  • Throwable 클래스의 주요 메소드

    메소드 설명
    public String getMessage() 발생한 예외에 대한 메세지를 반환
    public String getLocalizedMessage() 오버라이드하여 추가 메세지 제공 (오버라이드하지 않으면 getMessage()와 동일)
    public Throwable getCause() 예외의 원인이 되는 Throwable 객체 반환
    public void printStackTrace() 예외가 발생된 메소드가 호출될 때의 Method call stack을 출력

예외 처리 기법

try ~ catch 구문

1
2
3
4
5
6
7
try {
// 예외가 발생할 수 있는 코드 영역
// 예외 발생 시 예외 객체를 던짐 (throw)
} catch (Exception e) { // 던져진 예외를 받음 (catch)
// Exception의 자식 클래스로 지정하여 특정 클래스를 받는다.
// 예외 상황을 처리하는 코드
}

다중 예외 처리

  • 여러 개의 catch 구문을 사용하면 다중 예외를 처리할 수 있음

  • if ~ else if 구문처럼, 순차적으로 검사하면서 적용 가능한 예외를 처리

  • 다형성이 적용되어, 자식 예외를 처리 가능

  • 한가지의 catch 문에 대해서 예외가 잡힘

  • 상위 Exception을 제일 밑의 catch문에 배치

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    try {
    // 예외 발생 가능 코드 영역
    } catch (AException e) {
    // A예외 처리
    } catch (BException e) {
    // B예외 처리
    } catch (CException e) {
    // C예외 처리
    } catch (Exception e) {
    // 나머지 모든 예외 처리
    }

try ~ catch ~ finally 구문

  • try 구문 실행 중에 어떤 일이 발생해도 반드시 실행되어야 하는 구문은 finally 블록에 작성

  • try 구문 내에 return문이 있는 경우에도 finally 블록은 실행됨

  • try 구문 내에서 접근한 System 자원을 안전하게 복구하기 위해 사용

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    FileInputStream file = null;
    try {
    file = new FileInputStream(fileName);
    file.read();
    } catch (IOException e) {
    System.out.println("파일처리실패");
    } finally {
    if (file != null) {
    try {
    file.close();
    } catch (IOException e) {
    System.out.println("파일인풋스트림 종료 실패");
    }
    }
    }

try ~ with ~ resources 구문

  • Java1.7에서 추가된 기능

  • AutoClosable 인터페이스를 구현하는 리소스를 자동으로 close 처리

    1
    2
    3
    4
    5
    try (FileInputStream file = new FileInputStream(fileName)) {
    file.read();
    } catch (IOException e) {
    System.out.println("파일처리실패");
    }

예외 처리 위임

throws

  • 호출한 메소드로 예외 처리를 전달하는 방식

  • Checked Exception의 경우 throws로 위임 가능하나, 최종적으로 try ~ catch를 만나야 함

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    class CheckedException {
    void methodA() throws ClassNotFoundException {
    Class.forname("A Class");
    }

    void methodB() {
    try {
    methodA();
    } catch (ClassNotFoundException e) {
    ...
    }
    }
    }
  • Unchecked Exception의 경우 throws로 위임하지 않아도 자동으로 전달

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    class UncheckedException {
    void methodA() {
    int x = 10;
    x = 10/0;
    }
    void methodB() {
    try {
    methodA();
    } catch (ArithmeticException e) {
    ...
    }
    }
    }
  • 메소드를 오버라이드한 경우, 조상 클래스의 메소드보다 조상 예외는 던질 수 없음

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    class Foo {
    void methodA() throws IOException {}
    }

    class BarOne extends Foo{
    void methodA() throws IOException {} // possible
    }

    class BarTwo extends Foo{
    void methodA() throws FileNotFoundException {} // possible
    }

    class BarThree extends Foo{
    void methodA() throws Exception {} // *NOT* possible
    }

throw

  • 예외를 발생시키는 키워드

  • new 키워드로 새 Exception 객체를 생성하여 예외 내용을 작성

    1
    2
    3
    4
    5
    6
    7
    void exceptMethod() throws Exception {
    ...
    if (Err) {
    throw new Exception("Some Error"); // 예외 발생 및 Message 전달
    }
    ...
    }

사용자 정의 예외 (Custom Exceptions)

  • Exception 또는 RuntimeException 클래스를 상속하여 작성

    • Exception을 상속한경우 Checked Exception이 되어 반드시 예외를 처리해야 한다.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    class MyException extends RuntimeException {
    enum ErrorCode {
    ERROR_A, ERROR_B;
    }

    private ErrorCode errorCode;

    public MyException(ErrorCode errorCode, String message) {
    super(message);
    this.errorCode = errorCode;
    }

    @Override
    public String getLocalizedMessage() {
    String message = getMessage();
    ...
    return localizedMessage;
    }
    }

Comment and share

클래스 다이어그램

Class Diagram

  • 클래스의 구성요소 및 클래스 간의 관계를 묘사하는 다이어그램
  • 시간에 따라 변하지 않는 정적인 시스템 구조를 표현

클래스 다이어그램의 목적

  • 문제 해결을 위한 도메인 구조를 표현

Unified Modeling Language (UML)

  • 표준화된 모델링 표기 체계
  • 클래스를 구현하기 전에 설계하는 단계에서 사용
    • 클래스 이름, 파라미터, 리턴 타입 등

IDEA에서 UML 작성하기 (Plant UML)

  • Plant UML 플러그인 설치

  • Graphviz 설치 https://graphviz.org/download/

  • Plant UML의 문법

    • 클래스, 추상클래스, 인터페이스

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      interface IFoo {
      void method();
      }

      abstract class Bar

      class Foo {
      int [] array;
      int add(int x, int y);
      setArray(int [] array);
      void method();
      }
    • 가시성 (Visibility)

      • public : +
      • protected : #
      • default : ~
      • private : -
    • 클래스 간의 관계

      • Extension <|-
      • Aggregation o--
      • Composition *--
    • 타이틀

      1
      title 클래스 다이어그램 제목
    • 노트

      1
      2
      3
      note left of Foo
      노트 <b>내용</b> 작성
      end note

IDEA에서 UML 자동 생성

https://www.jetbrains.com/help/idea/class-diagram.html

Comment and share

Wrapper 클래스 (Wrapper Class)

Wrapper 클래스란

  • 기본형 타입을 객체로 사용하기 위한 클래스

Wrapper 클래스의 종류

기본형 Wrapper 클래스
byte Byte
char Character
short Short
int Integer
long Long
float Float
double Double
boolean Boolean

Wrapper 객체 생성

  • 생성자를 이용한 객체 생성

    1
    Integer integer = new Integer(10);
  • valueOf를 이용한 객체 생성

    1
    Integer integer = Integer.valueOf(10);

Autoboxing & Unboxing

  • 오토박싱 (Autoboxing)

    • Java1.5부터 추가된 기능으로, 객체로 다루어야 할 때 자동으로 Wrapper 클래스로 변경하는 기능
  • 언박싱 (Unboxing)

    • Wrapper 객체를 기본형으로 자동으로 변경하는 기능
    1
    2
    3
    int i = 10;
    Integer wrapped = i;
    int b = 20 + wrapped;

Wrapper 타입의 값 비교

  • Wrapper 타입은 객체이므로, ==를 이용하여 값을 비교할 수 없다.

    1
    2
    3
    4
    5
    6
    Integer intOne = new Integer(100);
    Integer intTwo = new Integer(100);

    System.out.println(intOne == intTwo); // false
    System.out.println(intOne.equals(intTwo)) // true
    System.out.println(intOne == 100) // true (Unboxing)

문자열의 기본 자료형 변환

  • Parsing 정적 메소드를 이용한 변환

    1
    2
    int x = Integer.parseInt("100");
    long y = Long.parseLong("512345124");
  • Wrapper 객체로의 변환

    1
    2
    Integer intObj = Integer.valueOf("1000");
    Integer intObjTwo = new Integer("1234");

Comment and share

제네릭 (Generic)

제네릭이란

  • 대상 객체의 타입을 입력받아 사용할 수 있는 형식
  • 미리 사용할 수 있는 타입을 명시하여 컴파일 타임에 체크할 수 있음
    • 입력을 Object로 한 경우 런타임을 체크하기 위한 instanceof를 많이 사용해야 함
    • 제네릭을 사용할 경우 간결하게 코드를 작성할 수 있다.

제네릭 클래스

제네릭 타입

  • 클래스와 인터페이스에 제네릭이 적용된 타입

  • 클래스를 선언할 때에는 타입이 알려지지 않으며, 타입 파라미터를 사용

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public class GenericClass<T> { // T: 타입 파라미터
    ...
    }

    public interface GenericInterface<T> { // T: 타입 파라미터
    ...
    }

    public class HashMap<K,V> { // K, V: 타입 파라미터
    ...
    }
  • 제네릭 타입은 실제로 사용될 때 타입 파라미터에 자료형을 입력받는다.

    1
    2
    GenericClass<String> generic = new GenericClass<String>();
    GenericClass<String> generic2 = new GenericClass<>();

타입 파라미터 주의점

  • static 멤버 변수는 타입 파라미터를 사용할 수 없다.

  • 정적 메소드에도 타입 파라미터를 사용할 수 없다.

  • 이유 : 객체를 생성했을 때 타입 T가 결정되기 때문이다.

    1
    2
    3
    4
    public class Generic<T> {
    static T classVar; // not possible
    static void method(T localVar) {} // not possible
    }
  • new 키워드를 사용하여 객체 생성을 할 수 없다. - 안전성

    1
    2
    3
    public class Generic<T> {
    T var = new T(); // not possible
    }
  • instanceof의 피연산자로 사용할 수 없다. - 안전성

    1
    2
    3
    4
    5
    6
    7
    8
    public class Generic<T> {
    {
    Object obj = new Object();
    if(obj instanceof T) { // not possible
    ...
    }
    }
    }

제네릭 타입의 상속

  • 부모 클래스 또는 인터페이스에 선언한 타입 파라미터는 반드시 자식에서도 선언

  • 자식 클래스에서 추가적인 타입 파라미터 선언할 수 있다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class Foo<T> {
    ...
    }

    interface IBar<D> {
    ...
    }

    class FooBar<C, T, D> extends Foo<T> implements IBar<D> {
    ...
    }

파라미터 타입의 제한

  • extends를 이용하여 파라미터 타입을 제한할 수 있다.

    • 인터페이스의 경우에도 extends 키워드를 사용한다.
    • 클래스와 인터페이스를 동시에 제약하려면 &로 연결한다.
  • 제한한 자료형의 자식 클래스는 모두 사용할 수 있다.

    1
    2
    3
    4
    5
    6
    7
    class Generic<T extends Number> {
    ...
    }

    class Generic<T extends Number & Cloneable> {
    ...
    }

제네릭 메소드

메소드에 선언된 제네릭

  • 메소드의 리턴 타입 앞에 타입 파라미터 변수를 선언하여 사용

    1
    2
    3
    4
    5
    class GenericMethod {
    public <T> T method(T x) {
    return x;
    }
    }
  • 메소드에 선언된 제네릭은 정적 메소드에도 사용 가능

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    class GenericMethod<T> {
    public static void method(T t) { // Error
    ...
    }

    public static <P> P method (P p) { // Possible
    ...
    }

    public static <P, V> V methodA(P p){
    // Error : V Type Not Definition
    ...
    }
    }
  • 와일드카드

    • <?> => <? extends Object>와 동일
    • <? extends T> => 와일드카드의 상한을 제한, T 포함 상속 클래스
    • <? super T> => 와일드카드의 하한을 제한, T 포함 상위 클래스
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    class Foo {
    ...
    }

    class Bar extends Foo {
    ...
    }

    class Generic<T> {
    ...
    }

    class WildCard {
    public void method1(Generic<?> x) {}
    public void method2(Generic<? extends Foo> x) {}
    public void method3(Generic<? super Bar> x) {}
    }

Comment and share

열거형 (Enumeration)

열거형이란

  • 몇가지 한정된 상수로 표현될 수 있는 자료형을 구현
  • enum 키워드를 이용하며, 내부적으로는 java.lang.Enum 클래스를 상속

열거형의 특징

  • 접근 제한자는 publicdefault만 사용 가능
  • 다른 클래스를 상속받을 수 없으나, 인터페이스 구현은 가능
  • 열거형 타입에는 열거형 상수와 null 값을 할당할 수 있음

열거형의 구현

  • 일반적인 열거형의 구현

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    enum Job {
    STUDENT, MARKETING, DEVELOPER, CHIEF_EXECUTIONAL_OFFICER;
    }

    public class Main {
    public static void main(String[] args) {
    Job job = Job.STUDENT;

    if (job == Job.CHIEF_EXECUTIONAL_OFFICER) {
    System.out.println("사장님, 안녕하세요?");
    }

    switch (job) {
    case STUDENT: // case에서는 'Job.' 을 쓰지 않는다.
    System.out.println("You will be a great one.");
    break;
    case MARKETING:
    System.out.println("You make things sold.");
    break;
    case DEVELOPER:
    System.out.println("You usually don't go home.");
    break;
    case CHIEF_EXECUTIONAL_OFFICER:
    System.out.println("You choose your company's fate.");
    break;
    default:
    System.out.println("I don't recognize what you do.");
    }
    }
    }
  • 클래스 내부에서 열거형 구현

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public class Foo {
    enum MyEnum {
    ONE, TWO;
    }
    }

    public class Main {
    public static void main(String[] args) {
    System.out.println(Foo.MyEnum.ONE);
    }
    }
  • 열거형에 메소드 구현

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    enum Symbol {
    ONE, TWO, THREE, FOUR;

    public Symbol nextSymbol() {
    if(this.equals(ONE)) {
    return TWO;
    } else if(this.equals(TWO)) {
    return THREE;
    } else if(this.equals(THREE)) {
    return FOUR;
    } else {
    return ONE;
    }
    }
    }

    public class Main {
    public static void main(String[] args) {
    Symbol sym = Symbol.ONE; // ONE
    Symbol nextSym = sym.nextSymbol(); // TWO
    nextSym = nextSym.nextSymbol(); // THREE
    }
    }

  • 열거형 생성자를 이용한 enum 상수 초기화

    • 열거형의 생성자는 항상 private이며 생략 가능
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    enum Family {
    FATHER("아버지"), MOTHER("어머니"), SON("아들"), DAUGHTER("딸"); // 생성자 호출
    private String koreanWord;

    Family(String koreanWord) { // private 생성자
    this.koreanWord = koreanWord;
    }

    public String getKoreanWord() {
    return koreanWord;
    }

    public void setKoreanWord(String koreanWord) {
    this.koreanWord = koreanWord;
    }
    }

    public class Main {
    public static void main(String[] args) {
    Family fam = Family.SON;
    System.out.println(fam.koreanWord) // 아들
    }
    }

Comment and share

인터페이스 (Interface)

인터페이스란

  • 클래스를 사용하는 방식, 접점만을 선언하는 클래스와 유사한 틀
  • 아무런 구현이 되어 있지 않으며, 모든 메소드가 추상 메소드

인터페이스의 특징

  • class가 아닌 interface 키워드로 선언

    • public 또는 default 접근 제어자만 사용 가능
  • 멤버 변수는 항상 public static final이며, 생략 가능

  • 멤버 메소드는 항상 public abstract이며, 생략 가능

  • 클래스와 달리 인터페이스는 여러 개 상속받을 수 있다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    public interface IFoo {
    public static final int MEMBER_VAR = 10;
    int MEMBER_VAR2 = 20; // public static final

    public abstract void methodA(int param);
    void methodB(int param); // public abstract
    }

    public class Foo implements IFoo {
    @Override
    void methodA(int param) {
    System.out.println(param);
    }

    @Override
    void methodB(int param) {
    System.out.println(param);
    }
    }

인터페이스간의 상속

  • 인터페이스 간의 ‘IS-A’ 관계

  • 인터페이스가 인터페이스를 상속할 경우 extends로 상속

  • 클래스-클래스와 달리 다중 상속 가능

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    interface Walkable {
    void walk();
    }

    interface Runnable {
    void run();
    }

    public interface Jumpable extends Walkable, Runnable {
    void jump();
    }

    public class Jumper implements Jumpable {
    @Override
    void walk() {
    System.out.println("walk");
    }

    @Override
    void run() {
    System.out.println("run");
    }

    @Override
    void jump() {
    System.out.println("jump");
    }
    }

JDK 1.8

  • 기본 메소드 (Default method): 자식 클래스에서 구현할 필요가 없는 메소드

    • 인터페이스에 default 메소드를 구현할 수 있다.
    • default 메소드는 항상 public이다.
    • 인터페이스의 철학과 맞지 않으나, 인터페이스가 개선되었을 때 손쉽게 기능 추가를 위해 만들어짐
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    interface IFoo {
    void abstractMethod();

    default void defaultMethod() { // 구현 클래스에서 구현할 필요가 없다.
    System.out.println("Default method");
    }
    }

    class SuperFoo {
    void defaultMethod() {
    System.out.println("Super method");
    }
    }

    class FooOne implements IFoo {
    void abstractMethod() {
    return;
    }
    }

    class FooTwo extends SuperFoo implements IFoo {
    void abstractMethod() {
    return;
    }
    }

    public class Main {
    public static void main(String[] args) {
    FooOne fooOne = new FooOne();
    fooOne.defaultMethod(); // Default method

    FooTwo fooTwo = new FooTwo();
    fooTwo.defaultMethod(); // Super method
    }
    }
  • static 메소드: 클래스 메소드와 동일하게 사용 가능

    • 인터페이스 이름으로 호출 가능
    • 클래스 구현체의 이름으로도 호출 가능
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    interface IFoo {
    static void staticMethod() {
    System.out.println("static method");
    }
    }

    public class Main {
    public static void main(String[] args) {
    IFoo.staticMethod(); // static method
    }
    }

Comment and share

추상 클래스 (Abstract Class)

추상 클래스란

  • 일부 메소드가 구현되지 않고 선언만 되어 있는 클래스
    • 자식 클래스에서 반드시 구현해야 하는 메소드를 abstract로 선언
    • 필요한 모든 클래스가 구현될 수 있도록 강제

추상 클래스의 선언

  • abstract 키워드를 이용해 클래스를 선언

  • abstract 키워드를 이용해 메소드를 선언

    1
    2
    3
    4
    5
    6
    7
    abstract class AbstractFoo {
    public void method() {
    return;
    }

    public abstract void abstractMethod();
    }

Comment and share

OOP-7(Polymorphism)

in Java, OOP

다형성 (Polymorphism)

다형성의 다양한 특징

  • 부모 클래스 타입으로 자식 클래스 객체를 참조하는 특징

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    public class Foo {
    public void methodA() {
    return;
    }
    }

    public class Bar extends Foo {
    public void methodB() {
    return;
    }
    }

    public class Main {
    public static void main(String args[]) {
    Bar bar = new Bar();

    Foo foo = (Foo)bar;
    }
    }
  • 부모 클래스로 자식 클래스를 참조한 경우, 자식 클래스의 메소드는 사용할 수 없다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    public class Main {
    public static void main(String args[]) {
    Bar bar = new Bar();
    Foo foo = (Foo)bar;

    foo.methodA(); // works
    // foo.methodB(); // error
    }
    }
  • 자식 클래스로 부모 클래스를 참조하려 하면 java.lan.ClassCastException 오류 발생

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public class Main {
    public static void main(String args[]) {
    Foo foo = new Foo();
    Bar bar;

    // bar = (Bar)foo; // error
    if (foo instanceof Bar) { // returns false
    bar = (Bar)foo;
    }
    }
    }
  • 멤버 변수 재정의는 선언된 객체의 타입을 따른다.

  • 메소드 오버라이딩은 메모리상의 객체의 타입을 따른다. (가상 메소드 호출; Virtual method call)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    public class Foo {
    public String x = "Super";

    public void methodA() {
    System.out.println("Super");
    }
    }

    public class Bar extends Foo {
    public String x = "Sub";

    @Override
    public void methodA() {
    System.out.println("Sub");
    return;
    }
    }

    public class Main {
    public static void main(String args[]) {
    Bar bar = new Bar();
    Foo foo = (Foo)bar;

    System.out.println(bar.x); // Sub
    bar.methodA(); // Sub

    System.out.println(foo.x); // Super
    foo.methodA(); // Sub
    }
    }
  • 공변 반환 타입 (Covariant return type)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class Foo {
    public Foo getInstance() {
    return this;
    }
    }

    class Bar extends Foo {
    public Bar getInstance() { // Foo 대신 Bar로 리턴 가능
    return this;
    }
    }

Comment and share

OOP-6(Modifier)

in Java, OOP

제어자 (Modifier)

제어자란

  • 클래스, 변수, 메소드에 부가 기능을 부여하는 키워드
  • 접근 제어자 (Access modifiers)
    • 접근할 수 있는 범위를 정하는 키워드
    • public, protected, (default = package), private
  • 그 외 제어자 (Other modifiers)
    • 특별한 기능을 부여하는 제어자
    • static, final, abstract, synchronized

제어자의 기능

접근 제어자

  • 접근 가능한 범위를 정해, 데이터 은닉/보호 (Encapsulation) 기능을 추가한다.

  • 접근 제어자별 접근 범위

    제어자 같은 클래스 같은 패키지 다른 패키지에 속한 자식 클래스 전체
    public O O O O
    protected O O O
    default O O
    private O
  • private 또는 protected 변수에 접근하기 위해 getter와 setter 사용

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    class public Foo {
    private int x = 0;
    private int y = 1;

    public void setX(int x) { // setter
    this.x = x;
    }

    public void setY(int y) { // setter
    if (y >= 0) {
    this.y = y;
    }
    }

    public int getX() { // getter
    return x;
    }

    public int getY() { // getter
    return y;
    }
    }

그 외의 제어자

  • final

    • 더 이상 바뀔 수 없음을 의미

    • 클래스, 메소드, 변수에 사용할 수 있음

      • 클래스: 더 이상 상속이 불가능해진다.

      • 메소드: 자식 클래스에서 오버라이드할 수 없다.

      • 변수: 변수의 값이 초기화 이후에 변하지 않는다.

        • 생성자에서 초기화가 이루어지는 것을 blank final 변수라 한다.
        1
        2
        3
        4
        5
        6
        7
        8
        9
        public class Foo {
        final int x = 0; // final variable
        final int y; // blank finial variable

        public Foo(int y) {
        this.y = y; // blank final variable initialization
        }

        }
  • static

    • 클래스 변수, 클래스 메소드 등을 선언하기 위해 사용
  • abstract

    • 추상 클래스에서 사용
  • synchronized

    • 동시성 프로그래밍에 사용

싱글톤 패턴 (Singletone)

  • 객체가 단 하나만 존재할 수 있는 클래스

  • private 생성자를 이용한다.

    1
    2
    3
    4
    5
    6
    7
    8
    class SingletonClass {
    private static SingletoneClass instance = new SingletonClass();
    private SingletonClass() {}

    public static SingletonClass getInstance() {
    return instance;
    }
    }

Comment and share

OOP-5(Package)

in Java, OOP

패키지와 임포트 (Packages and Imports)

패키지 (Packages)

  • Java에서 소스 코드를 관리하는 방식
  • 물리적으로 디렉토리로 구분된 파일을 .으로 계층적으로 구분
  • 패키지 이름을 짓는 규칙: package 소속.프로젝트.용도
    ex) package com.google.dev.utils
    ex) package com.fastcampus.catcare.service

임포트 (Imports)

  • 다른 패키지에 선언된 클래스를 사용하기 위한 키워드

  • 패키지에 속한 모든 클래스를 import (하위 패키지는 포함하지 않음)

    1
    import com.example.project.utils.*;
  • 패키지에 속한 특정 클래스를 import

    1
    2
    import com.fastcampus.dogcare.service.WebAPI;
    import java.io.InputStream;
  • 클래스의 이름이 겹치는 경우, 패키지명을 포함하여 사용

    1
    2
    3
    4
    5
    6
    7
    8
    import java.util.List;

    public class Foo {
    public static void main(String args[]) {
    List list = new List();
    java.awt.List list2 = new java.awt.List();
    }
    }
  • static 멤버는 static import하여 클래스를 생략하고 사용 가능

    1
    2
    3
    4
    5
    6
    7
    8
    9
    import static java.lang.Math.random;
    import static java.lang.System.out;

    public class StaticImport {
    public static void main(String args[]) {
    out.println(random());
    }
    }

Comment and share

Yechan Kim

author.bio


author.job