[Become a Java-Masta๐Ÿ‘จโ€๐Ÿซ 7์ฃผ์ฐจ] ์• ๋…ธํ…Œ์ด์…˜, I/O, ์ œ๋„ค๋ฆญ, ๋žŒ๋‹ค์‹

48944 ๋‹จ์–ด TILJavaJava

๐ŸŽฏ ๋ชฉํ‘œ

์ž๋ฐ”์˜ Annotation, I/O, Generic, Lambda์— ๋Œ€ํ•ด ํ•™์Šตํ•˜๊ธฐ.

๐Ÿ“Œ ํ•™์Šตํ•  ๊ฒƒ

Annotation

I/O

Generic

Lambda


Annotation

์• ๋…ธํ…Œ์ด์…˜(Annotation) : ์‚ฌ์ „์  ์˜๋ฏธ๋กœ ์ฃผ์„์„ ์˜๋ฏธํ•˜๋ฉฐ, ํ”„๋กœ๊ทธ๋žจ์— ๋Œ€ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์ œ๊ณตํ•˜๋Š” ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ์˜ ํ•œ ํ˜•ํƒœ


์ •์˜ํ•˜๋Š” ๋ฐฉ๋ฒ•

์• ๋…ธํ…Œ์ด์…˜ ํƒ€์ž…์€ java.lang or java.lang.annotation์—์„œ ์ œ๊ณตํ•ด์ฃผ๋Š” ๊ฒƒ์ด ์žˆ๊ณ  ํ•„์š”์—๋”ฐ๋ผ ์ž์‹ ์ด ์ง์ ‘ ์ •์˜ํ•ด์„œ ์‚ฌ์šฉํ•  .

์• ๋…ธํ…Œ์ด์…˜์„ ์ง์ ‘ ์ •์˜ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ @interface ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ •์˜ํ•œ๋‹ค.

public @interface CustomAnnotation {
    	// Element
	int value();
}

@CustomAnnotation(value = 29)
@CustomAnnotation(29)

@interface๋Š” ์• ๋…ธํ…Œ์ด์…˜ ํƒ€์ž…(annotation type)์„ ์„ ์–ธํ•˜๋Š” ํ‚ค์›Œ๋“œ์ด๊ณ , ์• ๋…ธํ…Œ์ด์…˜ ํƒ€์ž… ์„ ์–ธ์„ ์ผ๋ฐ˜์ ์ธ ์ธํ„ฐํŽ˜์ด์Šค ์„ ์–ธ๊ณผ ๊ตฌ๋ถ„ํ•˜๊ธฐ ์œ„ํ•ด interface ์•ž์— ๊ธฐํ˜ธ @๋ฅผ ๋ถ™์ธ๋‹ค.

์• ๋…ธํ…Œ์ด์…˜์€ Element๋ผ๋Š” ๊ฒƒ์„ ๋ฉค๋ฒ„๋กœ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์œผ๋ฉฐ, Element๋Š” ํƒ€์ž…๊ณผ ์ด๋ฆ„์œผ๋กœ ๊ตฌ์„ฑ๋˜๋ฉฐ default ๊ฐ’์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค.

Element์˜ ์ด๋ฆ„ ๋’ค์—๋Š” ๋ฉ”์†Œ๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ ์ฒ˜๋Ÿผ ๋’ค์— ()๋ฅผ ๋ถ™์—ฌ์•ผ ํ•œ๋‹ค.

์ •์˜๋œ ์• ๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์€ @์• ๋…ธํ…Œ์ด์…˜ ๋ช…์œผ๋กœ ์„ ์–ธํ•  ์ˆ˜ ์žˆ๊ณ , ํŠน์ • ํด๋ž˜์Šค๋‚˜ ๋ฉ”์†Œ๋“œ, ๋ณ€์ˆ˜์— ๋ถ™์—ฌ ์‚ฌ์šฉํ•œ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ํ•œ ์„ ์–ธ๋ถ€์— ์—ฌ๋Ÿฌ ์• ๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.

๊ธฐ๋ณธ Element๋Š” value์ด๋ฉฐ, ํ•ด๋‹นํ•˜๋Š” ๊ฐ’์€ ์ƒ๋žตํ•˜๊ณ  ๋ฐ”๋กœ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.


์• ๋…ธํ…Œ์ด์…˜์˜ ์šฉ๋„

  1. ์ปดํŒŒ์ผ ํƒ€์ž„์— ์ œ๊ณตํ•˜๋Š” ์ •๋ณด
    • @Override : ์ƒ์œ„ ํด๋ž˜์Šค์˜ ๋ฉ”์„œ๋“œ๋ฅผ ์žฌ์ •์˜ํ•˜์˜€์Œ์„ ๋‚˜ํƒ€๋‚ด๋Š” Annotation. ์ƒ์œ„ ํด๋ž˜์Šค์— ํ•ด๋‹น ๋ฉ”์„œ๋“œ๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ Compiler๊ฐ€ ๊ฒฝ๊ณ ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•จ.
    • @SuppressWarnings : ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ๊ฒฝ๊ณ ํ•˜๋Š” ๋‚ด์šฉ์„ Ignore ํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” Annotation
    • @Generated : ์†Œ์Šค ์ฝ”๋“œ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋„๊ตฌ์— ์˜ํ•ด์„œ ํ•ด๋‹น ์ฝ”๋“œ๊ฐ€ ์ž๋™์ ์œผ๋กœ ์ƒ์„ฑ๋˜์—ˆ์Œ์„ ๋‚˜ํƒ€๋‚ด๋Š” Annotation
  2. ์ปดํŒŒ์ผ ์‹œ๊ฐ„ ๋ฐ ๋ฐฐํฌ ์‹œ๊ฐ„ ์ฒ˜๋ฆฌ -> ์†Œํ”„ํŠธ์›จ์–ด ๊ฐœ๋ฐœํˆด์ด ์• ๋…ธํ…Œ์ด์…˜ ์ •๋ณด๋ฅผ ์ฒ˜๋ฆฌํ•˜์—ฌ ์ฝ”๋“œ, XML ํŒŒ์ผ๋“ฑ์„ ์ƒ์„ฑ ๊ฐ€๋Šฅ (์• ๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•œ ๊ณณ์— ํŠน์ • ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ ex) Lombok์˜ @Getter, @Setter)
  3. ๋Ÿฐํƒ€์ž„ ์ฒ˜๋ฆฌ -> ์ผ๋ถ€์•  ๋…ธํ…Œ์ด์…˜์€ ๋Ÿฐํƒ€์ž„์— ํŠน์ • ๊ธฐ๋Šฅ์„ ์‹คํ–‰ํ•˜๋„๋ก ์ •๋ณด๋ฅผ ์ œ๊ณต (Java Reflection)
    • ์ž๋ฐ” ๋ฆฌํ”Œ๋ ‰์…˜(Java Reflection) : ๊ตฌ์ฒด์ ์ธ ํด๋ž˜์Šค ํƒ€์ž…์„ ์•Œ์ง€ ๋ชปํ•ด๋„ ๋Ÿฐํƒ€์ž„ ์‹œ์— ํด๋ž˜์Šค ์ด๋ฆ„๋งŒ ์•Œ๊ณ ์žˆ๋‹ค๋ฉด ๊ทธ ํด๋ž˜์Šค์˜ ๋ฉ”์†Œ๋“œ, ํƒ€์ž…, ๋ณ€์ˆ˜๋“ค์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ฃผ๋Š” ์ž๋ฐ” API,
    • @FunctionalInterface : ํ•ด๋‹น Interface๊ฐ€ ํ•˜๋‚˜์˜ ๋ฉ”์„œ๋“œ๋งŒ์„ ์ œ๊ณตํ•˜๋Š” ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค์ž„์„ ๋‚˜ํƒ€๋‚ด๋Š” Annotation
    • @Deprecated : ๋” ์ด์ƒ ์ง€์›ํ•˜์ง€ ์•Š๋Š” ๊ธฐ๋Šฅ์ž„์„ ์•Œ๋ ค์ฃผ๋Š” Annotation
    • @SafeVarargs : Generic๊ณผ ๊ฐ™์€ ๊ฐ€๋ณ€ ์ธ์ž Parameter๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ๊ณ ๋ฅผ ignore ํ•˜๋Š” Annotation
    • @Repeatable : ํ•ด๋‹น Annotation์„ ๋ฐ˜๋ณต์ ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ์ง€์›ํ•˜๋Š” Annotation
    • @Inherited : Meta Annotation ์ค‘ ํ•˜๋‚˜๋กœ ์จ ์ ์šฉ๋œ ๋Œ€์ƒ Annotation์„ ํ•˜์œ„ Class, Interface์—๊ฒŒ ์ƒ์†์‹œํ‚ค๋Š” Annotation

@Retention

