[{"data":1,"prerenderedAt":649},["ShallowReactive",2],{"post-document:\u002Fjava\u002Fdebugging\u002F2026\u002F08\u002F11\u002Fjava-confusing-concepts-debugging\u002F":3},{"id":4,"title":5,"body":6,"categories":624,"date":626,"description":627,"extension":628,"image":629,"key_concepts":629,"last_modified_at":629,"legacyPath":630,"meta":631,"navigation":86,"part":633,"path":634,"published":86,"robots":629,"seo":635,"series":636,"stem":637,"strengths":629,"summary":629,"tags":638,"tradeoffs":629,"__hash__":648},"posts\u002Fposts\u002FBackend\u002FJAVA\u002Fdebugging\u002F2026-08-11-java-confusing-concepts-debugging.md","Java 디버깅 Part 1: 자주 헷갈리는 핵심 개념",{"type":7,"value":8,"toc":612},"minimark",[9,13,18,35,51,55,61,65,112,122,128,134,140,145,150,153,161,164,168,171,176,181,185,190,194,199,218,221,231,234,240,243,249,297,300,305,309,314,323,326,329,338,341,346,351,356,403,406,409,412,427,430,433,441,444,452,456,465,468,477,480,483,502,505,510,513,517,564,570,574,579,585,591,597,603,608],[10,11,5],"h2",{"id":12},"java-디버깅-part-1-자주-헷갈리는-핵심-개념",[14,15,17],"h3",{"id":16},"_1-클래스와-객체","1. 클래스와 객체",[19,20,25],"pre",{"className":21,"code":22,"language":23,"meta":24,"style":24},"language-java shiki shiki-themes github-light github-dark","User user = new User();\n","java","",[26,27,28],"code",{"__ignoreMap":24},[29,30,33],"span",{"class":31,"line":32},"line",1,[29,34,22],{},[36,37,38,42,45,48],"ul",{},[39,40,41],"li",{},"User -> 클래스 타입",[39,43,44],{},"user -> 참조 변수",[39,46,47],{},"new - > 새로오 객체를 생성하는 키워드",[39,49,50],{},"User() -> 생성자 호출",[52,53,54],"p",{},"클래스는 이미 존재하고, 그 클래스를 기반으로 객체를 새로 만드는 것",[56,57,58],"blockquote",{},[52,59,60],{},"User 클래스를 기반으로 새로운 객체를 생성ㅅ, 그 객체의 참조를 user 변수에 저장한다.",[14,62,64],{"id":63},"_2-생성자와-this","2. 생성자와 This",[19,66,68],{"className":21,"code":67,"language":23,"meta":24,"style":24},"class User {\n    String name;\n\n    User(String name) {\n        this.name = name;\n    }\n}\n",[26,69,70,75,81,88,94,100,106],{"__ignoreMap":24},[29,71,72],{"class":31,"line":32},[29,73,74],{},"class User {\n",[29,76,78],{"class":31,"line":77},2,[29,79,80],{},"    String name;\n",[29,82,84],{"class":31,"line":83},3,[29,85,87],{"emptyLinePlaceholder":86},true,"\n",[29,89,91],{"class":31,"line":90},4,[29,92,93],{},"    User(String name) {\n",[29,95,97],{"class":31,"line":96},5,[29,98,99],{},"        this.name = name;\n",[29,101,103],{"class":31,"line":102},6,[29,104,105],{},"    }\n",[29,107,109],{"class":31,"line":108},7,[29,110,111],{},"}\n",[36,113,114],{},[39,115,116,117],{},"String name; -> 인자(argument)가 아니라 field\n",[36,118,119],{},[39,120,121],{},"User 객체가 가지는 필드",[52,123,124,127],{},[26,125,126],{},"User(String name)","\n- 여기있는 name은 Parameter(매개변수)",[52,129,130,133],{},[26,131,132],{},"new User(\"민형\")","\n- 여기에 들어가는 \"민형\"이 argument(인자)",[52,135,136,139],{},[26,137,138],{},"String name;"," -> field",[52,141,142,144],{},[26,143,126],{}," -> parameter",[52,146,147,149],{},[26,148,132],{}," -> \"민형\"은 argument",[52,151,152],{},"this.name은 생성자로 전달받은 name parameter 값을 현재 객체의 name field에 저장한다.",[19,154,159],{"className":155,"code":157,"language":158,"meta":24},[156],"language-text","\"민형\"\n    ↓ argument\nString name\n    ↓ parameter\nthis.name = name\n    ↓\n현재 객체의 name field = \"민형\"\n","text",[26,160,157],{"__ignoreMap":24},[52,162,163],{},"User 객체를 생성하면 \"민형\"을 생성자의 argument로 전달하고, 생성자는 그 값을 현재 객체의 name 필드에 저장한다.",[14,165,167],{"id":166},"_3-참조변수","3. 참조변수",[52,169,170],{},"JAVA 언어 수준에서 메모리 직접 다루는 것은 아니기 때문에,",[56,172,173],{},[52,174,175],{},"같은 객체를 참조한다. 라고 서술하는 것이 더 안전한 편이다.",[36,177,178],{},[39,179,180],{},"b에는 새로운 객체가 생성되는 것이 아니라 a가 가진 참조값이 복사되므로, a 와 b는 같은 User 객체를 가리킨다.",[14,182,184],{"id":183},"_4-static","4. Static",[56,186,187],{},[52,188,189],{},"static은 특정 객체가 아니라, 클래스 자체에 속하는 멤버를 정의하고, 모든 인스턴스가 하나의 값을 공유하도록 한다.",[14,191,193],{"id":192},"_5-static-final","5. Static final",[56,195,196],{},[52,197,198],{},"final 참조 변수는 다른 객체로 재할당할 수 없다.",[19,200,202],{"className":21,"code":201,"language":23,"meta":24,"style":24},"static User user = new User(\"민형\");\n\nuser = new User(\"철수\"); -> 가능하다. \n",[26,203,204,209,213],{"__ignoreMap":24},[29,205,206],{"class":31,"line":32},[29,207,208],{},"static User user = new User(\"민형\");\n",[29,210,211],{"class":31,"line":77},[29,212,87],{"emptyLinePlaceholder":86},[29,214,215],{"class":31,"line":83},[29,216,217],{},"user = new User(\"철수\"); -> 가능하다.\n",[52,219,220],{},"다만",[52,222,223,226,227,230],{},[26,224,225],{},"static final User user = new User(\"민형\");"," 같은 경우에는\n",[26,228,229],{},"user = new User(\"철수\");"," 로 재할당이 불가능하다.",[52,232,233],{},"user가 가리키는 객체를 다른 객체로 바꾸지 못하게 하는 것",[19,235,238],{"className":236,"code":237,"language":158,"meta":24},[156],"final user ─X──→ [다른 User 객체]\n",[26,239,237],{"__ignoreMap":24},[52,241,242],{},"다만 객체 내부는 이와 같은 변경이 가능하다",[19,244,247],{"className":245,"code":246,"language":158,"meta":24},[156],"[User 객체]\nname = \"민형\"\n      ↓\nname = \"철수\"\n",[26,248,246],{"__ignoreMap":24},[250,251,252,269],"table",{},[253,254,255],"thead",{},[256,257,258,262,266],"tr",{},[259,260,261],"th",{},"코드",[259,263,265],{"align":264},"right","static",[259,267,268],{"align":264},"static final",[270,271,272,286],"tbody",{},[256,273,274,280,283],{},[275,276,277],"td",{},[26,278,279],{},"user = new User(\"철수\")",[275,281,282],{"align":264},"가능",[275,284,285],{"align":264},"불가능",[256,287,288,293,295],{},[275,289,290],{},[26,291,292],{},"user.name = \"철수\"",[275,294,282],{"align":264},[275,296,282],{"align":264},[52,298,299],{},"단, name 자체도 final이거나 setter가 막혀 있으면 별개야.",[56,301,302],{},[52,303,304],{},"Static은 클래스 단위의 공유 여부를 결정하고, final은 변수에 저장된 값을 다시 할당할 수 있는지를 제한한다.",[14,306,308],{"id":307},"_6-package-import","6. Package \u002F import",[56,310,311],{},[52,312,313],{},"package는 클래스의 소속과 이름 공간(namespace)를 정의하는 역할",[19,315,317],{"className":21,"code":316,"language":23,"meta":24,"style":24},"package com.practice.model;\n",[26,318,319],{"__ignoreMap":24},[29,320,321],{"class":31,"line":32},[29,322,316],{},[52,324,325],{},"의 의미는 이 클래는 com.practice.model 패키지에 속한다.",[52,327,328],{},"그리고서는",[19,330,332],{"className":21,"code":331,"language":23,"meta":24,"style":24},"import com.practice.model.User;\n",[26,333,334],{"__ignoreMap":24},[29,335,336],{"class":31,"line":32},[29,337,331],{},[52,339,340],{},"는:",[56,342,343],{},[52,344,345],{},"다른 패키지에 있는 User 클래스를 이 소스 코드에서 짧은 이름 User로 사용할 수 있게 된다.",[56,347,348],{},[52,349,350],{},"어떤 클래스를 말하는지 컴파일러가 알 수 있도록 이름을 연결해주는 것에 가깝다.",[36,352,353],{},[39,354,355],{},"왜 Main 안에서 임포트하냐..?",[19,357,359],{"className":21,"code":358,"language":23,"meta":24,"style":24},"package com.practice;\n\nimport com.practice.model.User;\n\npublic class Main {\n    public static void main(String[] args) {\n        User user = new User();\n    }\n}\n",[26,360,361,366,370,374,378,383,388,393,398],{"__ignoreMap":24},[29,362,363],{"class":31,"line":32},[29,364,365],{},"package com.practice;\n",[29,367,368],{"class":31,"line":77},[29,369,87],{"emptyLinePlaceholder":86},[29,371,372],{"class":31,"line":83},[29,373,331],{},[29,375,376],{"class":31,"line":90},[29,377,87],{"emptyLinePlaceholder":86},[29,379,380],{"class":31,"line":96},[29,381,382],{},"public class Main {\n",[29,384,385],{"class":31,"line":102},[29,386,387],{},"    public static void main(String[] args) {\n",[29,389,390],{"class":31,"line":108},[29,391,392],{},"        User user = new User();\n",[29,394,396],{"class":31,"line":395},8,[29,397,105],{},[29,399,401],{"class":31,"line":400},9,[29,402,111],{},[52,404,405],{},"import는 Main 클래스 밖, 파일 위쪽에 있는 이유",[52,407,408],{},"Main은 com.practice에 있고,\nUser는 com.practice.model에 있기 때문",[52,410,411],{},"꼭 import할 필요는 없는데",[19,413,415],{"className":21,"code":414,"language":23,"meta":24,"style":24},"com.practice.model.User user =\n    new com.practice.model.User();\n",[26,416,417,422],{"__ignoreMap":24},[29,418,419],{"class":31,"line":32},[29,420,421],{},"com.practice.model.User user =\n",[29,423,424],{"class":31,"line":77},[29,425,426],{},"    new com.practice.model.User();\n",[52,428,429],{},"라고 풀네임으로 적어도 되긴하다.",[52,431,432],{},"하지만 귀찮으니까",[19,434,435],{"className":21,"code":331,"language":23,"meta":24,"style":24},[26,436,437],{"__ignoreMap":24},[29,438,439],{"class":31,"line":32},[29,440,331],{},[52,442,443],{},"를 하고 나서",[19,445,446],{"className":21,"code":22,"language":23,"meta":24,"style":24},[26,447,448],{"__ignoreMap":24},[29,449,450],{"class":31,"line":32},[29,451,22],{},[14,453,455],{"id":454},"_7-추상화","7. 추상화",[19,457,459],{"className":21,"code":458,"language":23,"meta":24,"style":24},"Animal animal = new Animal();\n",[26,460,461],{"__ignoreMap":24},[29,462,463],{"class":31,"line":32},[29,464,458],{},[52,466,467],{},"부모 클래스에 sound()가 없는 게 아니라 존재한다.",[19,469,471],{"className":21,"code":470,"language":23,"meta":24,"style":24},"abstract void sound();\n",[26,472,473],{"__ignoreMap":24},[29,474,475],{"class":31,"line":32},[29,476,470],{},[52,478,479],{},"하지만 구현 내용이 없는 추상 메서드여서 구현을 반드시 구현을 해야한다.",[52,481,482],{},"eat() 사용 가능하다는 것도 맞긴 하다.",[19,484,486],{"className":21,"code":485,"language":23,"meta":24,"style":24},"Void eat() {\n    System.out.println(\"먹는다\");\n}\n",[26,487,488,493,498],{"__ignoreMap":24},[29,489,490],{"class":31,"line":32},[29,491,492],{},"Void eat() {\n",[29,494,495],{"class":31,"line":77},[29,496,497],{},"    System.out.println(\"먹는다\");\n",[29,499,500],{"class":31,"line":83},[29,501,111],{},[52,503,504],{},"부모 클래스에서 구현됐으니까 Dog가 상속받아 사용할 수 있다.",[56,506,507],{},[52,508,509],{},"정리하자면",[52,511,512],{},"Animal은 모든 동물이 sound() 기능을 가져야 한다는 공통 규칙만 추상적으로 정의하고, 실제 소리를 내는 방법은 자식 클래스가 구현하도록 해야한다.",[14,514,516],{"id":515},"가장-많이-헷갈리는-용어","가장 많이 헷갈리는 용어",[19,518,520],{"className":21,"code":519,"language":23,"meta":24,"style":24},"class User {\n\n    String name;\n\n    User(String name) {\n        this.name = name;\n    }\n}\n\nUser user = new User(\"민형\");\n",[26,521,522,526,530,534,538,542,546,550,554,558],{"__ignoreMap":24},[29,523,524],{"class":31,"line":32},[29,525,74],{},[29,527,528],{"class":31,"line":77},[29,529,87],{"emptyLinePlaceholder":86},[29,531,532],{"class":31,"line":83},[29,533,80],{},[29,535,536],{"class":31,"line":90},[29,537,87],{"emptyLinePlaceholder":86},[29,539,540],{"class":31,"line":96},[29,541,93],{},[29,543,544],{"class":31,"line":102},[29,545,99],{},[29,547,548],{"class":31,"line":108},[29,549,105],{},[29,551,552],{"class":31,"line":395},[29,553,111],{},[29,555,556],{"class":31,"line":400},[29,557,87],{"emptyLinePlaceholder":86},[29,559,561],{"class":31,"line":560},10,[29,562,563],{},"User user = new User(\"민형\");\n",[52,565,566,569],{},[26,567,568],{},"User"," -> 클래스 \u002F 타입",[52,571,572,139],{},[26,573,138],{},[52,575,576,578],{},[26,577,126],{}," -> 생성자",[52,580,581,584],{},[26,582,583],{},"\"민형\""," -> argument",[52,586,587,590],{},[26,588,589],{},"this"," -> 현재 객체",[52,592,593,596],{},[26,594,595],{},"this.name"," -> 현재 객체의 field",[52,598,599,602],{},[26,600,601],{},"user"," -> 참조 변수",[52,604,605,607],{},[26,606,132],{},"\n-> 새 User 객체 생성 + 생성 호출",[609,610,611],"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":24,"searchDepth":77,"depth":77,"links":613},[614],{"id":12,"depth":77,"text":5,"children":615},[616,617,618,619,620,621,622,623],{"id":16,"depth":83,"text":17},{"id":63,"depth":83,"text":64},{"id":166,"depth":83,"text":167},{"id":183,"depth":83,"text":184},{"id":192,"depth":83,"text":193},{"id":307,"depth":83,"text":308},{"id":454,"depth":83,"text":455},{"id":515,"depth":83,"text":516},[23,625],"debugging","2026-08-11 09:00:00 +0900","Java에서 자주 헷갈리는 클래스와 객체, 생성자와 this, static final, package import, 추상화 개념을 디버깅 관점에서 정리한다.","md",null,"\u002Fjava\u002Fdebugging\u002F2026\u002F08\u002F11\u002Fjava-confusing-concepts-debugging\u002F",{"layout":632},"post","1","\u002Fposts\u002Fbackend\u002Fjava\u002Fdebugging\u002F2026-08-11-java-confusing-concepts-debugging",{"title":5,"description":627},"Java 디버깅","posts\u002FBackend\u002FJAVA\u002Fdebugging\u002F2026-08-11-java-confusing-concepts-debugging",[639,640,641,642,643,644,645,646,647],"Java","Debugging","OOP","Class","Constructor","Static","Package","Import","Abstract","itgr6PZKN9-PrqLvB_3lxndkkiyWmL_xlbCgk690xck",1788744784676]