[{"data":1,"prerenderedAt":787},["ShallowReactive",2],{"post-document:\u002Fjava\u002Fbasics\u002F2026\u002F08\u002F11\u002Fjava-generics\u002F":3},{"id":4,"title":5,"body":6,"categories":767,"date":769,"description":770,"extension":771,"image":772,"key_concepts":772,"last_modified_at":772,"legacyPath":773,"meta":774,"navigation":170,"part":776,"path":777,"published":170,"robots":772,"seo":778,"series":779,"stem":780,"strengths":772,"summary":772,"tags":781,"tradeoffs":772,"__hash__":786},"posts\u002Fposts\u002FBackend\u002FJAVA\u002Fbasics\u002F2026-08-11-java-generics.md","Java 기초 Part 4: 제네릭",{"type":7,"value":8,"toc":755},"minimark",[9,13,18,128,135,139,148,184,200,204,211,241,244,259,268,277,292,295,299,304,328,334,338,341,356,359,374,380,384,394,457,460,513,521,564,576,580,595,611,615,642,653,662,670,674,677,692,695,710,716,720,741,746,751],[10,11,5],"h2",{"id":12},"java-기초-part-4-제네릭",[14,15,17],"h3",{"id":16},"_1-먼저-알아둘-단어","1. 먼저 알아둘 단어",[19,20,21,37],"table",{},[22,23,24],"thead",{},[25,26,27,31,34],"tr",{},[28,29,30],"th",{},"단어",[28,32,33],{},"정의",[28,35,36],{},"예시",[38,39,40,55,68,85,99,112],"tbody",{},[25,41,42,46,49],{},[43,44,45],"td",{},"제네릭(Generic)",[43,47,48],{},"클래스나 메서드가 사용할 데이터 타입을 외부에서 지정할 수 있게 하는 기능",[43,50,51],{},[52,53,54],"code",{},"Box\u003CT>",[25,56,57,60,63],{},[43,58,59],{},"타입 매개변수(Type Parameter)",[43,61,62],{},"아직 정해지지 않은 타입을 나타내는 이름",[43,64,65],{},[52,66,67],{},"T",[25,69,70,73,76],{},[43,71,72],{},"타입 인자(Type Argument)",[43,74,75],{},"제네릭을 사용할 때 실제로 지정하는 타입",[43,77,78,81,82],{},[52,79,80],{},"Box\u003CString>","의 ",[52,83,84],{},"String",[25,86,87,90,93],{},[43,88,89],{},"타입 안정성(Type Safety)",[43,91,92],{},"잘못된 타입의 값을 컴파일 단계에서 막는 성질",[43,94,95,98],{},[52,96,97],{},"List\u003CString>","에는 문자열만 저장",[25,100,101,104,107],{},[43,102,103],{},"Raw Type",[43,105,106],{},"타입 인자를 생략한 제네릭 타입",[43,108,109],{},[52,110,111],{},"ArrayList list",[25,113,114,117,120],{},[43,115,116],{},"Wrapper Class",[43,118,119],{},"기본형을 객체처럼 다루기 위한 참조 타입",[43,121,122,81,125],{},[52,123,124],{},"int",[52,126,127],{},"Integer",[129,130,131],"blockquote",{},[132,133,134],"p",{},"제네릭은 클래스나 메서드가 다룰 데이터 타입을 나중에 지정할 수 있게 해주는 기능이다.",[14,136,138],{"id":137},"_2-제네릭의-기본-사용법","2. 제네릭의 기본 사용법",[132,140,141,144,145,147],{},[52,142,143],{},"ArrayList\u003CString>","은 이 리스트에 ",[52,146,84],{}," 타입만 저장하겠다는 뜻이다.",[149,150,155],"pre",{"className":151,"code":152,"language":153,"meta":154,"style":154},"language-java shiki shiki-themes github-light github-dark","ArrayList\u003CString> history = new ArrayList\u003C>();\n\nhistory.add(\"10 + 20 = 30\"); \u002F\u002F 가능\nhistory.add(100);            \u002F\u002F 컴파일 오류\n","java","",[52,156,157,165,172,178],{"__ignoreMap":154},[158,159,162],"span",{"class":160,"line":161},"line",1,[158,163,164],{},"ArrayList\u003CString> history = new ArrayList\u003C>();\n",[158,166,168],{"class":160,"line":167},2,[158,169,171],{"emptyLinePlaceholder":170},true,"\n",[158,173,175],{"class":160,"line":174},3,[158,176,177],{},"history.add(\"10 + 20 = 30\"); \u002F\u002F 가능\n",[158,179,181],{"class":160,"line":180},4,[158,182,183],{},"history.add(100);            \u002F\u002F 컴파일 오류\n",[132,185,186,187,189,190,193,194,196,197,199],{},"여기서 ",[52,188,84],{},"은 타입 인자다. ",[52,191,192],{},"history.add(100)","은 ",[52,195,84],{}," 전용 리스트에 ",[52,198,127],{},"를 넣으려고 했기 때문에 컴파일 오류가 발생한다.",[14,201,203],{"id":202},"_3-제네릭이-없던-방식","3. 제네릭이 없던 방식",[132,205,206,207,210],{},"타입 인자를 지정하지 않은 ",[52,208,209],{},"ArrayList","를 Raw Type이라고 한다.",[149,212,214],{"className":151,"code":213,"language":153,"meta":154,"style":154},"ArrayList list = new ArrayList();\n\nlist.add(\"민형\");\nlist.add(100);\nlist.add(true);\n",[52,215,216,221,225,230,235],{"__ignoreMap":154},[158,217,218],{"class":160,"line":161},[158,219,220],{},"ArrayList list = new ArrayList();\n",[158,222,223],{"class":160,"line":167},[158,224,171],{"emptyLinePlaceholder":170},[158,226,227],{"class":160,"line":174},[158,228,229],{},"list.add(\"민형\");\n",[158,231,232],{"class":160,"line":180},[158,233,234],{},"list.add(100);\n",[158,236,238],{"class":160,"line":237},5,[158,239,240],{},"list.add(true);\n",[132,242,243],{},"Raw Type에는 여러 타입의 값을 넣을 수 있지만, 값을 꺼낼 때 문제가 생긴다.",[149,245,247],{"className":151,"code":246,"language":153,"meta":154,"style":154},"Object value = list.get(0);\nString name = (String) list.get(0);\n",[52,248,249,254],{"__ignoreMap":154},[158,250,251],{"class":160,"line":161},[158,252,253],{},"Object value = list.get(0);\n",[158,255,256],{"class":160,"line":167},[158,257,258],{},"String name = (String) list.get(0);\n",[132,260,261,262,264,265,267],{},"컴파일러는 꺼낸 값이 ",[52,263,84],{},"인지 ",[52,266,127],{},"인지 확신할 수 없으므로 직접 형변환해야 한다.",[149,269,271],{"className":151,"code":270,"language":153,"meta":154,"style":154},"String name = (String) list.get(1);\n",[52,272,273],{"__ignoreMap":154},[158,274,275],{"class":160,"line":161},[158,276,270],{},[132,278,279,280,283,284,287,288,291],{},"하지만 인덱스 ",[52,281,282],{},"1","에는 정수 ",[52,285,286],{},"100","이 들어 있으므로 실행 중에 ",[52,289,290],{},"ClassCastException","이 발생할 수 있다.",[132,293,294],{},"이러한 문제를 방지하기 위해 제네릭을 사용한다.",[14,296,298],{"id":297},"_4-제네릭의-장점","4. 제네릭의 장점",[300,301,303],"h4",{"id":302},"타입-안정성","타입 안정성",[149,305,307],{"className":151,"code":306,"language":153,"meta":154,"style":154},"ArrayList\u003CString> list = new ArrayList\u003C>();\n\nlist.add(\"민형\"); \u002F\u002F 가능\nlist.add(100);    \u002F\u002F 컴파일 오류\n",[52,308,309,314,318,323],{"__ignoreMap":154},[158,310,311],{"class":160,"line":161},[158,312,313],{},"ArrayList\u003CString> list = new ArrayList\u003C>();\n",[158,315,316],{"class":160,"line":167},[158,317,171],{"emptyLinePlaceholder":170},[158,319,320],{"class":160,"line":174},[158,321,322],{},"list.add(\"민형\"); \u002F\u002F 가능\n",[158,324,325],{"class":160,"line":180},[158,326,327],{},"list.add(100);    \u002F\u002F 컴파일 오류\n",[132,329,330,331,333],{},"컴파일러는 처음부터 이 리스트가 ",[52,332,84],{},"만 저장하는 곳이라는 사실을 알고 있다. 따라서 잘못된 타입을 실행 전에 차단한다. 이것이 타입 안정성이다.",[300,335,337],{"id":336},"형변환-불필요","형변환 불필요",[132,339,340],{},"제네릭이 없다면 값을 꺼낸 뒤 직접 형변환해야 한다.",[149,342,344],{"className":151,"code":343,"language":153,"meta":154,"style":154},"Object value = list.get(0); \nString name = (String) value; \n",[52,345,346,351],{"__ignoreMap":154},[158,347,348],{"class":160,"line":161},[158,349,350],{},"Object value = list.get(0); \n",[158,352,353],{"class":160,"line":167},[158,354,355],{},"String name = (String) value;\n",[132,357,358],{},"제네릭을 사용하면 꺼낸 값의 타입을 컴파일러가 알고 있다.",[149,360,362],{"className":151,"code":361,"language":153,"meta":154,"style":154},"ArrayList\u003CString> list = new ArrayList\u003C>(); \nString name = list.get(0);\n",[52,363,364,369],{"__ignoreMap":154},[158,365,366],{"class":160,"line":161},[158,367,368],{},"ArrayList\u003CString> list = new ArrayList\u003C>(); \n",[158,370,371],{"class":160,"line":167},[158,372,373],{},"String name = list.get(0);\n",[132,375,376,377,379],{},"따라서 바로 ",[52,378,84],{}," 변수로 받을 수 있다.",[300,381,383],{"id":382},"여러-타입에-재사용","여러 타입에 재사용",[132,385,386,387,390,391,393],{},"다음 ",[52,388,389],{},"Box"," 클래스는 ",[52,392,84],{},"만 저장할 수 있다.",[149,395,397],{"className":151,"code":396,"language":153,"meta":154,"style":154},"class Box {\n    private String value; \n\n    public void setValue(String value) {\n        this.value = value; \n    }\n\n    public String getValue() {\n        return value; \n    }\n}\n",[52,398,399,404,409,413,418,423,429,434,440,446,451],{"__ignoreMap":154},[158,400,401],{"class":160,"line":161},[158,402,403],{},"class Box {\n",[158,405,406],{"class":160,"line":167},[158,407,408],{},"    private String value; \n",[158,410,411],{"class":160,"line":174},[158,412,171],{"emptyLinePlaceholder":170},[158,414,415],{"class":160,"line":180},[158,416,417],{},"    public void setValue(String value) {\n",[158,419,420],{"class":160,"line":237},[158,421,422],{},"        this.value = value; \n",[158,424,426],{"class":160,"line":425},6,[158,427,428],{},"    }\n",[158,430,432],{"class":160,"line":431},7,[158,433,171],{"emptyLinePlaceholder":170},[158,435,437],{"class":160,"line":436},8,[158,438,439],{},"    public String getValue() {\n",[158,441,443],{"class":160,"line":442},9,[158,444,445],{},"        return value; \n",[158,447,449],{"class":160,"line":448},10,[158,450,428],{},[158,452,454],{"class":160,"line":453},11,[158,455,456],{},"}\n",[132,458,459],{},"제네릭을 사용하면 저장할 타입을 나중에 정할 수 있다.",[149,461,463],{"className":151,"code":462,"language":153,"meta":154,"style":154},"class Box\u003CT> {\n    private T value;\n\n    public void setValue(T value) {\n        this.value = value; \n    }\n\n    public T getValue() {\n        return value; \n    }\n}\n",[52,464,465,470,475,479,484,488,492,496,501,505,509],{"__ignoreMap":154},[158,466,467],{"class":160,"line":161},[158,468,469],{},"class Box\u003CT> {\n",[158,471,472],{"class":160,"line":167},[158,473,474],{},"    private T value;\n",[158,476,477],{"class":160,"line":174},[158,478,171],{"emptyLinePlaceholder":170},[158,480,481],{"class":160,"line":180},[158,482,483],{},"    public void setValue(T value) {\n",[158,485,486],{"class":160,"line":237},[158,487,422],{},[158,489,490],{"class":160,"line":425},[158,491,428],{},[158,493,494],{"class":160,"line":431},[158,495,171],{"emptyLinePlaceholder":170},[158,497,498],{"class":160,"line":436},[158,499,500],{},"    public T getValue() {\n",[158,502,503],{"class":160,"line":442},[158,504,445],{},[158,506,507],{"class":160,"line":448},[158,508,428],{},[158,510,511],{"class":160,"line":453},[158,512,456],{},[132,514,186,515,517,518,520],{},[52,516,67],{},"는 타입 매개변수이며, 실제 타입은 ",[52,519,389],{}," 객체를 사용할 때 결정한다.",[149,522,524],{"className":151,"code":523,"language":153,"meta":154,"style":154},"Box\u003CString> stringBox = new Box\u003C>();\nBox\u003CInteger> numberBox = new Box\u003C>();\n\nstringBox.setValue(\"민형\");\nnumberBox.setValue(100);\n\nString name = stringBox.getValue();\nInteger number = numberBox.getValue();\n",[52,525,526,531,536,540,545,550,554,559],{"__ignoreMap":154},[158,527,528],{"class":160,"line":161},[158,529,530],{},"Box\u003CString> stringBox = new Box\u003C>();\n",[158,532,533],{"class":160,"line":167},[158,534,535],{},"Box\u003CInteger> numberBox = new Box\u003C>();\n",[158,537,538],{"class":160,"line":174},[158,539,171],{"emptyLinePlaceholder":170},[158,541,542],{"class":160,"line":180},[158,543,544],{},"stringBox.setValue(\"민형\");\n",[158,546,547],{"class":160,"line":237},[158,548,549],{},"numberBox.setValue(100);\n",[158,551,552],{"class":160,"line":425},[158,553,171],{"emptyLinePlaceholder":170},[158,555,556],{"class":160,"line":431},[158,557,558],{},"String name = stringBox.getValue();\n",[158,560,561],{"class":160,"line":436},[158,562,563],{},"Integer number = numberBox.getValue();\n",[132,565,566,567,569,570,572,573,575],{},"같은 ",[52,568,54],{}," 코드를 ",[52,571,84],{},"과 ",[52,574,127],{}," 타입에 모두 재사용할 수 있다.",[14,577,579],{"id":578},"_5-iterator와-제네릭","5. Iterator와 제네릭",[149,581,583],{"className":151,"code":582,"language":153,"meta":154,"style":154},"Iterator\u003CString> iterator = history.iterator();\nString record = iterator.next();\n",[52,584,585,590],{"__ignoreMap":154},[158,586,587],{"class":160,"line":161},[158,588,589],{},"Iterator\u003CString> iterator = history.iterator();\n",[158,591,592],{"class":160,"line":167},[158,593,594],{},"String record = iterator.next();\n",[132,596,597,600,601,603,604,607,608,610],{},[52,598,599],{},"Iterator\u003CString>","은 순회하면서 꺼내는 데이터가 ",[52,602,84],{},"이라는 뜻이다. 따라서 ",[52,605,606],{},"iterator.next()","의 반환값도 바로 ",[52,609,84],{},"으로 받을 수 있다.",[14,612,614],{"id":613},"_6-자주-사용하는-제네릭-타입","6. 자주 사용하는 제네릭 타입",[616,617,618,623,628,632,637],"ul",{},[619,620,621],"li",{},[52,622,97],{},[619,624,625],{},[52,626,627],{},"ArrayList\u003CInteger>",[619,629,630],{},[52,631,599],{},[619,633,634],{},[52,635,636],{},"Map\u003CString, Integer>",[619,638,639],{},[52,640,641],{},"Optional\u003CUser>",[132,643,644,646,647,649,650,652],{},[52,645,636],{},"는 키가 ",[52,648,84],{},", 값이 ",[52,651,127],{},"라는 뜻이다.",[149,654,656],{"className":151,"code":655,"language":153,"meta":154,"style":154},"Map\u003CString, Integer> scores;\n",[52,657,658],{"__ignoreMap":154},[158,659,660],{"class":160,"line":161},[158,661,655],{},[149,663,668],{"className":664,"code":666,"language":667,"meta":154},[665],"language-text","Key   → String\nValue → Integer\n","text",[52,669,666],{"__ignoreMap":154},[14,671,673],{"id":672},"_7-왜-기본형-대신-wrapper-class를-사용할까","7. 왜 기본형 대신 Wrapper Class를 사용할까?",[132,675,676],{},"제네릭의 타입 인자에는 기본형을 직접 사용할 수 없다.",[149,678,680],{"className":151,"code":679,"language":153,"meta":154,"style":154},"\u002F\u002F 허용되지 않음\nArrayList\u003Cint> numbers; \n",[52,681,682,687],{"__ignoreMap":154},[158,683,684],{"class":160,"line":161},[158,685,686],{},"\u002F\u002F 허용되지 않음\n",[158,688,689],{"class":160,"line":167},[158,690,691],{},"ArrayList\u003Cint> numbers;\n",[132,693,694],{},"제네릭은 참조 타입을 대상으로 하기 때문에 Wrapper Class를 사용해야 한다.",[149,696,698],{"className":151,"code":697,"language":153,"meta":154,"style":154},"\u002F\u002F 허용됨\nArrayList\u003CInteger> numbers; \n",[52,699,700,705],{"__ignoreMap":154},[158,701,702],{"class":160,"line":161},[158,703,704],{},"\u002F\u002F 허용됨\n",[158,706,707],{"class":160,"line":167},[158,708,709],{},"ArrayList\u003CInteger> numbers;\n",[149,711,714],{"className":712,"code":713,"language":667,"meta":154},[665],"int     → Integer\ndouble  → Double\nboolean → Boolean\nchar    → Character\n",[52,715,713],{"__ignoreMap":154},[14,717,719],{"id":718},"_8-결론","8. 결론",[721,722,723,729,735],"ol",{},[619,724,303,725,728],{},[726,727],"br",{},"잘못된 타입을 컴파일 단계에서 차단한다.",[619,730,731,732,734],{},"형변환 감소",[726,733],{},"값을 꺼낼 때 불필요한 타입 캐스팅을 줄인다.",[619,736,737,738,740],{},"코드 재사용",[726,739],{},"하나의 클래스나 메서드를 여러 타입에 활용할 수 있다.",[129,742,743],{},[132,744,745],{},"제네릭은 클래스나 메서드가 사용할 데이터 타입을 외부에서 지정할 수 있게 한다. 이를 통해 타입 안정성을 확보하고, 불필요한 형변환을 줄이며, 같은 코드를 여러 타입에서 재사용할 수 있다.",[132,747,748,750],{},[52,749,143],{},"을 사용할 때 이미 제네릭을 사용하고 있었던 것이다.",[752,753,754],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":154,"searchDepth":167,"depth":167,"links":756},[757],{"id":12,"depth":167,"text":5,"children":758},[759,760,761,762,763,764,765,766],{"id":16,"depth":174,"text":17},{"id":137,"depth":174,"text":138},{"id":202,"depth":174,"text":203},{"id":297,"depth":174,"text":298},{"id":578,"depth":174,"text":579},{"id":613,"depth":174,"text":614},{"id":672,"depth":174,"text":673},{"id":718,"depth":174,"text":719},[153,768],"basics","2026-08-11 10:00:00 +0900","Java 제네릭으로 컬렉션이 다룰 데이터 타입을 지정하는 방법을 ArrayList 예제로 정리한다.","md",null,"\u002Fjava\u002Fbasics\u002F2026\u002F08\u002F11\u002Fjava-generics\u002F",{"layout":775},"post","4","\u002Fposts\u002Fbackend\u002Fjava\u002Fbasics\u002F2026-08-11-java-generics",{"title":5,"description":770},"Java 기초","posts\u002FBackend\u002FJAVA\u002Fbasics\u002F2026-08-11-java-generics",[782,783,209,784,785],"Java","Generic","Collection","Type Safety","b5TYWFd138VG5I6b6yCXBs129ArepJhEjzbCWpIUo5A",1788744784609]