@Retention ์—๋…ธํ…Œ์ด์…˜์€ ์• ๋…ธํ…Œ์ด์…˜ ์„ ์–ธ์— ์‚ฌ์šฉ๋˜๋Š” ๋ฉ”ํƒ€ ์• ๋…ธํ…Œ์ด์…˜์œผ๋กœ, ๋งˆํฌ๋œ ์—๋…ธํ…Œ์ด์…˜์„ ์–ธ์ œ๊นŒ์ง€ ์œ ์ง€ํ•  ๊ฑด์ง€ ๊ฒฐ์ •ํ•ด์ฃผ๋Š” ์• ๋…ธํ…Œ์ด์…˜์ด๋‹ค.

์ฆ‰, Java ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์• ๋…ธํ…Œ์ด์…˜์„ ๋‹ค๋ฃจ๋Š” ๋ฐฉ๋ฒ•์„ ๊ธฐ์ˆ ํ•˜๋ฉฐ, ์–ด๋Š ์‹œ์ ๊นŒ์ง€ ์˜ํ–ฅ์„ ๋ฏธ์น˜๋Š”์ง€ ๊ฒฐ์ •ํ•œ๋‹ค.

๋ณด์กดํ•  ๊ธฐ๊ฐ„์„ ํŠน์ •ํ•˜๊ฒŒ ๋ช…์‹œํ•˜์ง€ ์•Š์œผ๋ฉด ๊ธฐ๋ณธ๊ฐ’์€ ํด๋ž˜์Šค ํŒŒ์ผ๊นŒ์ง€ ๋ณด์กดํ•œ๋‹ค.

ํ•ด๋‹น ์ •์ฑ…๋“ค์€ java.lang.annotation.RetentionPolicy์— enum์œผ๋กœ ์ •์˜๋˜์–ด ์žˆ์œผ๋ฉฐ ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

  • SOURCE : ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ปดํŒŒ์ผํ•  ๋•Œ ํ•ด๋‹น ์• ๋…ธํ…Œ์ด์…˜ ์ œ์™ธ
  • CLASS : ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ปดํŒŒ์ผ์—์„œ๋Š” ํ•ด๋‹น ์• ๋…ธํ…Œ์ด์…˜์„ ๊ฐ€์ ธ๊ฐ€์ง€๋งŒ ๋Ÿฐํƒ€์ž„ ์‹œ์—๋Š” ์‚ฌ๋ผ์ง
  • RUNTIME : ๋Ÿฐํƒ€์ž„์—๋„ ํ•ด๋‹น ์• ๋…ธํ…Œ์ด์…˜ ์œ ์ง€
@Retention(RetentionPolicy.RUNTIME) //๋Ÿฐํƒ€์ž„์—๋„ ํ•ด๋‹น ์• ๋…ธํ…Œ์ด์…˜ ์œ ์ง€
public @interface CustomAnnotation {
    	// Element
	int value();
}

@Target

@Target ์• ๋…ธํ…Œ์ด์…˜์€ ์• ๋…ธํ…Œ์ด์…˜ ์„ ์–ธ์— ์‚ฌ์šฉ๋˜๋Š” ๋ฉ”ํƒ€ ์• ๋…ธํ…Œ์ด์…˜์œผ๋กœ, ์• ๋…ธํ…Œ์ด์…˜์„ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ฒ”์œ„๋ฅผ ์ •์˜ํ•œ๋‹ค.

ํ•ด๋‹น ๋ฒ”์œ„๋“ค์€ java.lang.annotation.ElementType์— ๋‹ค์–‘ํ•œ ๋ฒ”์œ„๊ฐ€ ์ •์˜๋˜์–ด ์žˆ์œผ๋ฉฐ ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

  • TYPE : Class, Interface ๋“ฑ์˜ Level์— ์„ ์–ธ ๊ฐ€๋Šฅ
  • METHOD : ๋ฉ”์„œ๋“œ์— ์„ ์–ธ ๊ฐ€๋Šฅ
  • FIELD : Enum, ์ƒ์ˆ˜, Field ๋ณ€์ˆ˜์— ๋Œ€ํ•ด ์„ ์–ธ ๊ฐ€๋Šฅ
  • PARAMETER : ๋งค๊ฐœ๋ณ€์ˆ˜์— ์„ ์–ธ ๊ฐ€๋Šฅ
  • CONTRUCTOR : ์ƒ์„ฑ์ž Type์— ์„ ์–ธ ๊ฐ€๋Šฅ
  • LOCAL_VARIABLE : ์ง€์—ญ ๋ณ€์ˆ˜์— ๋Œ€ํ•ด ์„ ์–ธ ๊ฐ€๋Šฅ
  • ANNOTATION_TYPE : Annotation์— ์„ ์–ธ ๊ฐ€๋Šฅ
  • PACKAGE : ํŒจํ‚ค์ง€์— ์„ ์–ธ ๊ฐ€๋Šฅ
@Target(ElementType.FIELD) //  Enum, ์ƒ์ˆ˜, Field ๋ณ€์ˆ˜์— ๋Œ€ํ•ด ์„ ์–ธ ๊ฐ€๋Šฅ
@Retention(RetentionPolicy.RUNTIME) // ๋Ÿฐํƒ€์ž„์—๋„ ํ•ด๋‹น ์• ๋…ธํ…Œ์ด์…˜ ์œ ์ง€
public @interface CustomAnnotation {
    	// Element
	int value();
}

@Documented

@Documented ์• ๋…ธํ…Œ์ด์…˜์€ ์• ๋…ธํ…Œ์ด์…˜ ์„ ์–ธ์— ์‚ฌ์šฉ๋˜๋Š” ๋ฉ”ํƒ€ ์• ๋…ธํ…Œ์ด์…˜์œผ๋กœ, ํ•ด๋‹น ์• ๋…ธํ…Œ์ด์…˜์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ Javadoc๋ฌธ์„œ์— ํฌํ•จํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์„ ์–ธํ•œ๋‹ค.

@Documented // ์ด ์• ๋…ธํ…Œ์ด์…˜์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ Javadoc๋ฌธ์„œ์— 
@Target(ElementType.FIELD) //  Enum, ์ƒ์ˆ˜, Field ๋ณ€์ˆ˜์— ๋Œ€ํ•ด ์„ ์–ธ ๊ฐ€๋Šฅ
@Retention(RetentionPolicy.RUNTIME) // ๋Ÿฐํƒ€์ž„์—๋„ ํ•ด๋‹น ์• ๋…ธํ…Œ์ด์…˜ ์œ ์ง€
public @interface CustomAnnotation {
    	// Element
	int value();
}

Annotation Processor

Annotation Processor๋Š” ์• ๋…ธํ…Œ์ด์…˜์„ ์ด์šฉํ•˜์—ฌ ํ”„๋กœ์„ธ์Šค๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•˜๋ฉฐ, ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ปดํŒŒ์ผ ์ค‘์— ์ƒˆ๋กœ์šด ์†Œ์Šค์ฝ”๋“œ๋ฅผ ์ƒ์„ฑํ•˜๊ฑฐ๋‚˜ ๊ธฐ์กด์˜ ์ฝ”๋“œ ๋ณ€๊ฒฝ์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•œ๋‹ค.

ํŠนํžˆ ์ปดํŒŒ์ผ ๋‹จ๊ณ„์—์„œ ์• ๋…ธํ…Œ์ด์…˜์— ์ •์˜๋œ ์•ก์…˜์„ ์ฒ˜๋ฆฌํ•˜๋Š”๋ฐ, ์ด๊ฒƒ์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์‹คํ–‰๋˜๊ธฐ ์ „ ์ปดํŒŒ์ผ ํƒ€์ž„์— ๋ฏธ๋ฆฌ ์ฒดํฌ๋ฅผ ํ•ด์ฃผ๊ธฐ ๋•Œ๋ฌธ์— ์• ๋…ธํ…Œ์ด์…˜์ด ์˜๋„ํ•œ๋Œ€๋กœ ์ด๋ฃจ์–ด์ง€์ง€ ์•Š์œผ๋ฉด ๋ˆˆ์œผ๋กœ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š” ์—๋Ÿฌ๋‚˜ ๊ฒฝ๊ณ ๋ฅผ ๋ณด์—ฌ์ค€๋‹ค.

์• ๋…ธํ…Œ์ด์…˜ ํ”„๋กœ์„ธ์„œ์˜ ๊ฐ€์žฅ ๋Œ€ํ‘œ์ ์ธ ์˜ˆ๋กœ๋Š” Lombok ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์žˆ๋‹ค.

Getter, Setter์™€ ๊ฐ™์ด ๋ฐ˜๋ณต์ ์ด๊ณ  ์ค‘๋ณต๋˜๋Š” ๋งŽ์€ ์ฝ”๋“œ๋ฅผ ์–‘์‚ฐํ•˜๋Š” ์ฝ”๋“œ(boilerplate code)๋ฅผ ์ตœ์†Œํ™”ํ•˜๊ณ  ํ•ต์‹ฌ์ ์ธ ๊ธฐ๋Šฅ์„ ๋ช…ํ™•ํ•˜๊ฒŒ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค.

