[{"data":1,"prerenderedAt":3741},["ShallowReactive",2],{"\u002Fblog\u002FJava-Generics":3,"post-count":3328,"series-global-data":3329,"authors-all":3444,"series-sidebar-none":3639,"sidebar-authors":3640},{"id":4,"title":5,"author":6,"body":7,"date":3317,"description":44,"draft":3318,"edited_at":3317,"extension":3319,"featured_image":3320,"meta":3321,"navigation":3322,"path":3323,"pinned":3318,"seo":3324,"sitemap":3325,"stem":3326,"tags":3320,"__hash__":3327},"blog\u002Fblog\u002FJava-Generics.md","Java Generics","chinono",{"type":8,"value":9,"toc":3276},"minimark",[10,20,27,38,126,140,206,220,224,227,291,294,322,393,403,410,424,427,435,457,502,507,637,641,747,751,758,850,854,913,944,952,958,991,998,1222,1225,1307,1332,1336,1412,1415,1444,1448,1455,1460,1489,1499,1620,1623,1748,1755,1763,1773,1780,1808,1836,2027,2031,2048,2052,2058,2079,2094,2098,2101,2161,2164,2191,2198,2284,2296,2299,2303,2314,2330,2390,2400,2404,2465,2473,2477,2507,2511,2517,2527,2530,2551,2600,2603,2648,2655,2659,2732,2758,2762,2769,2775,2797,2807,2811,2834,2837,2868,2871,2875,2943,2953,2957,2988,3005,3009,3272],[11,12,14,15,19],"h2",{"id":13},"_1-what-even-is-a-generic","1. What even ",[16,17,18],"em",{},"is"," a generic?",[21,22,23],"p",{},[24,25,26],"strong",{},"Generic = the ability to parameterize types.",[21,28,29,30,33,34,37],{},"That sounds abstract, so let me translate. You already know about ",[24,31,32],{},"parameters in methods",": you write a method once and pass in different ",[16,35,36],{},"values",".",[39,40,45],"pre",{"className":41,"code":42,"language":43,"meta":44,"style":44},"language-java shiki shiki-themes github-light github-dark","public int square(int x) { return x * x; }\n \nsquare(3);   \u002F\u002F works\nsquare(10);  \u002F\u002F works\n","java","",[46,47,48,86,92,111],"code",{"__ignoreMap":44},[49,50,53,57,60,64,68,71,74,77,80,83],"span",{"class":51,"line":52},"line",1,[49,54,56],{"class":55},"szBVR","public",[49,58,59],{"class":55}," int",[49,61,63],{"class":62},"sScJk"," square",[49,65,67],{"class":66},"sVt8B","(",[49,69,70],{"class":55},"int",[49,72,73],{"class":66}," x) { ",[49,75,76],{"class":55},"return",[49,78,79],{"class":66}," x ",[49,81,82],{"class":55},"*",[49,84,85],{"class":66}," x; }\n",[49,87,89],{"class":51,"line":88},2,[49,90,91],{"class":66}," \n",[49,93,95,98,100,104,107],{"class":51,"line":94},3,[49,96,97],{"class":62},"square",[49,99,67],{"class":66},[49,101,103],{"class":102},"sj4cs","3",[49,105,106],{"class":66},");   ",[49,108,110],{"class":109},"sJ8bj","\u002F\u002F works\n",[49,112,114,116,118,121,124],{"class":51,"line":113},4,[49,115,97],{"class":62},[49,117,67],{"class":66},[49,119,120],{"class":102},"10",[49,122,123],{"class":66},");  ",[49,125,110],{"class":109},[21,127,128,129,132,133,136,137,37],{},"A ",[24,130,131],{},"generic"," does the same thing — but instead of passing in a ",[16,134,135],{},"value",", you pass in a ",[24,138,139],{},"type",[39,141,143],{"className":41,"code":142,"language":43,"meta":44,"style":44},"ArrayList\u003CString>  cities  = new ArrayList\u003C>();   \u002F\u002F a list of Strings\nArrayList\u003CInteger> scores  = new ArrayList\u003C>();   \u002F\u002F a list of Integers\nArrayList\u003CCircle>  shapes  = new ArrayList\u003C>();   \u002F\u002F a list of Circles\n",[46,144,145,168,187],{"__ignoreMap":44},[49,146,147,150,153,156,159,162,165],{"class":51,"line":52},[49,148,149],{"class":66},"ArrayList\u003C",[49,151,152],{"class":55},"String",[49,154,155],{"class":66},">  cities  ",[49,157,158],{"class":55},"=",[49,160,161],{"class":55}," new",[49,163,164],{"class":66}," ArrayList\u003C>();   ",[49,166,167],{"class":109},"\u002F\u002F a list of Strings\n",[49,169,170,172,175,178,180,182,184],{"class":51,"line":88},[49,171,149],{"class":66},[49,173,174],{"class":55},"Integer",[49,176,177],{"class":66},"> scores  ",[49,179,158],{"class":55},[49,181,161],{"class":55},[49,183,164],{"class":66},[49,185,186],{"class":109},"\u002F\u002F a list of Integers\n",[49,188,189,191,194,197,199,201,203],{"class":51,"line":94},[49,190,149],{"class":66},[49,192,193],{"class":55},"Circle",[49,195,196],{"class":66},">  shapes  ",[49,198,158],{"class":55},[49,200,161],{"class":55},[49,202,164],{"class":66},[49,204,205],{"class":109},"\u002F\u002F a list of Circles\n",[21,207,208,209,212,213,216,217,37],{},"The class ",[46,210,211],{},"ArrayList"," is written ",[16,214,215],{},"once",". You decide what kind of thing it stores by plugging in a type between the ",[46,218,219],{},"\u003C>",[11,221,223],{"id":222},"_2-why-bother-aka-the-why-generics-rant","2. Why bother? (a.k.a. the \"Why Generics?\" rant)",[21,225,226],{},"Before Java 1.5, you had to write things like this:",[39,228,230],{"className":41,"code":229,"language":43,"meta":44,"style":44},"ArrayList list = new ArrayList();    \u002F\u002F raw type — no \u003C>\nlist.add(\"hello\");\nString s = (String) list.get(0);     \u002F\u002F manual cast required\n",[46,231,232,250,267],{"__ignoreMap":44},[49,233,234,237,239,241,244,247],{"class":51,"line":52},[49,235,236],{"class":66},"ArrayList list ",[49,238,158],{"class":55},[49,240,161],{"class":55},[49,242,243],{"class":62}," ArrayList",[49,245,246],{"class":66},"();    ",[49,248,249],{"class":109},"\u002F\u002F raw type — no \u003C>\n",[49,251,252,255,258,260,264],{"class":51,"line":88},[49,253,254],{"class":66},"list.",[49,256,257],{"class":62},"add",[49,259,67],{"class":66},[49,261,263],{"class":262},"sZZnC","\"hello\"",[49,265,266],{"class":66},");\n",[49,268,269,272,274,277,280,282,285,288],{"class":51,"line":94},[49,270,271],{"class":66},"String s ",[49,273,158],{"class":55},[49,275,276],{"class":66}," (String) list.",[49,278,279],{"class":62},"get",[49,281,67],{"class":66},[49,283,284],{"class":102},"0",[49,286,287],{"class":66},");     ",[49,289,290],{"class":109},"\u002F\u002F manual cast required\n",[21,292,293],{},"Two problems:",[295,296,297,304],"ol",{},[298,299,300,303],"li",{},[24,301,302],{},"You had to cast everything."," Ugly.",[298,305,306,309,310,313,314,317,318,321],{},[24,307,308],{},"No type safety."," You could ",[46,311,312],{},"list.add(\"hello\")"," and then ",[46,315,316],{},"list.add(42)"," and the compiler wouldn't say a word — until your program crashed at runtime with a ",[46,319,320],{},"ClassCastException",".\nWith generics, both problems disappear:",[39,323,325],{"className":41,"code":324,"language":43,"meta":44,"style":44},"ArrayList\u003CString> list = new ArrayList\u003C>();\nlist.add(\"hello\");\nString s = list.get(0);              \u002F\u002F ✅ no cast needed\nlist.add(42);                        \u002F\u002F ❌ compile error — Java stops you immediately\n",[46,326,327,343,355,376],{"__ignoreMap":44},[49,328,329,331,333,336,338,340],{"class":51,"line":52},[49,330,149],{"class":66},[49,332,152],{"class":55},[49,334,335],{"class":66},"> list ",[49,337,158],{"class":55},[49,339,161],{"class":55},[49,341,342],{"class":66}," ArrayList\u003C>();\n",[49,344,345,347,349,351,353],{"class":51,"line":88},[49,346,254],{"class":66},[49,348,257],{"class":62},[49,350,67],{"class":66},[49,352,263],{"class":262},[49,354,266],{"class":66},[49,356,357,359,361,364,366,368,370,373],{"class":51,"line":94},[49,358,271],{"class":66},[49,360,158],{"class":55},[49,362,363],{"class":66}," list.",[49,365,279],{"class":62},[49,367,67],{"class":66},[49,369,284],{"class":102},[49,371,372],{"class":66},");              ",[49,374,375],{"class":109},"\u002F\u002F ✅ no cast needed\n",[49,377,378,380,382,384,387,390],{"class":51,"line":113},[49,379,254],{"class":66},[49,381,257],{"class":62},[49,383,67],{"class":66},[49,385,386],{"class":102},"42",[49,388,389],{"class":66},");                        ",[49,391,392],{"class":109},"\u002F\u002F ❌ compile error — Java stops you immediately\n",[21,394,395,398,399,402],{},[24,396,397],{},"The big win:"," errors get caught at ",[24,400,401],{},"compile time",", not after your program is running in production. That's the entire selling point.",[11,404,406,407,409],{"id":405},"_3-meeting-arraylist-properly","3. Meeting ",[46,408,211],{}," properly",[21,411,412,413,416,417,419,420,423],{},"Arrays in Java have a fixed size — once you do ",[46,414,415],{},"new int[10]",", you've got 10 slots and that's it. ",[46,418,211],{}," solves this by being a ",[24,421,422],{},"resizable"," container.",[21,425,426],{},"Here's the class signature you'll see in the docs:",[39,428,433],{"className":429,"code":431,"language":432},[430],"language-text","java.util.ArrayList\u003CE>\n","text",[46,434,431],{"__ignoreMap":44},[21,436,437,438,441,442,445,446,449,450,453,454,456],{},"That ",[46,439,440],{},"\u003CE>"," is the ",[24,443,444],{},"formal generic type",". The letter ",[46,447,448],{},"E"," stands for ",[16,451,452],{},"Element",". When you actually use it, you replace ",[46,455,448],{}," with a real type:",[39,458,460],{"className":41,"code":459,"language":43,"meta":44,"style":44},"ArrayList\u003CString> cities = new ArrayList\u003CString>();\n\u002F\u002F or, since Java 7, the shorter \"diamond\" form:\nArrayList\u003CString> cities = new ArrayList\u003C>();\n",[46,461,462,483,488],{"__ignoreMap":44},[49,463,464,466,468,471,473,475,478,480],{"class":51,"line":52},[49,465,149],{"class":66},[49,467,152],{"class":55},[49,469,470],{"class":66},"> cities ",[49,472,158],{"class":55},[49,474,161],{"class":55},[49,476,477],{"class":66}," ArrayList\u003C",[49,479,152],{"class":55},[49,481,482],{"class":66},">();\n",[49,484,485],{"class":51,"line":88},[49,486,487],{"class":109},"\u002F\u002F or, since Java 7, the shorter \"diamond\" form:\n",[49,489,490,492,494,496,498,500],{"class":51,"line":94},[49,491,149],{"class":66},[49,493,152],{"class":55},[49,495,470],{"class":66},[49,497,158],{"class":55},[49,499,161],{"class":55},[49,501,342],{"class":66},[503,504,506],"h3",{"id":505},"useful-methods","Useful methods",[508,509,510,523],"table",{},[511,512,513],"thead",{},[514,515,516,520],"tr",{},[517,518,519],"th",{},"Method",[517,521,522],{},"What it does",[524,525,526,537,547,557,567,577,587,597,607,617,627],"tbody",{},[514,527,528,534],{},[529,530,531],"td",{},[46,532,533],{},"add(E o)",[529,535,536],{},"Append an element to the end",[514,538,539,544],{},[529,540,541],{},[46,542,543],{},"add(int index, E o)",[529,545,546],{},"Insert at a specific position",[514,548,549,554],{},[529,550,551],{},[46,552,553],{},"get(int index)",[529,555,556],{},"Retrieve element at index",[514,558,559,564],{},[529,560,561],{},[46,562,563],{},"set(int index, E o)",[529,565,566],{},"Replace element at index",[514,568,569,574],{},[529,570,571],{},[46,572,573],{},"remove(Object o)",[529,575,576],{},"Remove first occurrence",[514,578,579,584],{},[529,580,581],{},[46,582,583],{},"remove(int index)",[529,585,586],{},"Remove by index",[514,588,589,594],{},[529,590,591],{},[46,592,593],{},"size()",[529,595,596],{},"How many elements",[514,598,599,604],{},[529,600,601],{},[46,602,603],{},"contains(Object o)",[529,605,606],{},"Does it contain this?",[514,608,609,614],{},[529,610,611],{},[46,612,613],{},"indexOf(Object o)",[529,615,616],{},"Position of first match",[514,618,619,624],{},[529,620,621],{},[46,622,623],{},"isEmpty()",[529,625,626],{},"true if size == 0",[514,628,629,634],{},[529,630,631],{},[46,632,633],{},"clear()",[529,635,636],{},"Wipe everything",[503,638,640],{"id":639},"array-vs-arraylist-side-by-side","Array vs ArrayList — side by side",[508,642,643,655],{},[511,644,645],{},[514,646,647,650,653],{},[517,648,649],{},"Operation",[517,651,652],{},"Array",[517,654,211],{},[524,656,657,672,687,702,717,732],{},[514,658,659,662,667],{},[529,660,661],{},"Create",[529,663,664],{},[46,665,666],{},"String[] a = new String[10];",[529,668,669],{},[46,670,671],{},"ArrayList\u003CString> list = new ArrayList\u003C>();",[514,673,674,677,682],{},[529,675,676],{},"Access",[529,678,679],{},[46,680,681],{},"a[index]",[529,683,684],{},[46,685,686],{},"list.get(index)",[514,688,689,692,697],{},[529,690,691],{},"Update",[529,693,694],{},[46,695,696],{},"a[index] = \"London\";",[529,698,699],{},[46,700,701],{},"list.set(index, \"London\");",[514,703,704,707,712],{},[529,705,706],{},"Size",[529,708,709],{},[46,710,711],{},"a.length",[529,713,714],{},[46,715,716],{},"list.size()",[514,718,719,722,727],{},[529,720,721],{},"Add",[529,723,724],{},[16,725,726],{},"(not possible — fixed size!)",[529,728,729],{},[46,730,731],{},"list.add(\"London\");",[514,733,734,737,742],{},[529,735,736],{},"Remove",[529,738,739],{},[16,740,741],{},"(not possible)",[529,743,744],{},[46,745,746],{},"list.remove(index);",[11,748,750],{"id":749},"_4-the-naming-convention-youll-see-everywhere","4. The naming convention you'll see everywhere",[21,752,753,754,757],{},"Generic type parameters are written as ",[24,755,756],{},"single uppercase letters",". This is a convention, not a rule, but everyone follows it because otherwise you can't tell type parameters apart from real class names.",[508,759,760,770],{},[511,761,762],{},[514,763,764,767],{},[517,765,766],{},"Letter",[517,768,769],{},"Meaning",[524,771,772,787,802,816,828,840],{},[514,773,774,778],{},[529,775,776],{},[46,777,448],{},[529,779,780,782,783,786],{},[24,781,448],{},"lement (used in collections — ",[46,784,785],{},"List\u003CE>",")",[514,788,789,794],{},[529,790,791],{},[46,792,793],{},"K",[529,795,796,798,799,786],{},[24,797,793],{},"ey (used in maps — ",[46,800,801],{},"Map\u003CK, V>",[514,803,804,809],{},[529,805,806],{},[46,807,808],{},"V",[529,810,811,813,814,786],{},[24,812,808],{},"alue (used in maps — ",[46,815,801],{},[514,817,818,823],{},[529,819,820],{},[46,821,822],{},"N",[529,824,825,827],{},[24,826,822],{},"umber",[514,829,830,835],{},[529,831,832],{},[46,833,834],{},"T",[529,836,837,839],{},[24,838,834],{},"ype (general placeholder)",[514,841,842,847],{},[529,843,844],{},[46,845,846],{},"S, U, V…",[529,848,849],{},"Extra type params when you need more than one",[11,851,853],{"id":852},"_5-one-important-restriction-only-reference-types","5. One important restriction: only reference types",[39,855,857],{"className":41,"code":856,"language":43,"meta":44,"style":44},"ArrayList\u003CInteger> a = new ArrayList\u003C>();   \u002F\u002F ✅ ok\nArrayList\u003CDouble>  b = new ArrayList\u003C>();   \u002F\u002F ✅ ok\nArrayList\u003Cint>     c = new ArrayList\u003C>();   \u002F\u002F ❌ compile error\n",[46,858,859,877,895],{"__ignoreMap":44},[49,860,861,863,865,868,870,872,874],{"class":51,"line":52},[49,862,149],{"class":66},[49,864,174],{"class":55},[49,866,867],{"class":66},"> a ",[49,869,158],{"class":55},[49,871,161],{"class":55},[49,873,164],{"class":66},[49,875,876],{"class":109},"\u002F\u002F ✅ ok\n",[49,878,879,881,884,887,889,891,893],{"class":51,"line":88},[49,880,149],{"class":66},[49,882,883],{"class":55},"Double",[49,885,886],{"class":66},">  b ",[49,888,158],{"class":55},[49,890,161],{"class":55},[49,892,164],{"class":66},[49,894,876],{"class":109},[49,896,897,899,901,904,906,908,910],{"class":51,"line":94},[49,898,149],{"class":66},[49,900,70],{"class":55},[49,902,903],{"class":66},">     c ",[49,905,158],{"class":55},[49,907,161],{"class":55},[49,909,164],{"class":66},[49,911,912],{"class":109},"\u002F\u002F ❌ compile error\n",[21,914,915,916,919,920,922,923,922,926,922,929,932,933,922,935,922,937,922,940,943],{},"The type parameter ",[24,917,918],{},"must be a reference type"," (a class). Primitives (",[46,921,70],{},", ",[46,924,925],{},"double",[46,927,928],{},"char",[46,930,931],{},"boolean",") are not allowed. Use their wrapper classes (",[46,934,174],{},[46,936,883],{},[46,938,939],{},"Character",[46,941,942],{},"Boolean",") instead.",[11,945,947,948,951],{"id":946},"_6-writing-your-own-generic-class","6. Writing your ",[16,949,950],{},"own"," generic class",[21,953,954,955,957],{},"You're not limited to using ",[46,956,211],{},". You can write your own generic class. The syntax:",[39,959,961],{"className":41,"code":960,"language":43,"meta":44,"style":44},"public class ClassName\u003CE> {\n    \u002F\u002F use E like a normal type inside\n}\n",[46,962,963,981,986],{"__ignoreMap":44},[49,964,965,967,970,973,976,978],{"class":51,"line":52},[49,966,56],{"class":55},[49,968,969],{"class":55}," class",[49,971,972],{"class":62}," ClassName",[49,974,975],{"class":66},"\u003C",[49,977,448],{"class":55},[49,979,980],{"class":66},"> {\n",[49,982,983],{"class":51,"line":88},[49,984,985],{"class":109},"    \u002F\u002F use E like a normal type inside\n",[49,987,988],{"class":51,"line":94},[49,989,990],{"class":66},"}\n",[21,992,993,994,997],{},"Here's a tiny example — a ",[46,995,996],{},"Box"," that can hold any single thing:",[39,999,1001],{"className":41,"code":1000,"language":43,"meta":44,"style":44},"public class GenericBox\u003CT> {\n    private T item;\n    private boolean full;\n \n    public GenericBox() { full = false; }\n \n    public void store(T a) {\n        this.item = a;\n        full = true;\n    }\n \n    public void remove() {\n        item = null;\n        full = false;\n    }\n \n    public String toString() {\n        return full ? item.toString() : \"nothing\";\n    }\n}\n",[46,1002,1003,1018,1026,1036,1040,1059,1064,1085,1099,1113,1119,1124,1137,1150,1161,1166,1171,1184,1212,1217],{"__ignoreMap":44},[49,1004,1005,1007,1009,1012,1014,1016],{"class":51,"line":52},[49,1006,56],{"class":55},[49,1008,969],{"class":55},[49,1010,1011],{"class":62}," GenericBox",[49,1013,975],{"class":66},[49,1015,834],{"class":55},[49,1017,980],{"class":66},[49,1019,1020,1023],{"class":51,"line":88},[49,1021,1022],{"class":55},"    private",[49,1024,1025],{"class":66}," T item;\n",[49,1027,1028,1030,1033],{"class":51,"line":94},[49,1029,1022],{"class":55},[49,1031,1032],{"class":55}," boolean",[49,1034,1035],{"class":66}," full;\n",[49,1037,1038],{"class":51,"line":113},[49,1039,91],{"class":66},[49,1041,1043,1046,1048,1051,1053,1056],{"class":51,"line":1042},5,[49,1044,1045],{"class":55},"    public",[49,1047,1011],{"class":62},[49,1049,1050],{"class":66},"() { full ",[49,1052,158],{"class":55},[49,1054,1055],{"class":102}," false",[49,1057,1058],{"class":66},"; }\n",[49,1060,1062],{"class":51,"line":1061},6,[49,1063,91],{"class":66},[49,1065,1067,1069,1072,1075,1078,1082],{"class":51,"line":1066},7,[49,1068,1045],{"class":55},[49,1070,1071],{"class":55}," void",[49,1073,1074],{"class":62}," store",[49,1076,1077],{"class":66},"(T ",[49,1079,1081],{"class":1080},"s4XuR","a",[49,1083,1084],{"class":66},") {\n",[49,1086,1088,1091,1094,1096],{"class":51,"line":1087},8,[49,1089,1090],{"class":102},"        this",[49,1092,1093],{"class":66},".item ",[49,1095,158],{"class":55},[49,1097,1098],{"class":66}," a;\n",[49,1100,1102,1105,1107,1110],{"class":51,"line":1101},9,[49,1103,1104],{"class":66},"        full ",[49,1106,158],{"class":55},[49,1108,1109],{"class":102}," true",[49,1111,1112],{"class":66},";\n",[49,1114,1116],{"class":51,"line":1115},10,[49,1117,1118],{"class":66},"    }\n",[49,1120,1122],{"class":51,"line":1121},11,[49,1123,91],{"class":66},[49,1125,1127,1129,1131,1134],{"class":51,"line":1126},12,[49,1128,1045],{"class":55},[49,1130,1071],{"class":55},[49,1132,1133],{"class":62}," remove",[49,1135,1136],{"class":66},"() {\n",[49,1138,1140,1143,1145,1148],{"class":51,"line":1139},13,[49,1141,1142],{"class":66},"        item ",[49,1144,158],{"class":55},[49,1146,1147],{"class":102}," null",[49,1149,1112],{"class":66},[49,1151,1153,1155,1157,1159],{"class":51,"line":1152},14,[49,1154,1104],{"class":66},[49,1156,158],{"class":55},[49,1158,1055],{"class":102},[49,1160,1112],{"class":66},[49,1162,1164],{"class":51,"line":1163},15,[49,1165,1118],{"class":66},[49,1167,1169],{"class":51,"line":1168},16,[49,1170,91],{"class":66},[49,1172,1174,1176,1179,1182],{"class":51,"line":1173},17,[49,1175,1045],{"class":55},[49,1177,1178],{"class":66}," String ",[49,1180,1181],{"class":62},"toString",[49,1183,1136],{"class":66},[49,1185,1187,1190,1193,1196,1199,1201,1204,1207,1210],{"class":51,"line":1186},18,[49,1188,1189],{"class":55},"        return",[49,1191,1192],{"class":66}," full ",[49,1194,1195],{"class":55},"?",[49,1197,1198],{"class":66}," item.",[49,1200,1181],{"class":62},[49,1202,1203],{"class":66},"() ",[49,1205,1206],{"class":55},":",[49,1208,1209],{"class":262}," \"nothing\"",[49,1211,1112],{"class":66},[49,1213,1215],{"class":51,"line":1214},19,[49,1216,1118],{"class":66},[49,1218,1220],{"class":51,"line":1219},20,[49,1221,990],{"class":66},[21,1223,1224],{},"And in use:",[39,1226,1228],{"className":41,"code":1227,"language":43,"meta":44,"style":44},"GenericBox\u003CString>  box1 = new GenericBox\u003C>();\nGenericBox\u003CInteger> box2 = new GenericBox\u003C>();\n \nbox1.store(\"Hello World\");\nbox2.store(100);\n \n\u002F\u002F box1.store(100);   \u002F\u002F ❌ compile error — box1 only takes Strings\n",[46,1229,1230,1247,1262,1266,1281,1295,1299],{"__ignoreMap":44},[49,1231,1232,1235,1237,1240,1242,1244],{"class":51,"line":52},[49,1233,1234],{"class":66},"GenericBox\u003C",[49,1236,152],{"class":55},[49,1238,1239],{"class":66},">  box1 ",[49,1241,158],{"class":55},[49,1243,161],{"class":55},[49,1245,1246],{"class":66}," GenericBox\u003C>();\n",[49,1248,1249,1251,1253,1256,1258,1260],{"class":51,"line":88},[49,1250,1234],{"class":66},[49,1252,174],{"class":55},[49,1254,1255],{"class":66},"> box2 ",[49,1257,158],{"class":55},[49,1259,161],{"class":55},[49,1261,1246],{"class":66},[49,1263,1264],{"class":51,"line":94},[49,1265,91],{"class":66},[49,1267,1268,1271,1274,1276,1279],{"class":51,"line":113},[49,1269,1270],{"class":66},"box1.",[49,1272,1273],{"class":62},"store",[49,1275,67],{"class":66},[49,1277,1278],{"class":262},"\"Hello World\"",[49,1280,266],{"class":66},[49,1282,1283,1286,1288,1290,1293],{"class":51,"line":1042},[49,1284,1285],{"class":66},"box2.",[49,1287,1273],{"class":62},[49,1289,67],{"class":66},[49,1291,1292],{"class":102},"100",[49,1294,266],{"class":66},[49,1296,1297],{"class":51,"line":1061},[49,1298,91],{"class":66},[49,1300,1301,1304],{"class":51,"line":1066},[49,1302,1303],{"class":109},"\u002F\u002F box1.store(100);",[49,1305,1306],{"class":109},"   \u002F\u002F ❌ compile error — box1 only takes Strings\n",[21,1308,1309,1310,1313,1314,1317,1318,1320,1321,1323,1324,1327,1328,1331],{},"Compare this to the old non-generic version using ",[46,1311,1312],{},"Comparable item"," — that one would ",[16,1315,1316],{},"compile"," even if you mixed a ",[46,1319,152],{}," and an ",[46,1322,174],{},", then ",[24,1325,1326],{},"explode at runtime"," when you tried ",[46,1329,1330],{},"compareTo",". Generics catch it earlier. Beautiful.",[503,1333,1335],{"id":1334},"generic-interfaces-work-the-same-way","Generic interfaces work the same way",[39,1337,1339],{"className":41,"code":1338,"language":43,"meta":44,"style":44},"public interface InterfaceName\u003CE> { \u002F* ... *\u002F }\n \n\u002F\u002F real-world examples you already know:\npublic interface Comparable\u003CE> { \u002F* ... *\u002F }\npublic interface Edible\u003CE>     { \u002F* ... *\u002F }\n",[46,1340,1341,1364,1368,1373,1392],{"__ignoreMap":44},[49,1342,1343,1345,1348,1351,1353,1355,1358,1361],{"class":51,"line":52},[49,1344,56],{"class":55},[49,1346,1347],{"class":55}," interface",[49,1349,1350],{"class":62}," InterfaceName",[49,1352,975],{"class":66},[49,1354,448],{"class":55},[49,1356,1357],{"class":66},"> { ",[49,1359,1360],{"class":109},"\u002F* ... *\u002F",[49,1362,1363],{"class":66}," }\n",[49,1365,1366],{"class":51,"line":88},[49,1367,91],{"class":66},[49,1369,1370],{"class":51,"line":94},[49,1371,1372],{"class":109},"\u002F\u002F real-world examples you already know:\n",[49,1374,1375,1377,1379,1382,1384,1386,1388,1390],{"class":51,"line":113},[49,1376,56],{"class":55},[49,1378,1347],{"class":55},[49,1380,1381],{"class":62}," Comparable",[49,1383,975],{"class":66},[49,1385,448],{"class":55},[49,1387,1357],{"class":66},[49,1389,1360],{"class":109},[49,1391,1363],{"class":66},[49,1393,1394,1396,1398,1401,1403,1405,1408,1410],{"class":51,"line":1042},[49,1395,56],{"class":55},[49,1397,1347],{"class":55},[49,1399,1400],{"class":62}," Edible",[49,1402,975],{"class":66},[49,1404,448],{"class":55},[49,1406,1407],{"class":66},">     { ",[49,1409,1360],{"class":109},[49,1411,1363],{"class":66},[21,1413,1414],{},"And you can declare a class as a subtype of a generic interface:",[39,1416,1418],{"className":41,"code":1417,"language":43,"meta":44,"style":44},"public class String implements Comparable\u003CString> { \u002F* ... *\u002F }\n",[46,1419,1420],{"__ignoreMap":44},[49,1421,1422,1424,1426,1429,1432,1434,1436,1438,1440,1442],{"class":51,"line":52},[49,1423,56],{"class":55},[49,1425,969],{"class":55},[49,1427,1428],{"class":62}," String",[49,1430,1431],{"class":55}," implements",[49,1433,1381],{"class":62},[49,1435,975],{"class":66},[49,1437,152],{"class":55},[49,1439,1357],{"class":66},[49,1441,1360],{"class":109},[49,1443,1363],{"class":66},[11,1445,1447],{"id":1446},"_7-generic-methods","7. Generic methods",[21,1449,1450,1451,1454],{},"You can make a ",[16,1452,1453],{},"single method"," generic, even if its class isn't generic.",[21,1456,1457],{},[24,1458,1459],{},"Syntax:",[39,1461,1463],{"className":41,"code":1462,"language":43,"meta":44,"style":44},"public static \u003CE> returnType methodName(E parameter) { ... }\n",[46,1464,1465],{"__ignoreMap":44},[49,1466,1467,1469,1472,1475,1477,1480,1483,1486],{"class":51,"line":52},[49,1468,56],{"class":55},[49,1470,1471],{"class":55}," static",[49,1473,1474],{"class":55}," \u003C",[49,1476,448],{"class":66},[49,1478,1479],{"class":55},">",[49,1481,1482],{"class":66}," returnType ",[49,1484,1485],{"class":62},"methodName",[49,1487,1488],{"class":66},"(E parameter) { ... }\n",[21,1490,1491,1492,1494,1495,1498],{},"The ",[46,1493,440],{}," sits ",[24,1496,1497],{},"right before the return type",". Examples:",[39,1500,1502],{"className":41,"code":1501,"language":43,"meta":44,"style":44},"public static \u003CE> void print(E[] list) {\n    for (int i = 0; i \u003C list.length; i++)\n        System.out.print(list[i] + \" \");\n    System.out.println();\n}\n \npublic \u003CE> boolean isFilled(E filled) { \u002F* ... *\u002F }\n",[46,1503,1504,1528,1560,1579,1590,1594,1598],{"__ignoreMap":44},[49,1505,1506,1508,1510,1512,1514,1516,1518,1521,1523,1525],{"class":51,"line":52},[49,1507,56],{"class":55},[49,1509,1471],{"class":55},[49,1511,1474],{"class":55},[49,1513,448],{"class":66},[49,1515,1479],{"class":55},[49,1517,1071],{"class":55},[49,1519,1520],{"class":62}," print",[49,1522,67],{"class":66},[49,1524,448],{"class":55},[49,1526,1527],{"class":66},"[] list) {\n",[49,1529,1530,1533,1536,1538,1541,1543,1546,1549,1551,1554,1557],{"class":51,"line":88},[49,1531,1532],{"class":55},"    for",[49,1534,1535],{"class":66}," (",[49,1537,70],{"class":55},[49,1539,1540],{"class":66}," i ",[49,1542,158],{"class":55},[49,1544,1545],{"class":102}," 0",[49,1547,1548],{"class":66},"; i ",[49,1550,975],{"class":55},[49,1552,1553],{"class":66}," list.length; i",[49,1555,1556],{"class":55},"++",[49,1558,1559],{"class":66},")\n",[49,1561,1562,1565,1568,1571,1574,1577],{"class":51,"line":94},[49,1563,1564],{"class":66},"        System.out.",[49,1566,1567],{"class":62},"print",[49,1569,1570],{"class":66},"(list[i] ",[49,1572,1573],{"class":55},"+",[49,1575,1576],{"class":262}," \" \"",[49,1578,266],{"class":66},[49,1580,1581,1584,1587],{"class":51,"line":113},[49,1582,1583],{"class":66},"    System.out.",[49,1585,1586],{"class":62},"println",[49,1588,1589],{"class":66},"();\n",[49,1591,1592],{"class":51,"line":1042},[49,1593,990],{"class":66},[49,1595,1596],{"class":51,"line":1061},[49,1597,91],{"class":66},[49,1599,1600,1602,1604,1606,1608,1610,1613,1616,1618],{"class":51,"line":1066},[49,1601,56],{"class":55},[49,1603,1474],{"class":55},[49,1605,448],{"class":66},[49,1607,1479],{"class":55},[49,1609,1032],{"class":55},[49,1611,1612],{"class":62}," isFilled",[49,1614,1615],{"class":66},"(E filled) { ",[49,1617,1360],{"class":109},[49,1619,1363],{"class":66},[21,1621,1622],{},"Calling it:",[39,1624,1626],{"className":41,"code":1625,"language":43,"meta":44,"style":44},"Integer[] integers = {1, 2, 3, 4, 5};\nString[]  strings  = {\"London\", \"Paris\", \"New York\", \"Austin\"};\n \nGenericMethodDemo.\u003CInteger>print(integers);   \u002F\u002F explicit type\nGenericMethodDemo.\u003CString>print(strings);     \u002F\u002F explicit type\nGenericMethodDemo.print(integers);            \u002F\u002F or just let Java figure it out\n",[46,1627,1628,1665,1696,1700,1719,1736],{"__ignoreMap":44},[49,1629,1630,1632,1635,1637,1640,1643,1645,1648,1650,1652,1654,1657,1659,1662],{"class":51,"line":52},[49,1631,174],{"class":55},[49,1633,1634],{"class":66},"[] integers ",[49,1636,158],{"class":55},[49,1638,1639],{"class":66}," {",[49,1641,1642],{"class":102},"1",[49,1644,922],{"class":66},[49,1646,1647],{"class":102},"2",[49,1649,922],{"class":66},[49,1651,103],{"class":102},[49,1653,922],{"class":66},[49,1655,1656],{"class":102},"4",[49,1658,922],{"class":66},[49,1660,1661],{"class":102},"5",[49,1663,1664],{"class":66},"};\n",[49,1666,1667,1669,1672,1674,1676,1679,1681,1684,1686,1689,1691,1694],{"class":51,"line":88},[49,1668,152],{"class":55},[49,1670,1671],{"class":66},"[]  strings  ",[49,1673,158],{"class":55},[49,1675,1639],{"class":66},[49,1677,1678],{"class":262},"\"London\"",[49,1680,922],{"class":66},[49,1682,1683],{"class":262},"\"Paris\"",[49,1685,922],{"class":66},[49,1687,1688],{"class":262},"\"New York\"",[49,1690,922],{"class":66},[49,1692,1693],{"class":262},"\"Austin\"",[49,1695,1664],{"class":66},[49,1697,1698],{"class":51,"line":94},[49,1699,91],{"class":66},[49,1701,1702,1705,1707,1709,1711,1713,1716],{"class":51,"line":113},[49,1703,1704],{"class":66},"GenericMethodDemo.",[49,1706,975],{"class":55},[49,1708,174],{"class":66},[49,1710,1479],{"class":55},[49,1712,1567],{"class":62},[49,1714,1715],{"class":66},"(integers);   ",[49,1717,1718],{"class":109},"\u002F\u002F explicit type\n",[49,1720,1721,1723,1725,1727,1729,1731,1734],{"class":51,"line":1042},[49,1722,1704],{"class":66},[49,1724,975],{"class":55},[49,1726,152],{"class":66},[49,1728,1479],{"class":55},[49,1730,1567],{"class":62},[49,1732,1733],{"class":66},"(strings);     ",[49,1735,1718],{"class":109},[49,1737,1738,1740,1742,1745],{"class":51,"line":1061},[49,1739,1704],{"class":66},[49,1741,1567],{"class":62},[49,1743,1744],{"class":66},"(integers);            ",[49,1746,1747],{"class":109},"\u002F\u002F or just let Java figure it out\n",[21,1749,1750,1751,1754],{},"The compiler is usually smart enough to infer the type from the argument, so the explicit ",[46,1752,1753],{},"\u003CInteger>"," is optional in most cases.",[11,1756,1758,1759,1762],{"id":1757},"_8-bounded-generics-i-want-any-type-but-only-certain-ones","8. Bounded generics — \"I want ",[16,1760,1761],{},"any"," type, but only certain ones\"",[21,1764,1765,1766,1768,1769,1772],{},"Sometimes you want a generic that accepts ",[16,1767,1761],{}," type — ",[16,1770,1771],{},"as long as it has certain capabilities",". Example: a method that only makes sense for numbers.",[21,1774,1775,1776,1779],{},"You use the ",[46,1777,1778],{},"extends"," keyword:",[39,1781,1783],{"className":41,"code":1782,"language":43,"meta":44,"style":44},"public \u003CU extends Number> void inspect(U u) { \u002F* ... *\u002F }\n",[46,1784,1785],{"__ignoreMap":44},[49,1786,1787,1789,1791,1794,1796,1798,1801,1804,1806],{"class":51,"line":52},[49,1788,56],{"class":55},[49,1790,1474],{"class":55},[49,1792,1793],{"class":66},"U extends Number",[49,1795,1479],{"class":55},[49,1797,1071],{"class":55},[49,1799,1800],{"class":62}," inspect",[49,1802,1803],{"class":66},"(U u) { ",[49,1805,1360],{"class":109},[49,1807,1363],{"class":66},[21,1809,1810,1811,1814,1815,1818,1819,1824,1825,922,1827,922,1829,1832,1833,1835],{},"This says: \"",[46,1812,1813],{},"U"," can be any type, ",[24,1816,1817],{},"but it has to be a subtype of"," ",[24,1820,1821],{},[46,1822,1823],{},"Number",".\" So ",[46,1826,174],{},[46,1828,883],{},[46,1830,1831],{},"Float"," all work — ",[46,1834,152],{}," does not.",[39,1837,1839],{"className":41,"code":1838,"language":43,"meta":44,"style":44},"public class BoundedGeneric2\u003CT extends Number> {\n    T data;\n    public BoundedGeneric2(T t) { data = t; }\n    void display() {\n        System.out.println(\"Value is : \" + data);\n        System.out.println(\" and type is \" + data.getClass().getName());\n    }\n}\n \n\u002F\u002F Usage:\nBoundedGeneric2\u003CInteger> b1 = new BoundedGeneric2\u003C>(3);      \u002F\u002F ✅\nBoundedGeneric2\u003CDouble>  b2 = new BoundedGeneric2\u003C>(3.14);   \u002F\u002F ✅\nBoundedGeneric2\u003CString>  b3 = new BoundedGeneric2\u003C>(\"Hi\");   \u002F\u002F ❌ compile error\n",[46,1840,1841,1862,1867,1886,1896,1913,1941,1945,1949,1953,1958,1983,2005],{"__ignoreMap":44},[49,1842,1843,1845,1847,1850,1852,1854,1857,1860],{"class":51,"line":52},[49,1844,56],{"class":55},[49,1846,969],{"class":55},[49,1848,1849],{"class":62}," BoundedGeneric2",[49,1851,975],{"class":66},[49,1853,834],{"class":55},[49,1855,1856],{"class":55}," extends",[49,1858,1859],{"class":55}," Number",[49,1861,980],{"class":66},[49,1863,1864],{"class":51,"line":88},[49,1865,1866],{"class":66},"    T data;\n",[49,1868,1869,1871,1873,1875,1878,1881,1883],{"class":51,"line":94},[49,1870,1045],{"class":55},[49,1872,1849],{"class":62},[49,1874,1077],{"class":66},[49,1876,1877],{"class":1080},"t",[49,1879,1880],{"class":66},") { data ",[49,1882,158],{"class":55},[49,1884,1885],{"class":66}," t; }\n",[49,1887,1888,1891,1894],{"class":51,"line":113},[49,1889,1890],{"class":55},"    void",[49,1892,1893],{"class":62}," display",[49,1895,1136],{"class":66},[49,1897,1898,1900,1902,1904,1907,1910],{"class":51,"line":1042},[49,1899,1564],{"class":66},[49,1901,1586],{"class":62},[49,1903,67],{"class":66},[49,1905,1906],{"class":262},"\"Value is : \"",[49,1908,1909],{"class":55}," +",[49,1911,1912],{"class":66}," data);\n",[49,1914,1915,1917,1919,1921,1924,1926,1929,1932,1935,1938],{"class":51,"line":1061},[49,1916,1564],{"class":66},[49,1918,1586],{"class":62},[49,1920,67],{"class":66},[49,1922,1923],{"class":262},"\" and type is \"",[49,1925,1909],{"class":55},[49,1927,1928],{"class":66}," data.",[49,1930,1931],{"class":62},"getClass",[49,1933,1934],{"class":66},"().",[49,1936,1937],{"class":62},"getName",[49,1939,1940],{"class":66},"());\n",[49,1942,1943],{"class":51,"line":1066},[49,1944,1118],{"class":66},[49,1946,1947],{"class":51,"line":1087},[49,1948,990],{"class":66},[49,1950,1951],{"class":51,"line":1101},[49,1952,91],{"class":66},[49,1954,1955],{"class":51,"line":1115},[49,1956,1957],{"class":109},"\u002F\u002F Usage:\n",[49,1959,1960,1963,1965,1968,1970,1972,1975,1977,1980],{"class":51,"line":1121},[49,1961,1962],{"class":66},"BoundedGeneric2\u003C",[49,1964,174],{"class":55},[49,1966,1967],{"class":66},"> b1 ",[49,1969,158],{"class":55},[49,1971,161],{"class":55},[49,1973,1974],{"class":66}," BoundedGeneric2\u003C>(",[49,1976,103],{"class":102},[49,1978,1979],{"class":66},");      ",[49,1981,1982],{"class":109},"\u002F\u002F ✅\n",[49,1984,1985,1987,1989,1992,1994,1996,1998,2001,2003],{"class":51,"line":1126},[49,1986,1962],{"class":66},[49,1988,883],{"class":55},[49,1990,1991],{"class":66},">  b2 ",[49,1993,158],{"class":55},[49,1995,161],{"class":55},[49,1997,1974],{"class":66},[49,1999,2000],{"class":102},"3.14",[49,2002,106],{"class":66},[49,2004,1982],{"class":109},[49,2006,2007,2009,2011,2014,2016,2018,2020,2023,2025],{"class":51,"line":1139},[49,2008,1962],{"class":66},[49,2010,152],{"class":55},[49,2012,2013],{"class":66},">  b3 ",[49,2015,158],{"class":55},[49,2017,161],{"class":55},[49,2019,1974],{"class":66},[49,2021,2022],{"class":262},"\"Hi\"",[49,2024,106],{"class":66},[49,2026,912],{"class":109},[503,2028,2030],{"id":2029},"trivia","Trivia",[21,2032,2033,2034,2037,2038,2040,2041,2044,2045,37],{},"An ",[24,2035,2036],{},"unbounded"," generic ",[46,2039,440],{}," is secretly the same as ",[46,2042,2043],{},"\u003CE extends Object>"," — because every class in Java extends ",[46,2046,2047],{},"Object",[11,2049,2051],{"id":2050},"_9-raw-types-and-why-theyre-a-trap","9. Raw types (and why they're a trap)",[21,2053,128,2054,2057],{},[24,2055,2056],{},"raw type"," is a generic class used without specifying a type parameter:",[39,2059,2061],{"className":41,"code":2060,"language":43,"meta":44,"style":44},"ArrayList list = new ArrayList();   \u002F\u002F raw — no \u003C>\n",[46,2062,2063],{"__ignoreMap":44},[49,2064,2065,2067,2069,2071,2073,2076],{"class":51,"line":52},[49,2066,236],{"class":66},[49,2068,158],{"class":55},[49,2070,161],{"class":55},[49,2072,243],{"class":62},[49,2074,2075],{"class":66},"();   ",[49,2077,2078],{"class":109},"\u002F\u002F raw — no \u003C>\n",[21,2080,2081,2082,2085,2086,2089,2090,2093],{},"This is ",[16,2083,2084],{},"roughly"," equivalent to ",[46,2087,2088],{},"ArrayList\u003CObject>",". Java still allows raw types so old pre-2004 code keeps working (this is called ",[24,2091,2092],{},"backward compatibility","). But you should not write new code this way.",[503,2095,2097],{"id":2096},"why-raw-types-are-unsafe","Why raw types are unsafe",[21,2099,2100],{},"Look at this innocent-looking method:",[39,2102,2104],{"className":41,"code":2103,"language":43,"meta":44,"style":44},"public static Comparable max(Comparable o1, Comparable o2) {\n    if (o1.compareTo(o2) > 0) return o1;\n    else return o2;\n}\n",[46,2105,2106,2121,2146,2157],{"__ignoreMap":44},[49,2107,2108,2110,2112,2115,2118],{"class":51,"line":52},[49,2109,56],{"class":55},[49,2111,1471],{"class":55},[49,2113,2114],{"class":66}," Comparable ",[49,2116,2117],{"class":62},"max",[49,2119,2120],{"class":66},"(Comparable o1, Comparable o2) {\n",[49,2122,2123,2126,2129,2131,2134,2136,2138,2141,2143],{"class":51,"line":88},[49,2124,2125],{"class":55},"    if",[49,2127,2128],{"class":66}," (o1.",[49,2130,1330],{"class":62},[49,2132,2133],{"class":66},"(o2) ",[49,2135,1479],{"class":55},[49,2137,1545],{"class":102},[49,2139,2140],{"class":66},") ",[49,2142,76],{"class":55},[49,2144,2145],{"class":66}," o1;\n",[49,2147,2148,2151,2154],{"class":51,"line":94},[49,2149,2150],{"class":55},"    else",[49,2152,2153],{"class":55}," return",[49,2155,2156],{"class":66}," o2;\n",[49,2158,2159],{"class":51,"line":113},[49,2160,990],{"class":66},[21,2162,2163],{},"It compiles. It looks fine. Then:",[39,2165,2167],{"className":41,"code":2166,"language":43,"meta":44,"style":44},"Max.max(\"Welcome\", 23);   \u002F\u002F 💥 ClassCastException at runtime\n",[46,2168,2169],{"__ignoreMap":44},[49,2170,2171,2174,2176,2178,2181,2183,2186,2188],{"class":51,"line":52},[49,2172,2173],{"class":66},"Max.",[49,2175,2117],{"class":62},[49,2177,67],{"class":66},[49,2179,2180],{"class":262},"\"Welcome\"",[49,2182,922],{"class":66},[49,2184,2185],{"class":102},"23",[49,2187,106],{"class":66},[49,2189,2190],{"class":109},"\u002F\u002F 💥 ClassCastException at runtime\n",[21,2192,2193,2194,2197],{},"The compiler can't catch the bug because ",[46,2195,2196],{},"Comparable"," is raw. Fix it with generics:",[39,2199,2201],{"className":41,"code":2200,"language":43,"meta":44,"style":44},"public static \u003CE extends Comparable\u003CE>> E max(E o1, E o2) {\n    if (o1.compareTo(o2) > 0) return o1;\n    else return o2;\n}\n \nMax.max(\"Welcome\", 23);   \u002F\u002F ❌ now caught at compile time\n",[46,2202,2203,2229,2249,2257,2261,2265],{"__ignoreMap":44},[49,2204,2205,2207,2209,2211,2214,2216,2218,2221,2224,2226],{"class":51,"line":52},[49,2206,56],{"class":55},[49,2208,1471],{"class":55},[49,2210,1474],{"class":55},[49,2212,2213],{"class":66},"E extends Comparable",[49,2215,975],{"class":55},[49,2217,448],{"class":66},[49,2219,2220],{"class":55},">>",[49,2222,2223],{"class":66}," E ",[49,2225,2117],{"class":62},[49,2227,2228],{"class":66},"(E o1, E o2) {\n",[49,2230,2231,2233,2235,2237,2239,2241,2243,2245,2247],{"class":51,"line":88},[49,2232,2125],{"class":55},[49,2234,2128],{"class":66},[49,2236,1330],{"class":62},[49,2238,2133],{"class":66},[49,2240,1479],{"class":55},[49,2242,1545],{"class":102},[49,2244,2140],{"class":66},[49,2246,76],{"class":55},[49,2248,2145],{"class":66},[49,2250,2251,2253,2255],{"class":51,"line":94},[49,2252,2150],{"class":55},[49,2254,2153],{"class":55},[49,2256,2156],{"class":66},[49,2258,2259],{"class":51,"line":113},[49,2260,990],{"class":66},[49,2262,2263],{"class":51,"line":1042},[49,2264,91],{"class":66},[49,2266,2267,2269,2271,2273,2275,2277,2279,2281],{"class":51,"line":1061},[49,2268,2173],{"class":66},[49,2270,2117],{"class":62},[49,2272,67],{"class":66},[49,2274,2180],{"class":262},[49,2276,922],{"class":66},[49,2278,2185],{"class":102},[49,2280,106],{"class":66},[49,2282,2283],{"class":109},"\u002F\u002F ❌ now caught at compile time\n",[11,2285,2287,2288,922,2290,922,2293],{"id":2286},"_10-wildcards-extends-t-super-t","10. Wildcards: ",[46,2289,1195],{},[46,2291,2292],{},"? extends T",[46,2294,2295],{},"? super T",[21,2297,2298],{},"This part trips people up, so go slowly.",[503,2300,2302],{"id":2301},"why-wildcards-exist","Why wildcards exist",[21,2304,2305,2306,2309,2310,2313],{},"You might think: \"Integer is a subtype of Number, so ",[46,2307,2308],{},"ArrayList\u003CInteger>"," should be a subtype of ",[46,2311,2312],{},"ArrayList\u003CNumber>",", right?\"",[21,2315,2316,2319,2320,2322,2323,2325,2326,2329],{},[24,2317,2318],{},"Wrong."," In Java, ",[46,2321,2308],{}," and ",[46,2324,2312],{}," are ",[16,2327,2328],{},"unrelated"," types. This code fails to compile:",[39,2331,2333],{"className":41,"code":2332,"language":43,"meta":44,"style":44},"public static void display(ArrayList\u003CNumber> list) { \u002F* ... *\u002F }\n \nArrayList\u003CInteger> list1 = new ArrayList\u003C>();\ndisplay(list1);   \u002F\u002F ❌ compile error\n",[46,2334,2335,2361,2365,2380],{"__ignoreMap":44},[49,2336,2337,2339,2341,2343,2345,2348,2350,2352,2354,2357,2359],{"class":51,"line":52},[49,2338,56],{"class":55},[49,2340,1471],{"class":55},[49,2342,1071],{"class":55},[49,2344,1893],{"class":62},[49,2346,2347],{"class":66},"(ArrayList",[49,2349,975],{"class":55},[49,2351,1823],{"class":66},[49,2353,1479],{"class":55},[49,2355,2356],{"class":66}," list) { ",[49,2358,1360],{"class":109},[49,2360,1363],{"class":66},[49,2362,2363],{"class":51,"line":88},[49,2364,91],{"class":66},[49,2366,2367,2369,2371,2374,2376,2378],{"class":51,"line":94},[49,2368,149],{"class":66},[49,2370,174],{"class":55},[49,2372,2373],{"class":66},"> list1 ",[49,2375,158],{"class":55},[49,2377,161],{"class":55},[49,2379,342],{"class":66},[49,2381,2382,2385,2388],{"class":51,"line":113},[49,2383,2384],{"class":62},"display",[49,2386,2387],{"class":66},"(list1);   ",[49,2389,912],{"class":109},[21,2391,2392,2393,2396,2397,2399],{},"The fix: ",[24,2394,2395],{},"wildcards",". Use ",[46,2398,1195],{}," to say \"I don't care what specific type — just a list of something.\"",[503,2401,2403],{"id":2402},"the-three-forms","The three forms",[508,2405,2406,2418],{},[511,2407,2408],{},[514,2409,2410,2413,2416],{},[517,2411,2412],{},"Form",[517,2414,2415],{},"Name",[517,2417,769],{},[524,2419,2420,2433,2450],{},[514,2421,2422,2427,2430],{},[529,2423,2424],{},[46,2425,2426],{},"\u003C?>",[529,2428,2429],{},"Unbounded wildcard",[529,2431,2432],{},"Any type at all",[514,2434,2435,2440,2443],{},[529,2436,2437],{},[46,2438,2439],{},"\u003C? extends T>",[529,2441,2442],{},"Upper-bounded wildcard",[529,2444,2445,2446,2449],{},"Some unknown ",[24,2447,2448],{},"subtype"," of T",[514,2451,2452,2457,2460],{},[529,2453,2454],{},[46,2455,2456],{},"\u003C? super T>",[529,2458,2459],{},"Lower-bounded wildcard",[529,2461,2445,2462,2449],{},[24,2463,2464],{},"supertype",[21,2466,2467,2469,2470,37],{},[46,2468,2426],{}," is exactly the same as ",[46,2471,2472],{},"\u003C? extends Object>",[503,2474,2476],{"id":2475},"fixing-the-earlier-example","Fixing the earlier example",[39,2478,2480],{"className":41,"code":2479,"language":43,"meta":44,"style":44},"public static void display(ArrayList\u003C?> list) { \u002F* ... *\u002F }\n\u002F\u002F now display(list1) works for ArrayList\u003CInteger>, ArrayList\u003CDouble>, etc.\n",[46,2481,2482,2502],{"__ignoreMap":44},[49,2483,2484,2486,2488,2490,2492,2494,2496,2498,2500],{"class":51,"line":52},[49,2485,56],{"class":55},[49,2487,1471],{"class":55},[49,2489,1071],{"class":55},[49,2491,1893],{"class":62},[49,2493,2347],{"class":66},[49,2495,2426],{"class":55},[49,2497,2356],{"class":66},[49,2499,1360],{"class":109},[49,2501,1363],{"class":66},[49,2503,2504],{"class":51,"line":88},[49,2505,2506],{"class":109},"\u002F\u002F now display(list1) works for ArrayList\u003CInteger>, ArrayList\u003CDouble>, etc.\n",[11,2508,2510],{"id":2509},"_11-type-erasure-the-magic-trick-behind-generics","11. Type erasure (the magic trick behind generics)",[21,2512,2513,2514],{},"Here's the surprising part: ",[24,2515,2516],{},"at runtime, generics don't exist.",[21,2518,2519,2520,2523,2524,37],{},"When the Java compiler is done with your code, it ",[24,2521,2522],{},"erases"," all the type parameters. The compiled bytecode looks like the old, pre-generics code. This is called ",[24,2525,2526],{},"type erasure",[21,2528,2529],{},"What happens:",[2531,2532,2533,2540,2548],"ul",{},[298,2534,2535,2537,2538],{},[46,2536,440],{}," → replaced with ",[46,2539,2047],{},[298,2541,2542,2537,2545,2547],{},[46,2543,2544],{},"\u003CE extends Number>",[46,2546,1823],{}," (the bounded type)",[298,2549,2550],{},"Casts are auto-inserted where needed\nSo this:",[39,2552,2554],{"className":41,"code":2553,"language":43,"meta":44,"style":44},"ArrayList\u003CString> list = new ArrayList\u003C>();\nlist.add(\"Oklahoma\");\nString state = list.get(0);\n",[46,2555,2556,2570,2583],{"__ignoreMap":44},[49,2557,2558,2560,2562,2564,2566,2568],{"class":51,"line":52},[49,2559,149],{"class":66},[49,2561,152],{"class":55},[49,2563,335],{"class":66},[49,2565,158],{"class":55},[49,2567,161],{"class":55},[49,2569,342],{"class":66},[49,2571,2572,2574,2576,2578,2581],{"class":51,"line":88},[49,2573,254],{"class":66},[49,2575,257],{"class":62},[49,2577,67],{"class":66},[49,2579,2580],{"class":262},"\"Oklahoma\"",[49,2582,266],{"class":66},[49,2584,2585,2588,2590,2592,2594,2596,2598],{"class":51,"line":94},[49,2586,2587],{"class":66},"String state ",[49,2589,158],{"class":55},[49,2591,363],{"class":66},[49,2593,279],{"class":62},[49,2595,67],{"class":66},[49,2597,284],{"class":102},[49,2599,266],{"class":66},[21,2601,2602],{},"...effectively becomes this at runtime:",[39,2604,2606],{"className":41,"code":2605,"language":43,"meta":44,"style":44},"ArrayList list = new ArrayList();\nlist.add(\"Oklahoma\");\nString state = (String) list.get(0);\n",[46,2607,2608,2620,2632],{"__ignoreMap":44},[49,2609,2610,2612,2614,2616,2618],{"class":51,"line":52},[49,2611,236],{"class":66},[49,2613,158],{"class":55},[49,2615,161],{"class":55},[49,2617,243],{"class":62},[49,2619,1589],{"class":66},[49,2621,2622,2624,2626,2628,2630],{"class":51,"line":88},[49,2623,254],{"class":66},[49,2625,257],{"class":62},[49,2627,67],{"class":66},[49,2629,2580],{"class":262},[49,2631,266],{"class":66},[49,2633,2634,2636,2638,2640,2642,2644,2646],{"class":51,"line":94},[49,2635,2587],{"class":66},[49,2637,158],{"class":55},[49,2639,276],{"class":66},[49,2641,279],{"class":62},[49,2643,67],{"class":66},[49,2645,284],{"class":102},[49,2647,266],{"class":66},[21,2649,2650,2651,2654],{},"Generics are basically ",[24,2652,2653],{},"a compile-time-only feature",". They protect you while you're writing code, then quietly disappear.",[503,2656,2658],{"id":2657},"a-weird-consequence","A weird consequence",[39,2660,2662],{"className":41,"code":2661,"language":43,"meta":44,"style":44},"ArrayList\u003CString>  list1 = new ArrayList\u003C>();\nArrayList\u003CInteger> list2 = new ArrayList\u003C>();\n \nSystem.out.println(list1 instanceof ArrayList);   \u002F\u002F true\nSystem.out.println(list2 instanceof ArrayList);   \u002F\u002F true\n",[46,2663,2664,2679,2694,2698,2717],{"__ignoreMap":44},[49,2665,2666,2668,2670,2673,2675,2677],{"class":51,"line":52},[49,2667,149],{"class":66},[49,2669,152],{"class":55},[49,2671,2672],{"class":66},">  list1 ",[49,2674,158],{"class":55},[49,2676,161],{"class":55},[49,2678,342],{"class":66},[49,2680,2681,2683,2685,2688,2690,2692],{"class":51,"line":88},[49,2682,149],{"class":66},[49,2684,174],{"class":55},[49,2686,2687],{"class":66},"> list2 ",[49,2689,158],{"class":55},[49,2691,161],{"class":55},[49,2693,342],{"class":66},[49,2695,2696],{"class":51,"line":94},[49,2697,91],{"class":66},[49,2699,2700,2703,2705,2708,2711,2714],{"class":51,"line":113},[49,2701,2702],{"class":66},"System.out.",[49,2704,1586],{"class":62},[49,2706,2707],{"class":66},"(list1 ",[49,2709,2710],{"class":55},"instanceof",[49,2712,2713],{"class":66}," ArrayList);   ",[49,2715,2716],{"class":109},"\u002F\u002F true\n",[49,2718,2719,2721,2723,2726,2728,2730],{"class":51,"line":1042},[49,2720,2702],{"class":66},[49,2722,1586],{"class":62},[49,2724,2725],{"class":66},"(list2 ",[49,2727,2710],{"class":55},[49,2729,2713],{"class":66},[49,2731,2716],{"class":109},[21,2733,2734,2735,2322,2738,2740,2741,1818,2744,1818,2748,2751,2752,2322,2755,2757],{},"Even though ",[46,2736,2737],{},"ArrayList\u003CString>",[46,2739,2308],{}," look like two different types, ",[24,2742,2743],{},"only one",[24,2745,2746],{},[46,2747,211],{},[24,2749,2750],{},"class is actually loaded into the JVM",". The ",[46,2753,2754],{},"\u003CString>",[46,2756,1753],{}," parts vanish.",[11,2759,2761],{"id":2760},"_12-the-four-restrictions-on-generics","12. The four restrictions on generics",[21,2763,2764,2765,2768],{},"Because of type erasure, there are things you simply ",[16,2766,2767],{},"cannot"," do. Memorize these — they show up on every Java generics exam.",[503,2770,2772,2773],{"id":2771},"restriction-1-cant-create-an-instance-of-e","❌ Restriction 1: Can't create an instance of ",[46,2774,448],{},[39,2776,2778],{"className":41,"code":2777,"language":43,"meta":44,"style":44},"E object = new E();   \u002F\u002F compile error\n",[46,2779,2780],{"__ignoreMap":44},[49,2781,2782,2785,2787,2789,2792,2794],{"class":51,"line":52},[49,2783,2784],{"class":66},"E object ",[49,2786,158],{"class":55},[49,2788,161],{"class":55},[49,2790,2791],{"class":62}," E",[49,2793,2075],{"class":66},[49,2795,2796],{"class":109},"\u002F\u002F compile error\n",[21,2798,2799,2800,2803,2804,2806],{},"Why? ",[46,2801,2802],{},"new E()"," would run at runtime, but by then ",[46,2805,448],{}," has been erased. The JVM has no idea what type to actually instantiate.",[503,2808,2810],{"id":2809},"restriction-2-cant-create-a-generic-array","❌ Restriction 2: Can't create a generic array",[39,2812,2814],{"className":41,"code":2813,"language":43,"meta":44,"style":44},"E[] elements = new E[capacity];   \u002F\u002F compile error\n",[46,2815,2816],{"__ignoreMap":44},[49,2817,2818,2820,2823,2825,2827,2829,2832],{"class":51,"line":52},[49,2819,448],{"class":55},[49,2821,2822],{"class":66},"[] elements ",[49,2824,158],{"class":55},[49,2826,161],{"class":55},[49,2828,2791],{"class":55},[49,2830,2831],{"class":66},"[capacity];   ",[49,2833,2796],{"class":109},[21,2835,2836],{},"Workaround:",[39,2838,2840],{"className":41,"code":2839,"language":43,"meta":44,"style":44},"E[] elements = (E[]) new Object[capacity];   \u002F\u002F ⚠️ unchecked warning\n",[46,2841,2842],{"__ignoreMap":44},[49,2843,2844,2846,2848,2850,2852,2854,2857,2860,2863,2865],{"class":51,"line":52},[49,2845,448],{"class":55},[49,2847,2822],{"class":66},[49,2849,158],{"class":55},[49,2851,1535],{"class":66},[49,2853,448],{"class":55},[49,2855,2856],{"class":66},"[]) ",[49,2858,2859],{"class":55},"new",[49,2861,2862],{"class":55}," Object",[49,2864,2831],{"class":66},[49,2866,2867],{"class":109},"\u002F\u002F ⚠️ unchecked warning\n",[21,2869,2870],{},"This compiles but the compiler can't promise the cast will always succeed at runtime. Use carefully.",[503,2872,2874],{"id":2873},"restriction-3-generic-type-cant-be-used-in-a-static-context","❌ Restriction 3: Generic type can't be used in a static context",[39,2876,2878],{"className":41,"code":2877,"language":43,"meta":44,"style":44},"public class Test\u003CE> {\n    public static void m(E o1) { }    \u002F\u002F ❌ illegal\n    public static E o1;               \u002F\u002F ❌ illegal\n    static { E o2; }                  \u002F\u002F ❌ illegal\n}\n",[46,2879,2880,2895,2918,2929,2939],{"__ignoreMap":44},[49,2881,2882,2884,2886,2889,2891,2893],{"class":51,"line":52},[49,2883,56],{"class":55},[49,2885,969],{"class":55},[49,2887,2888],{"class":62}," Test",[49,2890,975],{"class":66},[49,2892,448],{"class":55},[49,2894,980],{"class":66},[49,2896,2897,2899,2901,2903,2906,2909,2912,2915],{"class":51,"line":88},[49,2898,1045],{"class":55},[49,2900,1471],{"class":55},[49,2902,1071],{"class":55},[49,2904,2905],{"class":62}," m",[49,2907,2908],{"class":66},"(E ",[49,2910,2911],{"class":1080},"o1",[49,2913,2914],{"class":66},") { }    ",[49,2916,2917],{"class":109},"\u002F\u002F ❌ illegal\n",[49,2919,2920,2922,2924,2927],{"class":51,"line":94},[49,2921,1045],{"class":55},[49,2923,1471],{"class":55},[49,2925,2926],{"class":66}," E o1;               ",[49,2928,2917],{"class":109},[49,2930,2931,2934,2937],{"class":51,"line":113},[49,2932,2933],{"class":55},"    static",[49,2935,2936],{"class":66}," { E o2; }                  ",[49,2938,2917],{"class":109},[49,2940,2941],{"class":51,"line":1042},[49,2942,990],{"class":66},[21,2944,2945,2946,2949,2950,2952],{},"Why? Static members belong to the ",[16,2947,2948],{},"class itself",", not any specific instance. But ",[46,2951,448],{}," is decided per-instance, so it's meaningless in a static context.",[503,2954,2956],{"id":2955},"restriction-4-exception-classes-cant-be-generic","❌ Restriction 4: Exception classes can't be generic",[39,2958,2960],{"className":41,"code":2959,"language":43,"meta":44,"style":44},"public class MyException\u003CT> extends Exception { }   \u002F\u002F ❌ illegal\n",[46,2961,2962],{"__ignoreMap":44},[49,2963,2964,2966,2968,2971,2973,2975,2978,2980,2983,2986],{"class":51,"line":52},[49,2965,56],{"class":55},[49,2967,969],{"class":55},[49,2969,2970],{"class":62}," MyException",[49,2972,975],{"class":66},[49,2974,834],{"class":55},[49,2976,2977],{"class":66},"> ",[49,2979,1778],{"class":55},[49,2981,2982],{"class":62}," Exception",[49,2984,2985],{"class":66}," { }   ",[49,2987,2917],{"class":109},[21,2989,2799,2990,2993,2994,2997,2998,3001,3002,37],{},[46,2991,2992],{},"catch"," blocks have to inspect types at runtime — but generics are erased before runtime. So you can't write ",[46,2995,2996],{},"catch (MyException\u003CString> ex)"," because the JVM literally can't tell ",[46,2999,3000],{},"MyException\u003CString>"," apart from ",[46,3003,3004],{},"MyException\u003CInteger>",[11,3006,3008],{"id":3007},"_13-quick-cheat-sheet","13. Quick cheat sheet",[39,3010,3012],{"className":41,"code":3011,"language":43,"meta":44,"style":44},"\u002F\u002F Generic class\npublic class Box\u003CT> { T item; }\n \n\u002F\u002F Multiple type parameters\npublic class Pair\u003CK, V> { K key; V value; }\n \n\u002F\u002F Generic interface\npublic interface Comparable\u003CE> { int compareTo(E o); }\n \n\u002F\u002F Generic method\npublic static \u003CE> void print(E[] list) { \u002F* ... *\u002F }\n \n\u002F\u002F Bounded generic\npublic class NumberBox\u003CT extends Number> { T data; }\n \n\u002F\u002F Wildcard - any type\npublic static void show(ArrayList\u003C?> list) { \u002F* ... *\u002F }\n \n\u002F\u002F Wildcard - upper bounded\npublic static void sum(ArrayList\u003C? extends Number> list) { \u002F* ... *\u002F }\n \n\u002F\u002F Wildcard - lower bounded\npublic static void fill(ArrayList\u003C? super Integer> list) { \u002F* ... *\u002F }\n",[46,3013,3014,3019,3035,3039,3044,3064,3068,3073,3100,3104,3109,3136,3140,3145,3165,3169,3174,3195,3199,3204,3231,3236,3242],{"__ignoreMap":44},[49,3015,3016],{"class":51,"line":52},[49,3017,3018],{"class":109},"\u002F\u002F Generic class\n",[49,3020,3021,3023,3025,3028,3030,3032],{"class":51,"line":88},[49,3022,56],{"class":55},[49,3024,969],{"class":55},[49,3026,3027],{"class":62}," Box",[49,3029,975],{"class":66},[49,3031,834],{"class":55},[49,3033,3034],{"class":66},"> { T item; }\n",[49,3036,3037],{"class":51,"line":94},[49,3038,91],{"class":66},[49,3040,3041],{"class":51,"line":113},[49,3042,3043],{"class":109},"\u002F\u002F Multiple type parameters\n",[49,3045,3046,3048,3050,3053,3055,3057,3059,3061],{"class":51,"line":1042},[49,3047,56],{"class":55},[49,3049,969],{"class":55},[49,3051,3052],{"class":62}," Pair",[49,3054,975],{"class":66},[49,3056,793],{"class":55},[49,3058,922],{"class":66},[49,3060,808],{"class":55},[49,3062,3063],{"class":66},"> { K key; V value; }\n",[49,3065,3066],{"class":51,"line":1061},[49,3067,91],{"class":66},[49,3069,3070],{"class":51,"line":1066},[49,3071,3072],{"class":109},"\u002F\u002F Generic interface\n",[49,3074,3075,3077,3079,3081,3083,3085,3087,3089,3092,3094,3097],{"class":51,"line":1087},[49,3076,56],{"class":55},[49,3078,1347],{"class":55},[49,3080,1381],{"class":62},[49,3082,975],{"class":66},[49,3084,448],{"class":55},[49,3086,1357],{"class":66},[49,3088,70],{"class":55},[49,3090,3091],{"class":62}," compareTo",[49,3093,2908],{"class":66},[49,3095,3096],{"class":1080},"o",[49,3098,3099],{"class":66},"); }\n",[49,3101,3102],{"class":51,"line":1101},[49,3103,91],{"class":66},[49,3105,3106],{"class":51,"line":1115},[49,3107,3108],{"class":109},"\u002F\u002F Generic method\n",[49,3110,3111,3113,3115,3117,3119,3121,3123,3125,3127,3129,3132,3134],{"class":51,"line":1121},[49,3112,56],{"class":55},[49,3114,1471],{"class":55},[49,3116,1474],{"class":55},[49,3118,448],{"class":66},[49,3120,1479],{"class":55},[49,3122,1071],{"class":55},[49,3124,1520],{"class":62},[49,3126,67],{"class":66},[49,3128,448],{"class":55},[49,3130,3131],{"class":66},"[] list) { ",[49,3133,1360],{"class":109},[49,3135,1363],{"class":66},[49,3137,3138],{"class":51,"line":1126},[49,3139,91],{"class":66},[49,3141,3142],{"class":51,"line":1139},[49,3143,3144],{"class":109},"\u002F\u002F Bounded generic\n",[49,3146,3147,3149,3151,3154,3156,3158,3160,3162],{"class":51,"line":1152},[49,3148,56],{"class":55},[49,3150,969],{"class":55},[49,3152,3153],{"class":62}," NumberBox",[49,3155,975],{"class":66},[49,3157,834],{"class":55},[49,3159,1856],{"class":55},[49,3161,1859],{"class":55},[49,3163,3164],{"class":66},"> { T data; }\n",[49,3166,3167],{"class":51,"line":1163},[49,3168,91],{"class":66},[49,3170,3171],{"class":51,"line":1168},[49,3172,3173],{"class":109},"\u002F\u002F Wildcard - any type\n",[49,3175,3176,3178,3180,3182,3185,3187,3189,3191,3193],{"class":51,"line":1173},[49,3177,56],{"class":55},[49,3179,1471],{"class":55},[49,3181,1071],{"class":55},[49,3183,3184],{"class":62}," show",[49,3186,2347],{"class":66},[49,3188,2426],{"class":55},[49,3190,2356],{"class":66},[49,3192,1360],{"class":109},[49,3194,1363],{"class":66},[49,3196,3197],{"class":51,"line":1186},[49,3198,91],{"class":66},[49,3200,3201],{"class":51,"line":1214},[49,3202,3203],{"class":109},"\u002F\u002F Wildcard - upper bounded\n",[49,3205,3206,3208,3210,3212,3215,3217,3220,3223,3225,3227,3229],{"class":51,"line":1219},[49,3207,56],{"class":55},[49,3209,1471],{"class":55},[49,3211,1071],{"class":55},[49,3213,3214],{"class":62}," sum",[49,3216,2347],{"class":66},[49,3218,3219],{"class":55},"\u003C?",[49,3221,3222],{"class":66}," extends Number",[49,3224,1479],{"class":55},[49,3226,2356],{"class":66},[49,3228,1360],{"class":109},[49,3230,1363],{"class":66},[49,3232,3234],{"class":51,"line":3233},21,[49,3235,91],{"class":66},[49,3237,3239],{"class":51,"line":3238},22,[49,3240,3241],{"class":109},"\u002F\u002F Wildcard - lower bounded\n",[49,3243,3245,3247,3249,3251,3254,3256,3258,3261,3264,3266,3268,3270],{"class":51,"line":3244},23,[49,3246,56],{"class":55},[49,3248,1471],{"class":55},[49,3250,1071],{"class":55},[49,3252,3253],{"class":62}," fill",[49,3255,2347],{"class":66},[49,3257,3219],{"class":55},[49,3259,3260],{"class":102}," super",[49,3262,3263],{"class":66}," Integer",[49,3265,1479],{"class":55},[49,3267,2356],{"class":66},[49,3269,1360],{"class":109},[49,3271,1363],{"class":66},[3273,3274,3275],"style",{},"html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}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);}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}",{"title":44,"searchDepth":88,"depth":88,"links":3277},[3278,3280,3281,3286,3287,3288,3292,3293,3297,3300,3306,3309,3316],{"id":13,"depth":88,"text":3279},"1. What even is a generic?",{"id":222,"depth":88,"text":223},{"id":405,"depth":88,"text":3282,"children":3283},"3. Meeting ArrayList properly",[3284,3285],{"id":505,"depth":94,"text":506},{"id":639,"depth":94,"text":640},{"id":749,"depth":88,"text":750},{"id":852,"depth":88,"text":853},{"id":946,"depth":88,"text":3289,"children":3290},"6. Writing your own generic class",[3291],{"id":1334,"depth":94,"text":1335},{"id":1446,"depth":88,"text":1447},{"id":1757,"depth":88,"text":3294,"children":3295},"8. Bounded generics — \"I want any type, but only certain ones\"",[3296],{"id":2029,"depth":94,"text":2030},{"id":2050,"depth":88,"text":2051,"children":3298},[3299],{"id":2096,"depth":94,"text":2097},{"id":2286,"depth":88,"text":3301,"children":3302},"10. Wildcards: ?, ? extends T, ? super T",[3303,3304,3305],{"id":2301,"depth":94,"text":2302},{"id":2402,"depth":94,"text":2403},{"id":2475,"depth":94,"text":2476},{"id":2509,"depth":88,"text":2510,"children":3307},[3308],{"id":2657,"depth":94,"text":2658},{"id":2760,"depth":88,"text":2761,"children":3310},[3311,3313,3314,3315],{"id":2771,"depth":94,"text":3312},"❌ Restriction 1: Can't create an instance of E",{"id":2809,"depth":94,"text":2810},{"id":2873,"depth":94,"text":2874},{"id":2955,"depth":94,"text":2956},{"id":3007,"depth":88,"text":3008},"2026-05-12",false,"md",null,{},true,"\u002Fblog\u002FJava-Generics",{"title":5,"description":44},{"loc":3323},"blog\u002FJava-Generics","1NAqPd2ioUIVkURA3LlHu8eZauFjE5dfQsUM0-QxAls",112,{"id":3330,"extension":3331,"meta":3332,"series":3333,"stem":3442,"__hash__":3443},"series\u002Fseries.json","json",{},{"微積分教學":3334,"生活紀錄":3337,"Motor Control":3339,"生活隨筆":3353,"Motor learning":3357,"小兒物治":3375,"中風":3390,"平衡":3403,"Network Communication":3413,"CSA":3420,"機器學習":3426,"小腦":3430,"SCI脊髓損傷":3439},[3335,3336],"微積分隨筆-未完成版","2025數學回顧",[3338],"一個漂流到地球的故事",[3340,3341,3342,3343,3344,3345,3346,3347,3348,3349,3350,3351,3352],"控制自己-Be-water-my-friend","控制自己-Be-water-my-friend（二）","控制自己-Be-water-my-friend（三）","控制自己-Be-water-my-friend（四）","控制自己-Be-water-my-friend（五）","進階控制制制制","周圍理論學派（一）反射理論","周圍理論學派（二）階層理論","中樞理論學派（一）CPG","中樞理論學派（二）Motor-Program","模組理論","系統理論","動態模組理論",[3354,3355,3356],"你好，世界。","根本沒人在乎你的部落格","早安-午安-晚安",[3358,3359,3360,3361,3362,3363,3364,3365,3366,3367,3368,3369,3370,3371,3372,3373,3374],"動作學習（一）介紹","動作學習（二）form-of-learning","動作學習（三）Measurement-of-learning","動作學習（四）理論","動作學習（五）理論-2","動作學習（六）理論-3","動作學習（七）練習方式-1","動作學習（八）練習方式-2","動作學習（九）回饋-1","動作學習（十）回饋-2-擴增性(KR)","動作學習（十一）回饋-3-擴增性(KP)","動作學習（十一）回饋-4-(間隔+物理引導)","動作學習（十二）神經可塑性","動作學習（十二）神經可塑性2","動作學習（十三）臨床應用","動作學習（十四）記憶","動作學習（十五）影響表現的因素",[3376,3377,3378,3379,3380,3381,3382,3383,3384,3385,3386,3387,3388,3389],"腦性痲痺-CP","CP補充（一）","CP—Rood-&-Bobath","CP—Rood-&-Bobath（二）","Motor-Learning","Motor-Learning小兒（二）","Gait-analysis小兒（一）","Gait-analysis小兒（二）","小兒發展（一）","小兒發展（二）","小兒發展（三）","小兒發展（四）","小兒發展（五）","GMFCS",[3391,3392,3393,3394,3395,3396,3397,3398,3399,3400,3401,3402],"腦血管病變（CVA）（中風）(一)","CVA（二）","CVA（三）血管症候群-i","CVA（四）血管症候群-(ii)","CVA（四）","CVA（六）","CVA（七）評估-(i)","CVA（八）評估-(ii)","CVA（九）復健—手部-(i)","CVA（十）功能性走路","CVA（十一）功能性走路ii","CVA（十二）輔助用品",[3404,3405,3406,3407,3408,3409,3410,3411,3412],"平衡與前庭失調（一）","Balance（二）前庭覺-(i)","Balance（三）","Balance（四）評估","Balance（五）復健","Balance（六）功能恢復","Balance（七）前庭障礙","Balance（八）檢查","Balance（九）干預",[3414,3415,3416,3417,3418,3419],"Network-Communication,-Chapter-1","Network-Communication,-Chapter-2","Network-Communication,-Chapter-3","Network-Communication-Chapter-4","Network-Communications,-Chapter-5","Network-Communication,-Chapter-6",[3421,3422,3423,3424,3425],"Week-1-—-Introduction-to-Computer-Systems","Computer-Systems-Architecture-Understanding-Performance","A-Top-Level-View-of-Computer-Function-and-Interconnection","The-Memory-Hierarchy-Understanding-Cache-Memory","Internal-Memory-How-Your-Computer-Remembers-Things",[3427,3428,3429],"機器學習導論","資料前處理與迴歸分析","決策樹",[3431,3432,3433,3434,3435,3436,3437,3438],"小腦（一）","小腦（二）","小腦（三）功能","小腦（四）損傷","小腦（五）各功能障礙","小腦（六）評估","小腦（七）評估(ii)","小腦（八）治療",[3440,3441],"脊髓損傷SCI（一）","SCI（二）受傷機制——創傷性（頸椎）","series","r3Uot7P0d_6NPQIxzyjciP2kW_OcCWsb6zMlWEgWDgQ",[3445,3464,3484,3503,3520,3537,3552,3569,3587,3609],{"id":3446,"title":3447,"avatar":3448,"banner":3320,"bio":3449,"body":3450,"description":44,"extension":3319,"meta":3454,"name":3447,"navigation":3322,"path":3455,"seo":3456,"sitemap":3457,"social":3458,"stem":3462,"__hash__":3463},"authors\u002Fauthors\u002Fautomata.md","Automata","\u002Fimages\u002Fuploads\u002Fnier-automata-2b.jpg","一隻吐司天喵，漂浮在銀河星辰中",{"type":8,"value":3451,"toc":3452},[],{"title":44,"searchDepth":88,"depth":88,"links":3453},[],{},"\u002Fauthors\u002Fautomata",{"description":44},{"loc":3455},{"website":3459,"twitter":3460,"github":3461},"https:\u002F\u002Freurl.cc\u002FWOeM29","https:\u002F\u002Freurl.cc\u002FLnvLEy","https:\u002F\u002Fgithub.com\u002FAutomata-0","authors\u002Fautomata","IkVbO2zA7revgYq624iVWpSZQUyMmWa82tw_EbWXViE",{"id":3465,"title":3466,"avatar":3467,"banner":3468,"bio":3469,"body":3470,"description":44,"extension":3319,"meta":3474,"name":3475,"navigation":3322,"path":3476,"seo":3477,"sitemap":3478,"social":3479,"stem":3482,"__hash__":3483},"authors\u002Fauthors\u002Fchinono.md","Chinono","\u002Fimages\u002Fuploads\u002F103467998_p0 copy.png","\u002Fimages\u002Fbackground_light.jpg","我不是女生！",{"type":8,"value":3471,"toc":3472},[],{"title":44,"searchDepth":88,"depth":88,"links":3473},[],{},"七糯糯","\u002Fauthors\u002Fchinono",{"description":44},{"loc":3476},{"github":3480,"twitter":44,"website":3481},"https:\u002F\u002Fgithub.com\u002FChinHongTan","https:\u002F\u002Fchinono.dev","authors\u002Fchinono","jj1J9mFh3InZFL6XtCzGBQ5jPip0EwBDE3mjGvnN6jE",{"id":3485,"title":3486,"avatar":3487,"banner":3488,"bio":3489,"body":3490,"description":44,"extension":3319,"meta":3494,"name":3495,"navigation":3322,"path":3496,"seo":3497,"sitemap":3498,"social":3499,"stem":3501,"__hash__":3502},"authors\u002Fauthors\u002Fhibiki12141132.md","Hibiki12141132","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F265822020?v=4","\u002Fimages\u002Fuploads\u002F1773978423557-___.jpg","享受著知識強姦大腦的過程 (內文含個人發癲 不要再意)",{"type":8,"value":3491,"toc":3492},[],{"title":44,"searchDepth":88,"depth":88,"links":3493},[],{},"HiBiKi","\u002Fauthors\u002Fhibiki12141132",{"description":44},{"loc":3496},{"github":3500,"twitter":44},"https:\u002F\u002Fgithub.com\u002FHiBiKi12141132","authors\u002Fhibiki12141132","dbRnKEcYeCH_faD8R7AUmPPcwgc26s_fR4Q_lu4qtA4",{"id":3504,"title":3505,"avatar":3506,"banner":3320,"bio":3507,"body":3508,"description":44,"extension":3319,"meta":3512,"name":3505,"navigation":3322,"path":3513,"seo":3514,"sitemap":3515,"social":3516,"stem":3518,"__hash__":3519},"authors\u002Fauthors\u002Fmahiro.md","Mahiro","https:\u002F\u002Ftruth.bahamut.com.tw\u002Fs01\u002F202601\u002F2a29b047d341f840b2ce89f7d65b2ba3.JPG","一個致力於逃離新竹的電機系小雜魚",{"type":8,"value":3509,"toc":3510},[],{"title":44,"searchDepth":88,"depth":88,"links":3511},[],{},"\u002Fauthors\u002Fmahiro",{"description":44},{"loc":3513},{"github":3517},"https:\u002F\u002Fgithub.com\u002Fwifekurumi","authors\u002Fmahiro","b435tdWu9eXUf06WroCge0I405cqA0FhLlUUhoPk14k",{"id":3521,"title":3522,"avatar":3523,"banner":3320,"bio":3524,"body":3525,"description":44,"extension":3319,"meta":3529,"name":3522,"navigation":3322,"path":3530,"seo":3531,"sitemap":3532,"social":3533,"stem":3535,"__hash__":3536},"authors\u002Fauthors\u002Fosborrrrn.md","Osborrrrn","\u002Fimages\u002Fuploads\u002Frectangle_large_type_2_c516437ed713e5de1f7d2dca8a20cd81.jpg","別人笑我太瘋癲，我笑他人看不穿。\n不見五陵豪傑墓，無花無酒鋤就田",{"type":8,"value":3526,"toc":3527},[],{"title":44,"searchDepth":88,"depth":88,"links":3528},[],{},"\u002Fauthors\u002Fosborrrrn",{"description":44},{"loc":3530},{"github":3534},"https:\u002F\u002Fgithub.com\u002FOsborrrrn","authors\u002Fosborrrrn","w6VWZKPUwvXn5i7MKXOpU2Jeqr3BrdTKVCeDOF2jZlU",{"id":3538,"title":3539,"avatar":3320,"banner":3320,"bio":3540,"body":3541,"description":44,"extension":3319,"meta":3545,"name":3539,"navigation":3322,"path":3546,"seo":3547,"sitemap":3548,"social":3549,"stem":3550,"__hash__":3551},"authors\u002Fauthors\u002F法法.md","法法","123",{"type":8,"value":3542,"toc":3543},[],{"title":44,"searchDepth":88,"depth":88,"links":3544},[],{},"\u002Fauthors\u002F法法",{"description":44},{"loc":3546},{"github":44},"authors\u002F法法","o5pdVuPCfTmhkDCpvgy4YmAP0CGdvFluPvjhgvQVbsI",{"id":3553,"title":3554,"avatar":3555,"banner":3320,"bio":3556,"body":3557,"description":44,"extension":3319,"meta":3561,"name":3554,"navigation":3322,"path":3562,"seo":3563,"sitemap":3564,"social":3565,"stem":3567,"__hash__":3568},"authors\u002Fauthors\u002F灰海獅.md","灰海獅","\u002Fimages\u002Fuploads\u002Fimg_3279.jpeg","守夜人",{"type":8,"value":3558,"toc":3559},[],{"title":44,"searchDepth":88,"depth":88,"links":3560},[],{},"\u002Fauthors\u002F灰海獅",{"description":44},{"loc":3562},{"github":3566},"https:\u002F\u002Fgithub.com\u002Fyuiri333","authors\u002F灰海獅","iZoSIFbQdS-6v3LiK1txgxnIMKy-d2CyZXQk9CMua_s",{"id":3570,"title":3571,"avatar":3572,"banner":3573,"bio":3574,"body":3575,"description":44,"extension":3319,"meta":3579,"name":3571,"navigation":3322,"path":3580,"seo":3581,"sitemap":3582,"social":3583,"stem":3585,"__hash__":3586},"authors\u002Fauthors\u002F花夜.md","花夜","\u002Fimages\u002Fuploads\u002F1772719470518-791_20260218161129.png","\u002Fimages\u002Fuploads\u002Fimg_2446.png","無論你身在何處，我都會在這裡等你",{"type":8,"value":3576,"toc":3577},[],{"title":44,"searchDepth":88,"depth":88,"links":3578},[],{},"\u002Fauthors\u002F花夜",{"description":44},{"loc":3580},{"github":3584,"twitter":44},"https:\u002F\u002Fgithub.com\u002Fflowernight0709","authors\u002F花夜","a7jeQiF_JkawgYIR-aYSGceJdDP6Z-OWydsICvgSIzs",{"id":3588,"title":3589,"avatar":3590,"banner":3591,"bio":3592,"body":3593,"description":3597,"extension":3319,"meta":3600,"name":3589,"navigation":3322,"path":3601,"seo":3602,"sitemap":3603,"social":3604,"stem":3607,"__hash__":3608},"authors\u002Fauthors\u002F輝月.md","輝月","\u002Fimages\u002Fuploads\u002Ffb_img_1771085634823.jpg","\u002Fimages\u002Fuploads\u002Fimg_1751.jpg","天下布魔好好玩",{"type":8,"value":3594,"toc":3598},[3595],[21,3596,3597],{},"準大學生，目前正在製作TFR模組",{"title":44,"searchDepth":88,"depth":88,"links":3599},[],{},"\u002Fauthors\u002F輝月",{"description":3597},{"loc":3601},{"twitter":3605,"github":3606},"https:\u002F\u002Fx.com\u002Fhuiyue945","https:\u002F\u002Fgithub.com\u002Fhuiyueyea","authors\u002F輝月","koUocBihphDy3453-nAcolM7JJYwI7UMBpVkf1JQrMQ",{"id":3610,"title":3611,"avatar":3612,"banner":3320,"bio":3613,"body":3614,"description":3618,"extension":3319,"meta":3631,"name":3611,"navigation":3322,"path":3632,"seo":3633,"sitemap":3634,"social":3635,"stem":3637,"__hash__":3638},"authors\u002Fauthors\u002F阿西狄亞.md","阿西狄亞","\u002Fimages\u002Fuploads\u002Fimg_20251215_121849_589.jpg","君は実に馬鹿だな",{"type":8,"value":3615,"toc":3629},[3616,3619],[21,3617,3618],{},"我是阿西狄亞，阿西狄亞的阿，阿西狄亞的西，阿西狄亞的狄，阿西狄亞的亞，你可以叫我阿西。",[21,3620,3621,3624,3625,3628],{},[24,3622,3623],{},"我說的所有事情都抱有極度主觀的看法以及意見","，如果你有其他想法，",[24,3626,3627],{},"你是對的","。",{"title":44,"searchDepth":88,"depth":88,"links":3630},[],{},"\u002Fauthors\u002F阿西狄亞",{"description":3618},{"loc":3632},{"github":3636},"https:\u002F\u002Fgithub.com\u002FAcedia0130","authors\u002F阿西狄亞","q5ECEDl8-0Y33tPck0lYZnzPjFdJkrOnBN7HkAO3pls",[],[3641,3650,3659,3668,3677,3686,3695,3704,3713,3724],{"id":3446,"title":3447,"avatar":3448,"banner":3320,"bio":3449,"body":3642,"description":44,"extension":3319,"meta":3646,"name":3447,"navigation":3322,"path":3455,"seo":3647,"sitemap":3648,"social":3649,"stem":3462,"__hash__":3463},{"type":8,"value":3643,"toc":3644},[],{"title":44,"searchDepth":88,"depth":88,"links":3645},[],{},{"description":44},{"loc":3455},{"website":3459,"twitter":3460,"github":3461},{"id":3465,"title":3466,"avatar":3467,"banner":3468,"bio":3469,"body":3651,"description":44,"extension":3319,"meta":3655,"name":3475,"navigation":3322,"path":3476,"seo":3656,"sitemap":3657,"social":3658,"stem":3482,"__hash__":3483},{"type":8,"value":3652,"toc":3653},[],{"title":44,"searchDepth":88,"depth":88,"links":3654},[],{},{"description":44},{"loc":3476},{"github":3480,"twitter":44,"website":3481},{"id":3485,"title":3486,"avatar":3487,"banner":3488,"bio":3489,"body":3660,"description":44,"extension":3319,"meta":3664,"name":3495,"navigation":3322,"path":3496,"seo":3665,"sitemap":3666,"social":3667,"stem":3501,"__hash__":3502},{"type":8,"value":3661,"toc":3662},[],{"title":44,"searchDepth":88,"depth":88,"links":3663},[],{},{"description":44},{"loc":3496},{"github":3500,"twitter":44},{"id":3504,"title":3505,"avatar":3506,"banner":3320,"bio":3507,"body":3669,"description":44,"extension":3319,"meta":3673,"name":3505,"navigation":3322,"path":3513,"seo":3674,"sitemap":3675,"social":3676,"stem":3518,"__hash__":3519},{"type":8,"value":3670,"toc":3671},[],{"title":44,"searchDepth":88,"depth":88,"links":3672},[],{},{"description":44},{"loc":3513},{"github":3517},{"id":3521,"title":3522,"avatar":3523,"banner":3320,"bio":3524,"body":3678,"description":44,"extension":3319,"meta":3682,"name":3522,"navigation":3322,"path":3530,"seo":3683,"sitemap":3684,"social":3685,"stem":3535,"__hash__":3536},{"type":8,"value":3679,"toc":3680},[],{"title":44,"searchDepth":88,"depth":88,"links":3681},[],{},{"description":44},{"loc":3530},{"github":3534},{"id":3538,"title":3539,"avatar":3320,"banner":3320,"bio":3540,"body":3687,"description":44,"extension":3319,"meta":3691,"name":3539,"navigation":3322,"path":3546,"seo":3692,"sitemap":3693,"social":3694,"stem":3550,"__hash__":3551},{"type":8,"value":3688,"toc":3689},[],{"title":44,"searchDepth":88,"depth":88,"links":3690},[],{},{"description":44},{"loc":3546},{"github":44},{"id":3553,"title":3554,"avatar":3555,"banner":3320,"bio":3556,"body":3696,"description":44,"extension":3319,"meta":3700,"name":3554,"navigation":3322,"path":3562,"seo":3701,"sitemap":3702,"social":3703,"stem":3567,"__hash__":3568},{"type":8,"value":3697,"toc":3698},[],{"title":44,"searchDepth":88,"depth":88,"links":3699},[],{},{"description":44},{"loc":3562},{"github":3566},{"id":3570,"title":3571,"avatar":3572,"banner":3573,"bio":3574,"body":3705,"description":44,"extension":3319,"meta":3709,"name":3571,"navigation":3322,"path":3580,"seo":3710,"sitemap":3711,"social":3712,"stem":3585,"__hash__":3586},{"type":8,"value":3706,"toc":3707},[],{"title":44,"searchDepth":88,"depth":88,"links":3708},[],{},{"description":44},{"loc":3580},{"github":3584,"twitter":44},{"id":3588,"title":3589,"avatar":3590,"banner":3591,"bio":3592,"body":3714,"description":3597,"extension":3319,"meta":3720,"name":3589,"navigation":3322,"path":3601,"seo":3721,"sitemap":3722,"social":3723,"stem":3607,"__hash__":3608},{"type":8,"value":3715,"toc":3718},[3716],[21,3717,3597],{},{"title":44,"searchDepth":88,"depth":88,"links":3719},[],{},{"description":3597},{"loc":3601},{"twitter":3605,"github":3606},{"id":3610,"title":3611,"avatar":3612,"banner":3320,"bio":3613,"body":3725,"description":3618,"extension":3319,"meta":3737,"name":3611,"navigation":3322,"path":3632,"seo":3738,"sitemap":3739,"social":3740,"stem":3637,"__hash__":3638},{"type":8,"value":3726,"toc":3735},[3727,3729],[21,3728,3618],{},[21,3730,3731,3624,3733,3628],{},[24,3732,3623],{},[24,3734,3627],{},{"title":44,"searchDepth":88,"depth":88,"links":3736},[],{},{"description":3618},{"loc":3632},{"github":3636},1778585291695]