접근 제어자(Access modifier)

  • Public
    • (패키지에 상관없이) 제약없이 사용이 가능하다.
  • protected
    • 부모 클래스에서는 public
    • 외부에서는 private
    • 다른 패키지인 경우, 상속 관계 있으면 사용 가능
  • pacakge(default)
    • 키워드를 사용하지 않았을 경우 default로 사용
    • 같은 패키지 이내에서만 사용 가능
  • private
    • 같은 클래스 안에서만 사용 가능
package com.kakao.test;

public class Student {
	// 결론적으로 field는 특별한 이유가 없는 한 싹다 private
	// class 내부의 필드는 보호해야하는 정
	private String stuName; // information hiding
	private String strNum;
	
	public String getStuName() {
		return this.stuName;
	}
	
	/**
	 * @param stuName
	 */
	public void setStuName(String stuName) {
		this.stuName = stuName;
	}
	
	
	public String getStrNum() {
		return strNum;
	}

	public void setStrNum(String strNum) {
		this.strNum = strNum;
	}

	public Student(){
		
	}
	// method는 행위를 하는 작업이기 때문에 특별한 이유가 없는 한 
	// 외부에서 사용할 수 있도록 public으로 설정한다. 
}

 


래퍼 클래스(Wrapper Class)

  • Primitive(기본 타입) type의 데이터를 객체로 취급해야 하는 경우가 생길 때 사용
  • 기본 타입 데이터를 객체로 포장해주는 클래스
  • 래퍼 클래스는 인스턴스에 저장된 값을 변경할 수 없기 때문에, 새로운 인스턴스 생성 후 생성된 인스턴스 값만 참조 가능
  • 박싱(Boxing) : 기본 타입 데이터를 래퍼 클래스의 인스턴스로 변환하는 과정
  • 언박싱(UnBoxing) : 래퍼 클래스의 인스턴스에 저장된 값을 다시 기본 타입의 데이터로 꺼내는 과정
  • JDK 1.5부터 컴파일러가 자동으로 박싱, 언박싱 처리 -> 오토 박싱, 오토 언박싱

 


제너릭(generic)

  • 데이터의 타입(data type)을 일반화(generalize) 하는 것
  • 클래스나 메소드에서 사용할 내부 데이터 타입을 컴파일 시에 미리 지정하는 방법
    • 객체의 타입 안정성 증가
    • 반환 값에 대한 타입 검사 비용 절감
  • JDK 1.5 이전까지는 Object를 사용했기 때문에, 원하는 타입으로 변환할 때 오류 발생 가능성이 있었다.
  • 제네릭 도입 이후 타입 변환과 같은 번거로운 작업 생략 가능
  • 타입 변수(type variable) : 임의의 참조형 타입을 의미한다.
    • 제네릭 클래스를 생성할 때, 타입 변수 자리에 사용할 실제 타입 명시 필요
    • 타입 변수 자리에는 기본 클래스가 아닌, 래퍼 클래스를 사용
    • Java SE 7부터는, 타입 추정이 가능한 경우, 타입 생략 가능
MyArray<Integer> myArr = new MyArray<Integer>();
MyArray<Integer> myArr = new MyArray<>();
import java.util.*;

class LandAnimal { public void crying() { System.out.println("육지동물"); } }
class Cat extends LandAnimal { public void crying() { System.out.println("냐옹냐옹"); } }
class Dog extends LandAnimal { public void crying() { System.out.println("멍멍"); } }
class Sparrow { public void crying() { System.out.println("짹짹"); } } 

class AnimalList<T> {
	ArrayList<T> al = new ArrayList<T>();
	
	void add(T animal) { al.add(animal); }
	T get(int index) { return al.get(index); }
	boolean remove(T animal) { return al.remove(animal); }
	int size() { return al.size(); }
}

public class prog {
	public static void main(String[] args) {
		AnimalList<LandAnimal> landAnimal = new AnimalList<>();	// Java SE 7부터 생략가능함.
		
		landAnimal.add(new LandAnimal());
		landAnimal.add(new Cat());
		landAnimal.add(new Dog());
		// landAnimal.add(new Sparrow());	// 오류가 발생함.
		
		for (int i = 0; i < landAnimal.size() ; i++) {
			landAnimal.get(i).crying();
		}
	}
}

 