์• ๋…ธํ…Œ์ด์…˜ ํ”„๋กœ์„ธ์„œ๋ฅผ ์ž‘์„ฑํ•˜๊ณ  ๋“ฑ๋กํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” AbstractProcessror ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›์•„์•ผ ํ•˜๋Š”๋ฐ, Lombok ๋˜ํ•œ AbstractProcessor๋ฅผ ์ƒ์†๋ฐ›์•„ ์• ๋…ธํ…Œ์ด์…˜ ํ”„๋กœ์„ธ์„œ๋ฅผ ์ •์˜ํ•œ ๊ฒƒ์ด๋‹ค.

  1. Lombok
    • @Getter @Setter @Builder
  2. AutoService :
    • java.util.ServiceLoader ์šฉ ํŒŒ์ผ ์ƒ์„ฑ ์œ ํ‹ธ๋ฆฌํ‹ฐ
    • ๋ฆฌ์†Œ์Šค ํŒŒ์ผ์„ ๋งŒ๋“ค์–ด ์คŒ.
    • META-INF ๋ฐ‘์˜ service ๋ฐ‘์— ServiceLoader์šฉ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ ํŒŒ์ผ์„ ๋งŒ๋“ค์–ด ์คŒ.
  3. @Override
    • ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์˜ค๋ฒ„๋ผ์ด๋”ฉํ•˜๋Š” ๋ฉ”์„œ๋“œ๊ฐ€ ์ž˜๋ชป๋œ ๋Œ€์ƒ์ž„์„ ์ฒดํฌํ•ด์ฃผ๋Š” ๊ฒƒ๋„ ์• ๋…ธํ…Œ์ด์…˜ ํ”„๋กœ์„ธ์„œ์ž„
  4. Dagger2
    • ์ปดํŒŒ์ผ ํƒ€์ž„ DI ์ œ๊ณต -> ๋Ÿฐํƒ€์ž„ ๋น„์šฉ์ด ์—†์–ด์ง.
  5. ์•ˆ๋“œ๋กœ์ด๋“œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ
    • ButterKnife : @BindView (๋ทฐ ์•„์ด๋””์™€ ์• ๋…ธํ…Œ์ด์…˜ ๋ถ™์ธ ํ•„๋“œ ๋ฐ”์ธ๋”ฉ)
    • DeepLinkDispatcher : ํŠน์ • URI ๋งํฌ๋ฅผ Activity๋กœ ์—ฐ๊ฒฐํ•  ๋•Œ ์‚ฌ์šฉ

I/O

I/O๋Š” Input(์ž…๋ ฅ) and Output(์ถœ๋ ฅ)์˜ ์•ฝ์ž์ด๋‹ค.

I/O์˜ ๊ฐ„๋‹จํ•œ ์˜ˆ์‹œ๋Š”, ํ‚ค๋ณด๋“œ๋กœ ํ…์ŠคํŠธ๋ฅผ ์ž…๋ ฅํ•˜๊ณ  ๋ชจ๋‹ˆํ„ฐ๋กœ ์ž…๋ ฅํ•œ ํ…์ŠคํŠธ๋ฅผ ์ถœ๋ ฅํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

๊ธฐ์กด์˜ IO(I/O)๋ฐฉ์‹์€ ์ŠคํŠธ๋ฆผ ๋ฐฉ์‹์˜ ์ž…์ถœ๋ ฅ์ธ๋ฐ, ์ด ๋ฐฉ์‹์œผ๋กœ๋Š” ๋„คํŠธ์›Œํฌ์ƒ์—์„œ ์ด๋ฃจ์–ด์ง€๋Š” ์ž…์ถœ๋ ฅ์˜ ์†๋„๊ฐ€ ํ•˜๋“œ์›จ์–ด์—์„œ ์ด๋ฃจ์–ด์ง€๋Š” ์ž…์ถœ๋ ฅ ์†๋„์— ๋น„ํ•ด ํ˜„์ €ํžˆ ๋Š๋ฆฌ๊ธฐ ๋•Œ๋ฌธ์— ๋ฌธ์ œ์ ์ด ์ƒ๊ฒผ๋‹ค.

๋˜ํ•œ ์ŠคํŠธ๋ฆผ ๋ฐฉ์‹์€ ๋ณ‘๋ชฉํ˜„์ƒ์— ๋งค์šฐ ์ทจ์•ฝํ•˜๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ๊ณ  ๋„คํŠธ์›Œํฌ์˜ ๋ฐœ์ „๋ณด๋‹ค ํ•˜๋“œ์›จ์–ด์˜ ๋ฐœ์ „์†๋„๊ฐ€ ์•ž์„œ๋‚˜๊ฐ€๋ฉด์„œ ์ƒˆ๋กœ์šด I/O ๋ฐฉ์‹์ด ํ•„์š”ํ•ด์กŒ๋‹ค.

๊ทธ๋ž˜์„œ ์ด๋Ÿฌํ•œ ๋„คํŠธ์›Œํฌ ํ™˜๊ฒฝ์—์„œ์˜ ๋ฌธ์ œ์ ์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ NIO(NEW I/O)๋ฐฉ์‹์ด ๋‚˜ํƒ€๋‚ฌ๋‹ค.

๊ตฌ๋ถ„IONIO
์ž…์ถœ๋ ฅ์ŠคํŠธ๋ฆผ์ฑ„๋„
๋ฒ„ํผnon-๋ฒ„ํผ๋ฒ„ํผ
๋น„๋™๊ธฐ์ง€์› ์•ˆํ•จ์ง€์›
๋ธ”๋กœํ‚น๋ธ”๋กœํ‚น๋งŒ ์ง€์›๋ธ”๋กœํ‚น / non-๋ธ”๋กœํ‚น ๋ชจ๋‘ ์ง€์›

Stream

Stream์ด๋ž€, ํ•œ ๋ฐฉํ–ฅ์œผ๋กœ ์—ฐ์†์ ์œผ๋กœ ํ˜๋Ÿฌ๊ฐ€๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค.

์ด Stream์ด ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ํ•œ ๋ฐฉํ–ฅ์œผ๋กœ ํ˜๋Ÿฌ๊ฐˆ ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ฃผ๋Š” ๊ด€, ํ†ต๋กœ๋ผ๋Š” ์˜๋ฏธ๋กœ ์‚ฌ์šฉ๋œ๋‹ค.

์ž…์ถœ๋ ฅ ๋…ธ๋“œ์— ์ง์ ‘ ์—ฐ๊ฒฐ๋˜๋Š” Stream์„ ๋…ธ๋“œ์ŠคํŠธ๋ฆผ์ด๋ผ๊ณ  ํ•˜๊ณ , ์ด๋Š” ํ•„์ˆ˜ ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ๋‹ค๋ฅธ ์ŠคํŠธ๋ฆผ์„ ๋ณด์กฐํ•˜๋Š” ๊ธฐ๋Šฅ์ ์ธ Stream์„ ํ•„ํ„ฐ์ŠคํŠธ๋ฆผ์ด๋ผ๊ณ  ํ•˜๋ฉฐ, ์ด๋Š” ์˜ต์…˜ ์ด๋‹ค.

๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒจํ„ด์œผ๋กœ ๋…ธ๋“œ์ŠคํŠธ๋ฆผ์— ํ•„ํ„ฐ์ŠคํŠธ๋ฆผ์ด ์ถ”๊ฐ€๋˜๋Š” ๋ฐฉ์‹์ด๋‹ค.


Stream์ด ๋ฐ์ดํ„ฐ๋ฅผ ์–ด๋–ค ๋ฐฉ์‹์œผ๋กœ ์ „๋‹ฌํ•˜๋Š๋ƒ์— ๋”ฐ๋ผ 2๊ฐ€์ง€๋กœ ๊ตฌ๋ถ„ํ•  ์ˆ˜ ์žˆ๋‹ค.

  1. Byte Stream (๋ฐ”์ดํŠธ ์ŠคํŠธ๋ฆผ)
    • ๋ฐ์ดํ„ฐ๋ฅผ Byte ๋‹จ์œ„๋กœ ์ฃผ๊ณ  ๋ฐ›์Œ
    • Binary ๋ฐ์ดํ„ฐ๋ฅผ ์ž…์ถœ๋ ฅํ•˜๋Š” ์ŠคํŠธ๋ฆผ
    • ๋ชจ๋“  ์ข…๋ฅ˜์˜ ๋ฐ์ดํ„ฐ ๋ฅผ ์ฃผ๊ณ ๋ฐ›์„ ์ˆ˜ ์žˆ์Œ
    • InputStream๊ณผ OutputStream ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›์•„ ์‚ฌ์šฉ

    • FileInputStream / FileOutputStream : ํŒŒ์ผ ์ž…์ถœ๋ ฅ ์ŠคํŠธ๋ฆผ
    • ByteArrayInputStream / ByteArrayOutputStream : ๋ฉ”๋ชจ๋ฆฌ ์ž…์ถœ๋ ฅ ์ŠคํŠธ๋ฆผ
    • PipedInputStream / PipedOutputStream : ํ”„๋กœ์„ธ์Šค ์ž…์ถœ๋ ฅ ์ŠคํŠธ๋ฆผ
    • AudioInputStream / AudioOutputStream : ์˜ค๋””์˜ค ์žฅ์น˜ ์ž…์ถœ๋ ฅ ์ŠคํŠธ๋ฆผ

์ž๋ฐ”์—์„œ ๊ฐ€์žฅ ์ž‘์€ ํƒ€์ž…์ธ char ํ˜•์ด 2๋ฐ”์ดํŠธ์ด๋ฏ€๋กœ, 1๋ฐ”์ดํŠธ์”ฉ ์ „์†ก๋˜๋Š” ๋ฐ”์ดํŠธ ๊ธฐ๋ฐ˜ ์ŠคํŠธ๋ฆผ์œผ๋กœ๋Š” ์›ํ™œํ•œ ์ฒ˜๋ฆฌ๊ฐ€ ํž˜๋“  ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ฒฝ์šฐ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ์ž๋ฐ”๋Š” Character Stream์„ ์ง€์›ํ•จ

  1. Character Stream (๋ฌธ์ž ์ŠคํŠธ๋ฆผ)
    • ๋ฐ์ดํ„ฐ๋ฅผ Character ๋‹จ์œ„๋กœ ์ฃผ๊ณ  ๋ฐ›์Œ
    • ๋ฌธ์ž ๋ฐ์ดํ„ฐ๋ฅผ ์ธ์ฝ”๋”ฉ ์ฒ˜๋ฆฌํ•˜์—ฌ ์ž…์ถœ๋ ฅํ•˜๋Š” ์ŠคํŠธ๋ฆผ
    • ์˜ค์ง ๋ฌธ์ž ๋ฐ์ดํ„ฐ ๋งŒ ์ฃผ๊ณ ๋ฐ›์„ ์ˆ˜ ์žˆ์Œ
    • Reader์™€ Writer ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›์•„ ์‚ฌ์šฉ

    • FileReader / FileWriter : ํŒŒ์ผ ์ž…์ถœ๋ ฅ ์ŠคํŠธ๋ฆผ
    • CharArrayReader / CharArrayWriter : ๋ฉ”๋ชจ๋ฆฌ ์ž…์ถœ๋ ฅ ์ŠคํŠธ๋ฆผ
    • PipedReader / PipedWriter : ํ”„๋กœ์„ธ์Šค ์ž…์ถœ๋ ฅ ์ŠคํŠธ๋ฆผ
    • StringReader / StringWriter : ๋ฌธ์ž์—ด ์ž…์ถœ๋ ฅ ์ŠคํŠธ๋ฆผ

๋‘ Stream์€ ๋ชจ๋‘ ์ฒ˜์Œ์—๋Š” byte๋กœ ๋ฐ›์•„๋“ค์ด๊ณ , ๊ทธ ๋‹ค์Œ์€ ๊ฐ Stream์ด ์•Œ์•„์„œ ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์ค€๋‹ค.


ํ‘œ์ค€ Stream

System Class๋Š” ์ž๋ฐ”์—์„œ ๋ฏธ๋ฆฌ ์ •์˜ํ•ด๋‘” ํ‘œ์ค€ ์ž…์ถœ๋ ฅ ํด๋ž˜์Šค์ด๋ฉฐ, java.lang ํŒจํ‚ค์ง€์— ํฌํ•จ๋˜์–ด ์žˆ๋‹ค.

  • System.in : ํ‘œ์ค€ ์ž…๋ ฅ ์ŠคํŠธ๋ฆผ
  • System.out : ํ‘œ์ค€ ์ถœ๋ ฅ ์ŠคํŠธ๋ฆผ
  • System.err : ํ‘œ์ค€ ์—๋Ÿฌ ์ถœ๋ ฅ ์ŠคํŠธ๋ฆผ

Channel

์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ๊ฐ„์˜ ํ†ต์‹ ์ˆ˜๋‹จ์„ ์˜๋ฏธํ•œ๋‹ค.

์ผ๋ฐ˜์ ์œผ๋กœ NIO(new I/O)์˜ ๋ชจ๋“  I/O๋Š” ์ฑ„๋„๋กœ ์‹œ์ž‘ํ•œ๋‹ค.

์ฑ„๋„์€ ์ŠคํŠธ๋ฆผ๊ณผ ์œ ์‚ฌํ•˜์ง€๋งŒ ๋ช‡ ๊ฐ€์ง€ ์ฐจ์ด์ ์ด ์กด์žฌํ•œ๋‹ค.

  • ๋น„๋™๊ธฐ์  ์ž…์ถœ๋ ฅ
  • ์ŠคํŠธ๋ฆผ์€ ๋‹จ๋ฐฉํ–ฅ ์ž…์ถœ๋ ฅ(์ฝ๊ธฐ ๋˜๋Š” ์“ฐ๊ธฐ) ๋งŒ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ ์ฑ„๋„์„ ํ†ตํ•ด์„œ๋Š” ์–‘๋ฐฉํ–ฅ ์ž…์ถœ๋ ฅ(์ฝ๊ณ  ์“ฐ๊ธฐ) ์ด ๊ฐ€๋Šฅํ•˜๋‹ค ์žˆ๋‹ค.
  • ํ•ญ์ƒ ๋ฒ„ํผ๋ฅผ ์ด์šฉํ•˜์—ฌ ์ž…์ถœ๋ ฅ์„ ํ•œ๋‹ค.

Buffer

๋ฐ์ดํ„ฐ๋ฅผ ์ž„์‹œ ์ €์žฅํ•˜๋Š” ๊ณต๊ฐ„์„ ์˜๋ฏธํ•œ๋‹ค.

IO์—์„œ๋Š” ์ถœ๋ ฅ ์ŠคํŠธ๋ฆผ์ด 1๋ฐ”์ดํŠธ๋ฅผ ์“ฐ๋ฉด ์ž…๋ ฅ ์ŠคํŠธ๋ฆผ์ด 1๋ฐ”์ดํŠธ๋ฅผ ์ฝ๋Š”๋‹ค.

NIO์—์„œ ๋ฒ„ํผ๋Š” ์ฑ„๋„๊ณผ ์ƒํ˜ธ์ž‘์šฉํ•  ๋•Œ ์‚ฌ์šฉ๋œ๋‹ค. ์ปค๋„์— ์˜ํ•ด ๊ด€๋ฆฌ๋˜๋Š” ์‹œ์Šคํ…œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ง์ ‘ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ฑ„๋„์— ์˜ ํ•ด ์ง์ ‘ read ๋˜๊ฑฐ๋‚˜ write ๋  ์ˆ˜ ์žˆ๋Š” ๋ฐฐ์—ด๊ณผ ๊ฐ™์€ ๊ฐ์ฒด์ด๋‹ค.

์ž…์ถœ๋ ฅ์„ ๋‹ด๋‹นํ•˜๋Š” ์žฅ์น˜, ํ”„๋กœ์„ธ์Šค์—์„œ ๊ณ ์† ์žฅ์น˜(ํ”„๋กœ์„ธ์Šค)๊ฐ€ ์ €์† ์žฅ์น˜(ํ”„๋กœ์„ธ์Šค)๊ฐ€ ์ž‘์—…์„ ํ•˜๋Š” ๋™์•ˆ ๊ธฐ๋‹ค๋ฆฌ๋Š” ์‹œ๊ฐ„์„ ์ค„์—ฌ ๊ฐœ๋ณ„ ์ž‘์—…๋“ค ๊ฐ„์˜ ํ˜‘๋™์„ ์›ํ™œํ•˜๊ฒŒ ์ง€์›ํ•˜๊ธฐ ์œ„ํ•ด ์กด์žฌํ•œ๋‹ค.

๋”ฐ๋ผ์„œ, 1๋ฐ”์ดํŠธ์”ฉ ์ „๋‹ฌ์ด ์•„๋‹ˆ๋ผ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๋™์•ˆ ๋ฒ„ํผ์— ๋ฐ์ดํ„ฐ๋ฅผ ์ถ•์ฒ™ํ•˜์—ฌ ํ•œ๋ฒˆ์— ์ „๋‹ฌํ•˜์—ฌ ๋น ๋ฅธ ์†๋„๋ฅผ ๋ณด์ธ๋‹ค.


InputStream

Byte Stream๊ธฐ๋ฐ˜์˜ ์ž…๋ ฅ ์ŠคํŠธ๋ฆผ์˜ ์ตœ์ƒ์œ„ ํด๋ž˜์Šค(์ถ”์ƒํด๋ž˜์Šค)๋กœ์จ ๋ชจ๋“  Byte๊ธฐ๋ฐ˜ ์ž…๋ ฅ ์ŠคํŠธ๋ฆผ์€ ์ด ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›๊ณ  ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒจํ„ด์œผ๋กœ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์ŠคํŠธ๋ฆผ์ด ๋งŒ๋“ค์–ด์ง„๋‹ค.