컬렉션 프레임워크(Collection Framework)

  • 다수의 데이터를 쉽고 효과적으로 처리할 수 있는 표준화된 방법을 제공하는 클래스의 집합
  • 데이터를 저장하는 자료구조와 데이터를 처리하는 알고리즘을 구조화하여 클래스로 구현해 놓은 것
  • 인터페이스를 사용하여 구현
    • List, Set, Map

 

 

스트림(Stream)

  • 파일이나 콘솔의 입출력을 직접 다루지 않고, 스트림이라는 흐름 사용
  • 실제 입력이나 출력이 표현된 데이터의 이상화된 흐름
  • java.io 
    • InputStream
    • OutputStream
  • 보조 스트림 : 실제 데이터를 주고받지는 않지만, 다른 스트림의 기능을 향상시키거나 새로운 기능을 추가
    • 여러 개 Stream을 결합해서 확장 가능 

 

람다 표현식(lambda expression)

  • 메소드를 하나의 식으로 표현한 것
  • 객체를 생성하지 않아도, 메소드 사용 가능
  • Java SE 8 부터 람다 표현식이 생겼고, 함수형 프로그래밍 가능
  • 유의사항
    • 매개변수 타입의 추론이 가능한 경우 생략 가능
    • 매개변수가 하나일 때 괄호 생략 가능
    • 함수의 몸체가 하나의 명령문일 때 중괄호 생략 가능
    • 함수의 몸체가 하나의 return 문일 때 중괄호 생략 불가능 
    • return문 대신에 표현식 사용 가능
int min(int x, int y) {
    return x < y ? x : y;
}

// lambda expression
// (매개변수 목록) -> {함수 몸체}
(x, y) -> x < y ? x : y;
new Thread(new Runnable() {
    public void run() {
        System.out.println("전통적인 방식의 일회용 스레드 생성");
    }
}).start();
 
new Thread(()->{
    System.out.println("람다 표현식을 사용한 일회용 스레드 생성");
}).start();

 

 

함수형 인터페이스(functional interface)

  • 람다 표현식을 하나의 변수에 대입할 때 사용하는 참조 변수의 타입
  • 추상 클래스와 다르게, 하나의 추상 메소드만 가진다.
  • 어노테이션을 사용해 함수형 인터페이스 명시
@FunctionalInterface
interface Calc { // 함수형 인터페이스의 선언
    public int min(int x, int y);
}
 
public class Lambda02 {
public static void main(String[] args){
        Calc minNum = (x, y) -> x < y ? x : y; // 추상 메소드의 구현
        System.out.println(minNum.min(3, 4));  // 함수형 인터페이스의 사용
    }
}

 

스트림 API

  • Java SE 8부터 생긴 개념
  • 배열이나 컬렉션에 접근하기 위해서는 반복문이나 반복자(iterator)를 사용해야 한다. -> 가독성 저하, 코드 재사용 불가능
  • 정형화된 데이터의 단점을 스트림 API은 데이터를 추상화해서 다뤄 다양한 방식으로 저장된 데이터를 읽고 쓰기 가능하다.
  • 스트림 API 특징
    • 외부 반복을 통해 작업하는 컬렉션과 다르게 내부 반복을 통해 작업 수행
    • 재사용이 가능한 컬렉션과 다르게 한 번 사용 가능
    • 원본 데이터 변경 X
    • 연산은 필터-맵(filter-map) 기반의 API를 사용해서 성능 최적화
    • parallelStream() 메소드를 통해 손쉬운 병렬 처리 지원
  • 동작 흐름
    • 1. 스트림의 생성
    • 2. 스트림의 중개 연산 (스트림의 변환)
    • 3. 스트림의 최종 연산 (스트림의 사용)

 

Optional Class

  • primitive 타입의 객체를 포장해주는 래퍼 클래스
  • Optional 인스턴스는 모든 타입의 참조 변수를 저장할 수 있다.
  • 예상치 못한 NullPointerException 예외를 제공되는 메소드로 간단히 회피 가능
  • null 값 예외 처리 가능

 

Optional 객체 생성

  • of() 메소드 : null 이 아닌 명시된 값을 가지는 Optional 객체 반환
  • ofNullable() 메소드 사용 
    • 명시된 값이 null이 아니면 명시된 값을 가지는 Optional 객체를 반환하고, 명시된 값이 null이면 비어있는 Optional 객체 반환 
    • null 가능성이 있을 때 사용

+ Recent posts