InputStream ํด๋ž˜์Šค์—๋Š” ์ž…๋ ฅ์„ ์œ„ํ•ด ํ•„์š”ํ•œ ๊ธฐ๋ณธ์ ์ธ ๋ฉ”์†Œ๋“œ๋“ค์ด ์ •์˜๋˜์–ด ์žˆ๋‹ค.

  • int available() : ํ˜„์žฌ ์ฝ์„ ์ˆ˜ ์žˆ๋Š” byte์ˆ˜๋ฅผ ๋ฆฌํ„ด
  • abstract int read() : InputStream์œผ๋กœ๋ถ€ํ„ฐ 1byte๋ฅผ ์ฝ๊ณ  ๋ฆฌํ„ด.
  • int read(byte[] b) : InputStream์œผ๋กœ๋ถ€ํ„ฐ ์ฝ์€ ๋ฐ”์ดํŠธ๋“ค์„ byte[] b์— ์ €์žฅํ•˜๊ณ  ์ฝ์€ ๋ฐ”์ดํŠธ ์ˆ˜๋ฅผ ๋ฆฌํ„ด.
  • int read(byte[] b, int off, int len) : InputStream์œผ๋กœ๋ถ€ํ„ฐ len byte๋งŒํผ ์ฝ์–ด byte[] b์˜ b[ off ] ๋ถ€ํ„ฐ len ๊ฐœ๊นŒ์ง€ ์ €์žฅํ•œ ํ›„ ์ฝ์€ byte ์ˆ˜์ธ len ๊ฐœ๋ฅผ ๋ฆฌํ„ด. ๋งŒ์•ฝ len ๊ฐœ๋ณด๋‹ค ์ ์€ byte๋ฅผ ์ฝ๋Š” ๊ฒฝ์šฐ ์‹ค์ œ ์ฝ์€ byte์ˆ˜๋ฅผ ๋ฆฌํ„ด
  • void close() : ์‚ฌ์šฉํ•œ ์‹œ์Šคํ…œ ๋ฆฌ์†Œ์Šค๋ฅผ ๋ฐ˜๋‚ฉ ํ›„ ์ž…๋ ฅ ์ŠคํŠธ๋ฆผ์„ ๋‹ซ๋Š” ๋ฉ”์†Œ๋“œ.close() : ์‚ฌ์šฉํ•œ ์‹œ์Šคํ…œ ๋ฆฌ์†Œ์Šค๋ฅผ ๋ฐ˜๋‚ฉ ํ›„ InputStream์„ ๋‹ซ์Œ.

OutputStream

OutputStream ๋˜ํ•œ Byte Stream๊ธฐ๋ฐ˜์˜ ์ถœ๋ ฅ ์ŠคํŠธ๋ฆผ์˜ ์ตœ์ƒ์œ„ ํด๋ž˜์Šค(์ถ”์ƒํด๋ž˜์Šค)๋กœ์จ ๋ชจ๋“  Byte๊ธฐ๋ฐ˜ ์ถœ๋ ฅ ์ŠคํŠธ๋ฆผ์€ ์ด ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›๊ณ  ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒจํ„ด์œผ๋กœ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์ŠคํŠธ๋ฆผ์ด ๋งŒ๋“ค์–ด์ง„๋‹ค.

OutputStream ํด๋ž˜์Šค์—๋„ ์ถœ๋ ฅ์„ ์œ„ํ•ด ํ•„์š”ํ•œ ๊ธฐ๋ณธ์ ์ธ ๋ฉ”์†Œ๋“œ๋“ค์ด ์ •์˜๋˜์–ด ์žˆ๋‹ค.

  • void flush() : ๋ฒ„ํผ์— ๋‚จ์•„์žˆ๋Š” OutputStream์„์„ ์ถœ๋ ฅ
  • abstract void write(int b) : ์ •์ˆ˜ b์˜ ํ•˜์œ„ 1byte๋ฅผ ์ถœ๋ ฅ
  • void write(byte[] b) : ๋ฒ„ํผ์˜ ๋‚ด์šฉ์„ ์ถœ๋ ฅ
  • void write(byte[] b, int off, int len) : b ๋ฐฐ์—ด ์•ˆ์˜ ์‹œ์ž‘์  off ๋ถ€ํ„ฐ len ๋งŒํผ ์ถœ๋ ฅ
  • void close() : ์‚ฌ์šฉํ•œ ์‹œ์Šคํ…œ ๋ฆฌ์†Œ์Šค๋ฅผ ๋ฐ˜๋‚ฉ ํ›„ OutputStream์„ ๋‹ซ์Œ.

ํŒŒ์ผ ์ฝ๊ณ  ์“ฐ๊ธฐ

์ž๋ฐ”์˜ ๋‚ด์žฅ ํด๋ž˜์Šค์ธ FileReader, FileWriter, BufferedReader, BufferedWriter๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํŒŒ์ผ์„ ์ฝ๊ณ  ์“ธ ์ˆ˜ ์žˆ๋‹ค.

File file = new File(PATH);

FileWriter fw = new FileWriter(file);
FileReader fr = new FileReader(file);
BufferedWriter bw = new BufferedWriter(fw);
BufferedReader br = new BufferedReader(fr);

FileReader, FileWriter์™€ BufferedReader, BufferedWriter๋Š” ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒจํ„ด์ด ์ ์šฉ๋จ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.


Generic

Java 5๋ถ€ํ„ฐ ์ถ”๊ฐ€๋˜์–ด ํด๋ž˜์Šค์™€ ์ธํ„ฐํŽ˜์ด์Šค, ๋ฉ”์†Œ๋“œ๋ฅผ ์ •์˜ํ•  ๋•Œ ํƒ€์ž… ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

  • ํƒ€์ž… ๋ณ€์ˆ˜ : ์ผ๋ฐ˜์ ์œผ๋กœ ๋Œ€๋ฌธ์ž ์•ŒํŒŒ๋ฒณ ํ•œ ๊ธ€์ž๋กœ ํ‘œํ˜„ํ•œ๋‹ค.
    • <T> : Type
    • <E> : Element
    • <K> : Key
    • <N> : Number
    • <V> : Value
    • <R> : Return

์ปดํŒŒ์ผ ์‹œ์˜ ๊ฐ์ฒด์˜ ํƒ€์ž…์„ ์ฒดํฌ๋ฅผ ํ•ด์ฃผ๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•จ์œผ๋กœ์จ ์•ˆ์ •์„ฑ์„ ๋†’์ด๊ณ  ํ˜•๋ณ€ํ™˜์˜ ๋ฒˆ๊ฑฐ๋กœ์›€์„ ์ค„์—ฌ์ค€๋‹ค.

Collection ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ํ”ํžˆ Generic์ด ํ™œ์šฉ๋œ๋‹ค.

//List<T>
List<Integer> listG = new ArrayList<>(); // ์ œ๋„ค๋ฆญ
listG.add(1);
int temp = listG.get(0);

List listNG = new ArrayList(); // ์ œ๋„ค๋ฆญ ์‚ฌ์šฉ X
listNG.add(1);
temp = (int)listNG.get(0); // ํ˜•๋ณ€ํ™˜ ํ•„์š”

Generic์€ Generic ํƒ€์ž…๊ณผ Generic ๋ฉ”์†Œ๋“œ๋กœ ๊ตฌ๋ถ„ํ•  ์ˆ˜ ์žˆ๋‹ค.

Generic ํƒ€์ž…

ํƒ€์ž… ๋ณ€์ˆ˜๊ฐ€ ์žˆ๋Š” ํด๋ž˜์Šค ๋˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค

class GenericClass<T> {
     ...
}

interface  GenericInterface<T> {
     ...
}

Generic ๋ฉ”์†Œ๋“œ

๋งค๊ฐœ ํƒ€์ž…๊ณผ ๋ฆฌํ„ด ํƒ€์ž…์œผ๋กœ ํƒ€์ž… ๋ณ€์ˆ˜๋ฅผ ๊ฐ–๋Š” ๋ฉ”์†Œ๋“œ

public <T, R> R genericMethod(T t) { }

์ œ๋„ค๋ฆญ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ

  1. ์ œ๋„ค๋ฆญ ํƒ€์ž…์˜ ๋ฐฐ์—ด์„ ์ƒ์„ฑํ•  ๊ฒฝ์šฐ : new T[N]์€ ์ปดํŒŒ์ผ ํƒ€์ž„์— ๋ฐฐ์—ด์˜ ํƒ€์ž…์„ ์•Œ ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค.

  2. static ๋ณ€์ˆ˜์— ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ : static ๋ณ€์ˆ˜๋Š” ์ธ์Šคํ„ด์Šค์— ์ข…์†๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ ์ธ์Šคํ„ด์Šค๋ณ„ ํƒ€์ž…์ด ๋ณ€๊ฒฝ๋  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค. (๋‹จ, static ๋ฉ”์†Œ๋“œ์—๋Š” ์ œ๋„ค๋ฆญ ์‚ฌ์šฉ ๊ฐ€๋Šฅ)


Generic์˜ ์ฃผ์š” ๊ฐœ๋…์œผ๋กœ๋Š” Bounded-Type๊ณผ Wild-Card๊ฐ€ ์žˆ๋‹ค.


BoundedType

Bounded-Type์€ ์ œ๋„ค๋ฆญ์œผ๋กœ ์‚ฌ์šฉ๋  ํƒ€์ž… ๋ณ€์ˆ˜์˜ ๋ฒ”์œ„๋ฅผ ์ œํ•œํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

Generic ํƒ€์ž…์— extends๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํƒ€์ž… ๋ณ€์ˆ˜์˜ ๋ฒ”์œ„๋ฅผ ์ œํ•œํ•œ๋‹ค. (์ธํ„ฐํŽ˜์ด์Šค, ํด๋ž˜์Šค ๋ชจ๋‘ ์ƒ๊ด€์—†์ด extends๋ฅผ ์‚ฌ์šฉ)

public class CustomGeneric<T extends Number> {
     ...
}

CustomGeneric<Integer> listI = new CustomGeneric<();
CustomGeneric<String> listS = new CustomGeneric<>(); // Bounded-Type์œผ๋กœ ํƒ€์ž… ๋ณ€์ˆ˜๋ฅผ Number๋กœ ์ œํ•œํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ปดํŒŒ์ผ ์—๋Ÿฌ ๋ฐœ์ƒ!
public class CustomGeneric<T extends ClassName & InterfaceName> { // & ๊ธฐํ˜ธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํƒ€์ž… ๋ณ€์ˆ˜๋ฅผ ํด๋ž˜์Šค์™€ ์ธํ„ฐํŽ˜์ด์Šค 2๊ฐœ๋กœ ์ œํ•œ ๊ฐ€๋Šฅ 
     ...
}

WildCard

์ œ๋„ค๋ฆญ ํƒ€์ž…์„ ๋ฉ”์†Œ๋“œ์˜ ๋งค๊ฐœ๊ฐ’์œผ๋กœ ์ „๋‹ฌํ•  ๋•Œ ๊ตฌ์ฒด์ ์ธ ํƒ€์ž…์œผ๋กœ๋งŒ ํƒ€์ž… ์ œํ•œ์ด ์ƒ๊ธด๋‹ค ๊ทธ๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ์™€์ผ๋“œ ์นด๋“œ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

? ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์™€์ผ๋“œ ์นด๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

  • ์ œ๋„ค๋ฆญ ํƒ€์ž… <?> : ์ œํ•œ ์—†์Œ. ๋ชจ๋“  ํด๋ž˜์Šค๋‚˜ ์ธํ„ฐํŽ˜์ด์Šค ๊ฐ€๋Šฅ
  • ์ œ๋„ค๋ฆญ ํƒ€์ž… <? extends ์ƒ์œ„ ํƒ€์ž…> : ํƒ€์ž…์˜ ์ƒํ•œ์„  ์ง€์ •(ํ•ด๋‹น ํƒ€์ž… ๋ฐ ํ•˜์œ„ํƒ€์ž…๋งŒ, ์ตœ์ƒ์ด ์ œ์‹œํ•œ ํƒ€์ž…), ์ตœ๋Œ€ ์ œ์‹œ๋œ ์ƒ์œ„ ํƒ€์ž…๋ณด๋‹ค ๋” ์ƒ์œ„ ํƒ€์ž…์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Œ
  • ์ œ๋„ค๋ฆญ ํƒ€์ž… <? super ํ•˜์œ„ ํƒ€์ž…> : ํƒ€์ž…์˜ ํ•˜ํ•œ์„  ์ง€์ •(ํ•ด๋‹น ํƒ€์ž… ๋ฐ ์ƒ์œ„ํƒ€์ž…๋งŒ, ์ตœํ•˜๊ฐ€ ์ œ์‹œํ•œ ํƒ€์ž…), ์ตœ์†Œ ์ œ์‹œ๋œ ํ•˜์œ„ ํƒ€์ž…๋ณด๋‹ค ๋” ํ•˜์œ„ ํƒ€์ž…์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Œ

Erasure

  • ์ œ๋„ค๋ฆญ์˜ ํƒ€์ž… ์†Œ๊ฑฐ(Generics Type Erasure) : ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ์ œ๋„ค๋ฆญ ํƒ€์ž…์„ ์ด์šฉํ•ด ์†Œ์ŠคํŒŒ์ผ์„ ๊ฒ€์‚ฌํ•˜๊ณ  ๋Ÿฐํƒ€์ž„์—๋Š” ํ•ด๋‹น ํƒ€์ž…์˜ ์ •๋ณด๋ฅผ ์•Œ ์ˆ˜ ์—†๋‹ค๋Š” ๊ฐœ๋…์ด๋‹ค. ์ฆ‰, ์ปดํŒŒ์ผ๋œ ํŒŒ์ผ*.class์—๋Š” ์ œ๋„ค๋ฆญ ํƒ€์ž…์— ๋Œ€ํ•œ ์ •๋ณด๊ฐ€ ์—†๋‹ค๋Š” ๋œป.

Erasure ๊ทœ์น™

  • UnBounded-Type์€ Object
    • ex) (<?>, <T>) => Object
  • Bounded-Type์€ extends ๋’ค์— ์ž‘์„ฑํ•œ ๊ฐ์ฒด
    • ex) <T extends Number> => Number

Lambda

๋žŒ๋‹ค์‹(Lambda expression)์€ ๋ฉ”์†Œ๋“œ๋ฅผ ๊ฐ„๋‹จํ•˜๋ฉด์„œ ๋ช…ํ™•ํ•œ ์‹(expression)์œผ๋กœ ํ‘œํ˜„ํ•œ ๊ฒƒ์ด๋‹ค.

๋žŒ๋‹ค์‹์€ ์ธํ•ด ์ด๋ฆ„๊ณผ ๋ฆฌํ„ดํƒ€์ž…์ด ํ•„์š”์—†์–ด, ์ต๋ช… ํ•จ์ˆ˜(anonymous function)๋ผ๊ณ ๋„ ํ•œ๋‹ค.

๋žŒ๋‹ค์‹์€ ๋ฉ”์†Œ๋“œ์™€ ๋™๋“ฑํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด์ง€๋งŒ, ์‚ฌ์‹ค ๋žŒ๋‹ค์‹์€ ์ต๋ช… ํด๋ž˜์Šค์˜ ๊ฐ์ฒด์™€ ๋™๋“ฑํ•˜์—ฌ ๋Ÿฐํƒ€์ž„ ์‹œ์— ์ธํ„ฐํŽ˜์ด์Šค์˜ ์ต๋ช… ๊ตฌํ˜„ ๊ฐ์ฒด๋กœ ์ƒ์„ฑ๋˜๊ณ  ๋Œ€์ž…๋˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค์— ๋”ฐ๋ผ ๊ตฌํ˜„ ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ๊ฒฐ์ •๋œ๋‹ค.

Lambda์˜ ๋„์ž…์œผ๋กœ ์ธํ•ด ์ž๋ฐ”๋Š” ๊ฐ์ฒด ์ง€ํ–ฅ ์–ธ์–ด์ธ ๋™์‹œ์— ํ•จ์ˆ˜ํ˜• ์–ธ์–ด๊ฐ€ ๋˜์—ˆ๋‹ค.


Lambda ์‚ฌ์šฉ๋ฒ•

๋ฉ”์†Œ๋“œ์—์„œ ๋ฉ”์†Œ๋“œ์ด๋ฆ„๊ณผ ๋ฆฌํ„ดํƒ€์ž…์„ ์ œ๊ฑฐํ•˜๊ณ  ๋งค๊ฐœ๋ณ€์ˆ˜ {์‹คํ–‰์ฝ”๋“œ} ์‚ฌ์ด์— -> ํ™”์‚ดํ‘œ๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ

๋งค๊ฐœ๋ณ€์ˆ˜ -> {์‹คํ–‰์ฝ”๋“œ} ๋กœ ๋žŒ๋‹ค์‹์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

๋ฉ”์†Œ๋“œ๋ฅผ ์„ ์–ธ ํ•  ๋•Œ๋„ ๋์— ์„ธ๋ฏธ์ฝœ๋ก  ;์„ ๋ถ™์ด์ง€ ์•Š๋“ฏ์ด, ๋žŒ๋‹ค์‹ ๋˜ํ•œ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์„ธ๋ฏธ์ฝœ๋ก  ;์„ ๋ถ™์ด์ง€ ์•Š๋Š”๋‹ค

// ๋ฉ”์†Œ๋“œ
๋ฆฌํ„ดํƒ€์ž… ๋ฉ”์†Œ๋“œ์ด๋ฆ„ (๋งค๊ฐœ๋ณ€์ˆ˜ํƒ€์ž… ๋งค๊ฐœ๋ณ€์ˆ˜) {
    ์‹คํ–‰์ฝ”๋“œ
}
// ๋žŒ๋‹ค์‹
((๋งค๊ฐœ๋ณ€์ˆ˜) -> {์‹คํ–‰์ฝ”๋“œ})
// ๋งค๊ฐœ๋ณ€์ˆ˜ :
// ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ํ•˜๋‚˜์ผ ๋•Œ๋Š” ()๋ฅผ ์ƒ๋žตํ•  ์ˆ˜ ์žˆ๋‹ค.   
// ๋‹จ, ๋งค๊ฐœ๋ณ€์ˆ˜ ํƒ€์ž…์ด ์žˆ์œผ๋ฉด(๋Œ€๋ถ€๋ถ„์˜ ๋งค๊ฐœ๋ณ€์ˆ˜ ํƒ€์ž…์€ ์ถ”๋ก ์ด ๊ฐ€๋Šฅํ•ด์„œ ์ƒ๋žต ๊ฐ€๋Šฅ) ()๋ฅผ ์ƒ๋žตํ•  ์ˆ˜ ์—†๋‹ค.  
// ์ฝ”๋“œ : 
// ์‹คํ–‰์ฝ”๋“œ๊ฐ€ ํ•˜๋‚˜์ผ ๋•Œ๋Š” {}๋ฅผ ์ƒ๋žตํ•  ์ˆ˜ ์žˆ๋‹ค.   
// ๋‹จ, {} ์•ˆ์˜ ์‹คํ–‰์ฝ”๋“œ์— return ํ‚ค์›Œ๋“œ๊ฐ€ ์‚ฌ์šฉ๋˜๋Š” ๊ฒฝ์šฐ {}๋ฅผ ์ƒ๋žตํ•  ์ˆ˜ ์—†๋‹ค. 


// ๋ฉ”์†Œ๋“œ
int max(int a, int b) {
    return a > b ? a : b;
}
// ๋žŒ๋‹ค์‹
((a, b) -> a > b ? a : b) // ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ a์™€ b 2๊ฐœ์ด๋ฏ€๋กœ () ์ƒ๋žต ๋ถˆ๊ฐ€. ๊ทธ๋ฆฌ๊ณ  return ํ‚ค์›Œ๋“œ๊ฐ€ ์‚ฌ์šฉ๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ {} ์ƒ๋žต ๊ฐ€๋Šฅ

List๋ฅผ ๋žŒ๋‹ค์‹์œผ๋กœ ์กฐ์ž‘ํ•˜๋Š” ๊ฐ„๋‹จํ•œ ์˜ˆ์‹œ๋ฅผ ์‚ดํŽด๋ณด์ž.

ArrayList<Integer> list = new ArrayList<Integer>();
for(int i=1; i<=10; ++i) list.add(i);
		
list.replaceAll(e -> e+10); // ๋ชจ๋“  ์š”์†Œ์— 10์”ฉ ๋”ํ•˜๊ธฐ
list.removeIf(e -> e%2==1); // ํ™€์ˆ˜๊ฐ’ ์š”์†Œ ์—†์• ๊ธฐ
list.forEach(e -> System.out.println(e)); // ๋ชจ๋“  ์š”์†Œ ์ถœ๋ ฅ	

๊ทธ๋ฆฌ๊ณ  PS๋ฅผ ํ•˜๋‹ค๋ณด๋ฉด ์ž์ฃผ ์ ‘ํ•˜๊ฒŒ ๋˜๋Š” Comparator ์ธํ„ฐํŽ˜์ด์Šค์˜ compare๋ฉ”์†Œ๋“œ ๋˜ํ•œ ์ต๋ช… ๊ตฌํ˜„ ๊ฐ์ฒด๋กœ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์ง€๋งŒ, ๋žŒ๋‹ค์‹์œผ๋กœ ๊ฐ„๋‹จํ•˜๊ฒŒ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

// Comparator ์ธํ„ฐํŽ˜์ด์Šค์˜ compare๋ฉ”์†Œ๋“œ ์ต๋ช… ๊ตฌํ˜„ ๊ฐ์ฒด
Arrays.sort(time, new Comparator<int[]>() {
			@Override
			public int compare(int[] t1, int[] t2) {
				if(t1[0] == t2[0]) return t1[1] - t2[1];
				else return t1[0] - t2[0];
			}
		});
// ๋žŒ๋‹ค์‹
Arrays.sort(time, (t1, t2)->{
			if(t1[0] == t2[0]) return t1[1] - t2[1];
			else return t1[0] - t2[0];
		});

ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค

๋žŒ๋‹ค ํ‘œํ˜„์‹์œผ๋กœ ๊ตฌํ˜„์ด ๊ฐ€๋Šฅํ•œ ์ธํ„ฐํŽ˜์ด์Šค๋Š” ์ถ”์ƒ ๋ฉ”์„œ๋“œ๋ฅผ 1๊ฐœ๋งŒ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋งŒ ๊ฐ€๋Šฅํ•˜๋‹ค.

๊ทธ๋ž˜์„œ ์ถ”์ƒ ๋ฉ”์„œ๋“œ๊ฐ€ 1๊ฐœ์ธ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋ผ๊ณ  ํ•œ๋‹ค.

// ์•ฝ์‹ ์‚ฌ์šฉ ์˜ˆ์ œ
@FunctionalInterface
interface CustomFunction{
    void customMethod();
}

// ์‚ฌ์šฉ 1. ๋žŒ๋‹ค์‹์„ ์ฐธ์กฐํ•˜๋Š” ์ฐธ์กฐ๋ณ€์ˆ˜๋กœ ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ง€์ •ํ•˜๊ณ , ์ฐธ์กฐ๋ณ€์ˆ˜์—์„œ ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœ
CustomFunction cf = () -> System.out.println("This is FunctionalInterface");
customMethod(cf); // This is FunctionalInterface

// ์‚ฌ์šฉ 2. ์ฐธ์กฐ๋ณ€์ˆ˜ ์—†์ด ๋ฐ”๋กœ ๋žŒ๋‹ค์‹์„ ๋ฉ”์†Œ๋“œ๋กœ ์‚ฌ์šฉ 
customMethod() -> System.out.println("This is FunctionalInterface");
// ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋ฐ›๊ณ  ๋ฆฌํ„ดํ•ด์ฃผ๋Š” ์˜ˆ์ œ
@FunctionalInterface
interface CustomFunction{
    int customMethod(int a, int b);
}

CustomFunction cf = (a, b) -> a > b ? a : b;
int bigNum = cf.customMethod(1, 2); 

@FunctionalInterface : ํ•ด๋‹น ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋ผ๋Š”๊ฑธ ์•Œ๋ ค์ฃผ๋Š” ์• ๋…ธํ…Œ์ด์…˜, ์ธํ„ฐํŽ˜์ด์Šค ์„ ์–ธ์‹œ ํ•ด๋‹น ์• ๋…ธํ…Œ์ด์…˜์„ ๋ถ™์ด๋ฉด 2๊ฐœ ์ด์ƒ์˜ ์ถ”์ƒ ๋ฉ”์†Œ๋“œ๊ฐ€ ์„ ์–ธ๋˜์ง€ ์•Š์•˜๋Š”์ง€ ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ฒดํฌํ•˜์—ฌ 2๊ฐœ ์ด์ƒ์˜ ์ถ”์ƒ ๋ฉ”์†Œ๋“œ๊ฐ€ ์„ ์–ธ๋˜์–ด ์žˆ๋‹ค๋ฉด ์ปดํŒŒ์ผ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

๋ชจ๋“  ์• ๋…ธํ…Œ์ด์…˜๋“ค์˜ ๊ธฐ๋Šฅ์ด ๊ทธ๋ ‡๋“ฏ, @FunctionalInterface์€ ์ปดํŒŒ์ผ๋Ÿฌ์—๊ฒŒ ํ™•์ธ์„ ๋ถ€ํƒํ•˜๋Š” ๊ฒƒ์ผ ๋ฟ ์•ˆ๋ถ™์–ด์žˆ๋‹ค๊ณ  ํ•ด์„œ ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋กœ ๋™์ž‘ํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค.

์ž๋ฐ”์—์„œ ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ œ๊ณตํ•˜๋Š” ํ‘œ์ค€ API java.util.function๋ฅผ ์ œ๊ณตํ•ด์ค€๋‹ค.


Variable Capture

Variable Capture๋Š” ๋žŒ๋‹ค์‹์—์„œ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋„˜๊ฒจ์ง„ ๋ณ€์ˆ˜๊ฐ€ ์•„๋‹Œ ์™ธ๋ถ€์—์„œ ์ •์˜๋œ ๋ณ€์ˆ˜๋ฅผ ์ฐธ์กฐํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค.

๋žŒ๋‹ค์‹์—์„œ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ ๋ณ€์ˆ˜๋“ค์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

  1. ๋กœ์ปฌ ๋ณ€์ˆ˜
  2. static ๋ณ€์ˆ˜
  3. ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜

Variable Capture์—๋Š” ์œ„ ๋ณ€์ˆ˜๋“ค ์ค‘ 1. ๋กœ์ปฌ ๋ณ€์ˆ˜์— ๋Œ€ํ•œ ์ œ์•ฝ ์กฐ๊ฑด์ด ์กด์žฌํ•œ๋‹ค.

  1. ๋กœ์ปฌ ๋ณ€์ˆ˜๋Š” final์œผ๋กœ ์„ ์–ธ๋˜์–ด์•ผ ํ•œ๋‹ค,
  2. final๋กœ ์„ ์–ธ๋˜์–ด ์žˆ์ง€ ์•Š์€ ๋กœ์ปฌ ๋ณ€์ˆ˜๋Š” Effectively Final(์œ ์‚ฌ final; final ์ฒ˜๋Ÿผ ๋™์ž‘)์ด์–ด์•ผ ํ•œ๋‹ค. ์ฆ‰, ๊ฐ’์˜ ์žฌํ• ๋‹น์ด ์ผ์–ด๋‚˜๋ฉด ์•ˆ๋œ๋‹ค.

๋”ฐ๋ผ์„œ, ๋žŒ๋‹ค์‹์—์„œ ๋กœ์ปฌ ๋ณ€์ˆ˜๋งŒ ๋ณ€๊ฒฝ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๊ณ , ๋‚˜๋จธ์ง€ ๋ณ€์ˆ˜๋“ค์€ ์ฝ๊ธฐ ๋ฐ ์“ฐ๊ธฐ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.

์ด๋Ÿฌํ•œ ์ œ์•ฝ์ด ์กด์žฌํ•˜๋Š” ์ด์œ ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

1์ฃผ์ฐจ์—์„œ ์ •๋ฆฌํ•˜์˜€๋“ฏ์ด, JVM์—์„œ ๋กœ์ปฌ ๋ณ€์ˆ˜๋Š” ์Šคํƒ ์˜์—ญ์— ์ƒ์„ฑ๋œ๋‹ค.

์‹ค์ œ ๋ฉ”๋ชจ๋ฆฌ์™€๋Š” ๋‹ฌ๋ฆฌ JVM์—์„œ ์Šคํƒ ์˜์—ญ์€ ์“ฐ๋ ˆ๋“œ๋งˆ๋‹ค ๋ณ„๋„์˜ ์Šคํƒ์ด ๋˜ ์ƒ์„ฑ๋˜์–ด ์“ฐ๋ ˆ๋“œ๋ผ๋ฆฌ๋Š” ๋กœ์ปฌ ๋ณ€์ˆ˜ ๊ณต์œ ๊ฐ€ ๋ถˆ๊ฐ€๋Šฅ ํ•˜๋‹ค.

๊ทธ๋ฆฌ๊ณ  JVM์—์„œ ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜๋Š” ํž™ ์˜์—ญ์— ์ƒ์„ฑ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜๋Š” ์“ฐ๋ ˆ๋“œ๋ผ๋ฆฌ ๊ณต์œ ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.

๋žŒ๋‹ค์‹์€ ๋กœ์ปฌ ๋ณ€์ˆ˜๊ฐ€ ์กด์žฌํ•˜๋Š” ์Šคํƒ์— ์ง์ ‘ ์ ‘๊ทผํ•˜์ง€ ์•Š๊ณ , ๋กœ์ปฌ ๋ณ€์ˆ˜๋ฅผ ์ž์‹ (๋žŒ๋‹ค๊ฐ€ ๋™์ž‘ํ•˜๋Š” ๋ณ„๋„์˜ ์“ฐ๋ ˆ๋“œ)์˜ ์Šคํƒ์— ๋ณต์‚ฌํ•œ๋‹ค.

๊ทธ๋ž˜์„œ ๋งŒ์•ฝ ์›๋ž˜ ์ง€์—ญ ๋ณ€์ˆ˜๊ฐ€ ์žˆ๋Š” ์“ฐ๋ ˆ๋“œ๋Š” ์‚ฌ๋ผ์ ธ์„œ ๋กœ์ปฌ ๋ณ€์ˆ˜๊ฐ€ ์‚ฌ๋ผ์ ธ๋„ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š”๋‹ค.

๊ทธ๋ž˜์„œ ์ง„์งœ ๋ฌธ์ œ๋Š” ๋ฉ€ํ‹ฐ ์“ฐ๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ, ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์“ฐ๋ ˆ๋“œ์—์„œ ๋žŒ๋‹ค์‹์„ ์‚ฌ์šฉํ•˜๋ฉด์„œ ๋žŒ๋‹ค ์บก์ณ๋ง์ด ๊ณ„์† ๋ฐœ์ƒํ•˜๋Š”๋ฐ ์ด ๋•Œ ์™ธ๋ถ€ ๋ณ€์ˆ˜ ๊ฐ’์˜ ๋ถˆ๋ณ€์„ฑ์„ ๋ณด์žฅํ•˜์ง€ ๋ชปํ•œ๋‹ค๋ฉด ๋™๊ธฐ(sync)ํ™” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.

์ด๋Ÿฌํ•œ ๋ฌธ์ œ ๋•Œ๋ฌธ์— ์ง€์—ญ๋ณ€์ˆ˜์— ๋Œ€ํ•œ ์ œ์•ฝ์‚ฌํ•ญ์ด ์กด์žฌํ•˜๊ฒŒ ๋˜๋Š” ๊ฒƒ์ด๋‹ค.

static ๋ณ€์ˆ˜๋‚˜ ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜๋Š” ์Šคํƒ ์˜์—ญ์ด ์•„๋‹Œ ํž™ ์˜์—ญ์— ์œ„์น˜ํ•˜๊ณ , ํž™ ์˜์—ญ์€ ๋ชจ๋“  ์“ฐ๋ ˆ๋“œ๊ฐ€ ๊ณต์œ ํ•˜๊ณ  ์žˆ๋Š” ๋ฉ”๋ชจ๋ฆฌ ์˜์—ญ์ด๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ’์„ ์ง์ ‘ ์ ‘๊ทผํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฌธ์ œ๊ฐ€ ์—†๋Š” ๊ฒƒ์ด๋‹ค.


๋ฉ”์†Œ๋“œ, ์ƒ์„ฑ์ž ๋ ˆํผ๋Ÿฐ์Šค

Method Reference

๋žŒ๋‹ค์‹์ด ํ•˜๋‚˜์˜ ๋ฉ”์†Œ๋“œ๋งŒ ํ˜ธ์ถœํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” '๋ฉ”์†Œ๋“œ ์ฐธ์กฐ(Method References)'๋ฅผ ํ†ตํ•ด ๋žŒ๋‹ค์‹์„ ๋” ๊ฐ„๋žตํ•˜๊ฒŒ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

๋ฉ”์†Œ๋“œ๋ฅผ ์ฐธ์กฐํ•ด์„œ ๋งค๊ฐœ ๋ณ€์ˆ˜์˜ ์ •๋ณด ๋ฐ ๋ฆฌํ„ด ํƒ€์ž…์„ ์•Œ์•„๋‚ธ๋‹ค. ๋žŒ๋‹ค์‹์—์„œ ๋ถˆํ•„์š”ํ•œ ๋งค๊ฐœ ๋ณ€์ˆ˜๋ฅผ ์ œ๊ฑฐํ•˜๋Š” ๊ฒƒ์ด ๋ชฉ์ ์ด๋‹ค.

ClassName::MethodName

or

ReferenceVariable::MethodName

Integer parseInt(String s) { 				// ๋ฉ”์†Œ๋“œ
    return Integer.parseInt(s);
}
Function<String, Integer> f = s -> Integer.parseInt(s); // ๋žŒ๋‹ค์‹
Function<String, Integer> f = Integer::parseInt; 	// ๋ฉ”์†Œ๋“œ ์ฐธ์กฐ
Function<String, String, Boolean> f = (s1, s2) -> s1.equlas(s2); 	// ๋žŒ๋‹ค์‹
Function<String, String, Boolean> f = String::equals; 			// ๋ฉ”์†Œ๋“œ ์ฐธ์กฐ

Constructor References

์ƒ์„ฑ์ž ์ฐธ์กฐ(Constructor References)๋Š” Constructor๋ฅผ ์ƒ์„ฑํ•ด์ฃผ๋Š” ์ฝ”๋“œ๋กœ์จ ๊ฐ์ฒด ์ƒ์„ฑ์„ ์˜๋ฏธํ•œ๋‹ค.

ClassName::new

Function<Integer, int[]> f = x -> new int[x];   // ๋žŒ๋‹ค์‹
Function<Integer, int[]> f = int[]::new;  	// ์ƒ์„ฑ์ž ์ฐธ์กฐ
Supplier<CustomClass> s = () -> new CustomClass(); 	// ๋žŒ๋‹ค์‹
Supplier<CustomClass> s = CustomClass:new; 		// ์ƒ์„ฑ์ž ์ฐธ์กฐ

์ข‹์€ ์›นํŽ˜์ด์ง€ ์ฆ๊ฒจ์ฐพ๊ธฐ