βοΈ κ΅λΉ νμμμ νλ‘μ νΈλ₯Ό μ§νν λ Map μλ£κ΅¬μ‘°κ° λμ§λ λͺ°λλ μμ , μλ‘ λ€λ₯Έ κ°μ²΄λ₯Ό Object λ°°μ΄μ λ΄μ μ§μ νλ³νμ ν΄μ λ°μ΄ν°λ₯Ό μ‘°μνλ κΈ°μ΅μ΄ μλλ°, μ΄ λ νλ³νμ μκΎΈ μλͺ»ν΄μ λ°νμ μλ¬κ° κ³μ λ¬λ κ²½νμ΄ μκ°λ¬λ€.
κ³Όκ±°μ λ§μ£Όνλ λ¬Έμ λ€μ μκΈ°νκ³ , μ ν΄λΉ κ°λ μ΄ νμνμ§ μ΄λ² νμ΅μ ν΅ν΄ μμκ°λ μκ°μ κ°μ Έλ³΄μ.
Generic
Genericμ΄λ λ¨μ΄μ μ¬μ μ μλ―Έλ 'ν¬κ΄μ μΈ' μ΄λΌλ λ»μ΄λ€. λ¨μ΄ λ» κ·Έλλ‘ ν΄λμ€μ λ΄κΈΈ κ°μ²΄λ λ©μλ, μμ±μμ λ§€κ° λ³μμ μ’ λ₯λ₯Ό νΉμ ν΄λμ€λ₯Ό μ§μ νλ κ²μ΄ μλλΌ, ν¬κ΄μ μΈ μλ―Έμ λ¨μ΄λ₯Ό μ¬μ©ν΄ λ΄κΈΈ κ°μ²΄μ μ’ λ₯μ λν΄μ μ΄μ΄λλ€λ μλ―Έλ‘ μ¬μ©νλ€.
μ¦, Genericμ μ»΄νμΌ νμμμ ν΄λμ€μ λ΄κΈΈ κ°μ²΄μ ννμ ν΄λΉ ν΄λμ€μ λ΄κΈΈ ννμ λ§λμ§ νμΈνλ μν μ νλ€. μ΄λ κ°λ°μκ° μ§μ νλ³νμ ν΄μΌνλ μκ³ λ‘μμ λκ³ , νλ‘κ·Έλ¨ μ»΄νμΌ μμ ννλ₯Ό νμΈνκ³ λ§μ§ μμ κ²½μ° μμΈλ₯Ό λμ§κΈ° λλ¬Έμ μ΄λ₯Ό ν΄κ²°νλ κ²λ λ°νμ μ μμΈλ₯Ό λμ§λ κ²λ³΄λ€ ν¨μ¬ μμνλ€.
...
public class GenericTest {
public static void main(String[] args) {
List list = new ArrayList();
list.add(100);
list.add(200);
list.add("300");
String value1 = (String) list.get(1);
Integer value2 = (Integer) list.get(2);
System.out.println("λ¬Έμμ΄ list[1] : " + value1);
System.out.println("μ μ list[2] : " + value2);
}
}
μμ μ½λλ Genericμ΄ λ±μ₯νκΈ° μ΄μ μ μ¬μ©νλ λ°©μμ μ½λλ₯Ό κ°λ¨νκ² μμ±ν κ²μ΄λ€. List κ°μ²΄λ ArrayList ν΄λμ€λ‘ ꡬνλμμ§λ§ ν΄λΉ 리μ€νΈ λ΄λΆμ μ΄λ€ νμ
μ λ°μ΄ν°κ° λ€μ΄κ°μ§ μ μ μλ μν©μ΄κΈ° λλ¬Έμ List κ°μ²΄ λ΄μλ μλ¬΄λ° μ°Έμ‘° μλ£νμΌλ‘ μΈν
λ μ μλ€.(μΆνμ Collection.List λ΄λΆ ꡬ쑰μ λν΄ μμΈν μμ보μ.)
ByteCode
...
// access flags 0x9
public static main([Ljava/lang/String;)V
L0
LINENUMBER 9 L0
NEW java/util/ArrayList
DUP
INVOKESPECIAL java/util/ArrayList.<init> ()V
ASTORE 1
L1
LINENUMBER 10 L1
ALOAD 1
BIPUSH 100
INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer;
INVOKEINTERFACE java/util/List.add (Ljava/lang/Object;)Z (itf)
POP
...
L4
LINENUMBER 14 L4
ALOAD 1
ICONST_1
INVOKEINTERFACE java/util/List.get (I)Ljava/lang/Object; (itf)
CHECKCAST java/lang/String
ASTORE 2
...
}
ByteCodeλ₯Ό μ΄ν΄λ³΄μ. ν΄λΉ μ½λμ μλ¨μ 보면 Listμ add() λ©μλμ get() λ©μλκ° νΈμΆλ λ λ§€κ° λ³μμ μΈμλ‘ μ€μ ν 리ν°λ΄ λ°μ΄ν°κ° μ»΄νμΌλ¬μ μν΄ Objectλ‘ λ³κ²½λμ΄ λμ΄κ°λ κ²μ νμΈ ν μ μλ€. μ΄λ λͺ¨λ μ°Έμ‘° μλ£νμ μ΅μμ μ‘°μμΌλ‘ Objectλ₯Ό μμ λ°κ³ μμ΄ Listμ λ΄μ λ, λ΄κΈ°λ κ°μ²΄λ€μ΄ Objectλ‘ Listμ λ΄κΈ°λ κ²μ΄λ€.
κ°κΈ° λ€λ₯Έ μ°Έμ‘° μλ£νμ νμ μ΄ μ μΈλμ§ μμ Listμ λ΄λ κ²μ μκ°λ³΄λ€ ν° λ¬Έμ λ μλμ§λ§, ν΄λΉ Listμ λ΄κΈ΄ κ°μ κΊΌλ΄μ΄ μ¬μ©ν΄μΌ νλ κ²½μ°μλ ν° λ¬Έμ μ΄λ€.
첫 λ²μ§Έ μμ€μ½λκ° λ°λ‘ λ¬Έμ μ μμμΈλ°, μ΄μ¨λ μ§μ΄ λ£μ λ°μ΄ν°λ Objectλ‘ λμΌνκΈ° λλ¬Έμ μ»΄νμΌλ¬λ λ¬Έμ λΌκ³ νλ¨νμ§ μμ μ»΄νμΌν ν΄λμ€ νμΌμ Runtime Data Areaλ‘ λκΈΈ κ²μ΄λ€. μ΄ λ λ¬Έμ κ° λ°μνλλ° main() λ©μλ νΈμΆ μ, list λ³μμ λ°μ΄ν°λ₯Ό μ§μ λ³μλ‘ μ μΈν value1, value2μ νμ μ λ§μ§ μκ² μΊμ€ν νκΈ° λλ¬Έμ JVMμ ClassCastException μμΈλ₯Ό λ°μμν¨λ€.
μ΄λ κ² λ¨μν νλ³νμΌλ‘ μΈν΄ λ°νμ μ μμΈκ° λ°μνλ κ²μ μ ν리μΌμ΄μ μ΄μμ μμ΄ ν° λ¬Έμ μ΄λ€. λλ¬Έμ Genericμ μ΄λ¬ν λ¬Έμ λ₯Ό ν΄κ²°νκ³ , μ³μ§ μμ νμ μ λμ νμ λ μ»΄νμΌ μλ¬λ₯Ό λ°μμμΌ μ ν리μΌμ΄μ μ΄μ μ΄μ μ κ°λ°μκ° λ¬Έμ μ μμμ μ¬μ μ μμ ν μ μλ€.
Java 5 μ΄νμ λ±μ₯ν Genericμ λ€μν ν΄λμ€μ μ μλμ΄ μλλ° λνμ μΈ μκ° μμ£Ό μ¬μ©νλ ArrayList<E> ν΄λμ€μ΄λ€. κ·Έλ λ€λ©΄ <> μμ λ€μ΄μλ κ°κΈ° λ€λ₯Έ μΊλ¦ν°λ 무μμ μλ―Έν κΉ?
Generic Type
μ¬μ€ Genericμ <> μμλ μ΄λ€ λ¬Έμλ₯Ό λ£μ΄λ μκ΄μμ΄ μ¬μ© κ°λ₯νλ€.
public class Generic<Type> {
public Type type;
public Generic(Type type) {
this.type = type;
}
}
νμ§λ§ μ΄λ κ² ν΅μΌμ± μλ λ¬Έμλ‘ Generic νμ μ λͺ μΈνλ©΄ μλ―Έκ° μ곑λκ±°λ μλμλ λ€λ₯΄κ² ν΄λΉ ν΄λμ€κ° μ¬μ©λ μ μλ€. μ΄λ¬ν λΆλΆμμ λ°μνλ λ¬Έμ λ₯Ό μ¬μ μ μλ°©νκΈ° μν΄ λͺ κ°μ§ κ·μΉμ΄ μ‘΄μ¬νλ€.
βοΈ E : Elementμ μ½μ. μμμ μλ―Έλ₯Ό κ°μ§λ©° μ£Όλ‘ Java Collectionμμ μ£Όλ‘ μ¬μ©λλ€.
βοΈ T : Type
βοΈ N : Number
βοΈ V : Value
βοΈ K : Key
βοΈ S, U, V : λ λ²μ§Έ, μΈ λ²μ§Έλ‘ μ μνλ Generic
ν΄λΉ κ·μΉμ κΌ μ§μΌμΌ ν μ무λ μμ§λ§ λꡬλ μ΄ν΄νκΈ° μ¬μ°λ €λ©΄ λ°λ₯΄λ κ²μ΄ μ’κ² λ€. κ·Έλ°λ° μ’ μ’ Genericμ ? λ‘ μ€μ λμ΄ μλ κ²μ λ³Ό μ μλλ° ? κ° μλ―Ένλ κ²μ 무μμ΄κ³ μ΄λ€ μ©λλ‘ μ¬μ©λ κΉ?
Wild Card '?'
public class WildCardTest {
public static void main(String[] args) {
WildCardTest test = new WildCardTest();
ArrayList<Integer> arr = new ArrayList<Integer>();
arr.add(1);
arr.add(2);
arr.add(3);
test.wildCardTest(arr);
List<String> linked = new LinkedList<String>();
linked.add("a");
linked.add("b");
linked.add("c");
test.wildCardTest(linked);
}
public void wildCardTest(List<?> list) {
System.out.println("νμ¬ ν΄λμ€ : " + list.getClass());
for (Object obj : list) {
System.out.println(obj.getClass());
}
}
}
/*
νμ¬ ν΄λμ€ : class java.util.ArrayList
class java.lang.Integer
class java.lang.Integer
class java.lang.Integer
νμ¬ ν΄λμ€ : class java.util.LinkedList
class java.lang.String
class java.lang.String
class java.lang.String
*/
Genericμ λ©μλμ λ§€κ° λ³μ μΈμλ‘ λ°λ κ°μ²΄ μ€, Genericμ΄ μ μλμ΄ μλ κ°μ²΄μ νμ μλ μ μ© ν μ μλ€.
WildCardTest ν΄λμ€μ μ μλ wildCardTest λ©μλλ₯Ό νμΈν΄λ³΄μ. λ§€κ° λ³μ μΈμλ‘ λ°λ List κ°μ²΄μ νμ μ΄ ? λ‘ μ μΈλμ΄ μλλ°, ? λ Wild Cardμ μλ―Έλ‘ μ¬μ©λλ€. μ΄λ₯Ό ν΅ν΄μ κ°μ²΄κ° Genericμ΄ μ μκ° λμ΄ μλ€λ©΄ λ§€κ° λ³μμμλ Genericμ μ μ ν μ μλ€λ κ²μ μ μ μλ€.
κ·Έλμ main() λ©μλμ μ μλ ArrayListμ LinkedListμ νμ μ΄ λ€λ₯΄μ§λ§ wildCardTest() λ©μλμ λ§€κ° λ³μλ‘ λ£μ΄λ λ³λ€λ₯Έ μ»΄νμΌ μλ¬λ λ°νμ μλ¬ μμ΄ μ€νλλ€.
λ€λ§ λ§€κ° λ³μλ₯Ό ? λ‘ μ μ ν κ²½μ°, λ©μλ μ€μ½ν λ΄μμ λ§€κ° λ³μ κ°μ²΄λ Objectλ‘ μ μλκΈ°μ κ°μ²΄μ νμ μ΄ μ΄λ€ νμ μΈμ§ μκ³ μλ€λ©΄ instanceof μμ½μ΄λ₯Ό μ΄μ©ν΄ ν΄λΉ νμ μ΄ λ§λμ§ κ²μ¦μ ν νμ μ¬μ©νλ κ²μ΄ μ’λ€.
λν, ? μ λ§€κ° λ³μλΏλ§ μλλΌ μ§μ λ³μλ νλμμλ μ μΈμ κ°λ₯νλ€. νμ§λ§ ν΄λΉ μμμμ μ¬μ©ν κ²½μ° νμ μμ μ±μ΄ λ¨μ΄μ§κΈ° λλ¬Έμ μ»΄νμΌ μλ¬λ₯Ό λ°μμν€λλ°, κ·Έ μ΄μ λ κ°μ²΄μ νμ μ΄ λ¬΄μμΈμ§ μμ§ λͺ»νκΈ° λλ¬Έμ΄λ€. μ¦, ? μ μΈμλ‘ λμ΄μ¨ λ°μ΄ν°λ₯Ό μ½λ κ²μ κ°λ₯νμ§λ§ μ°λ κ²μ λΆκ°λ₯νλ€.
public class WildCardTest {
public List<?> list;
public static void main(String[] args) {
WildCardTest test = new WildCardTest();
...
test.list.add("1"); // μ»΄νμΌ μλ¬ λ°μ
}
...
}
/*
java: no suitable method found for add(int)
method java.util.Collection.add(capture#1 of ?) is not applicable
(argument mismatch; int cannot be converted to capture#1 of ?)
method java.util.List.add(capture#1 of ?) is not applicable
(argument mismatch; int cannot be converted to capture#1 of ?)
*/
Bounded Wild Card
public class BoundedWildCardTest {
public static void main(String[] args) {
List<Parent> parents = new ArrayList<>();
parents.add(new Parent(1));
parents.add(new Parent(2));
parents.add(new Child(3));
List<Child> children = new ArrayList<>();
children.add(new Child(1));
children.add(new Child(2));
children.add(new Child(3));
List<String> stringList = new ArrayList<>();
stringList.add("a");
stringList.add("b");
stringList.add("c");
BoundedWildCardTest test = new BoundedWildCardTest();
test.boundedTest(parents);
test.boundedTest(children);
test.boundedTest(stringList); // μ»΄νμΌ μλ¬ λ°μ
}
public void boundedTest(List<? extends Parent> list) {
System.out.println(list.getClass());
for (Parent obj : list) {
System.out.println(obj.toString());
}
}
}
μμμ ?(μ΄ν Wild Card)μ λν΄μ 곡λΆνλ€. Wild Cardλ μ΄λ€ νμ μ μΈμκ° μλ κ΄κ³κ° μμ΄ μ΄λ€ κ΄μ μμλ νΈν μ§ λͺ°λΌλ, λ€λ₯Έ κ΄μ μμ λ°λΌλ³Έλ€λ©΄ μ μ ν ν΅μ κ° μ΄λ€μ§μ§ μκΈ° λλ¬Έμ μμνμ§ λͺ»ν λ¬Έμ κ° λ°μν μ μλ€.
μ΄λ¬ν Wild Cardλ₯Ό μ΄λμ λ ν΅μ νκΈ° μν΄ extends λΌλ μμ½μ΄κ° μ‘΄μ¬νλλ°, μ΄λ Bounded Wild CardλΌκ³ νλ©°, ν΄λμ€ μμμ κ°λ μ²λΌ μ§μ λ ν΄λμ€λ₯Ό ν¬ν¨νμ¬ νμ ν΄λμ€λ§ νμ© ν μ μλλ‘ νλ€.
μ μ½λλ₯Ό νμΈν΄λ³΄λ©΄, boundedTest() λ©μλμ λ§€κ° λ³μλ‘ List κ°μ²΄λ₯Ό λ°λλ°, μ΄ λ <? extends Parent>λ‘ νμ μ μ νμ΄ μ μλμ΄ μλ€. μ΄λ List κ°μ²΄μ νμ μ΄ Parent κ°μ²΄λ₯Ό ν¬ν¨ν νμ μμ κ°μ²΄λ€λ§ λ§€κ° λ³μλ‘ νμ©νκ² λ€λ μλ―Έμ΄κΈ° λλ¬Έμ, String νμ μ List κ°μ²΄λ boundedTest() λ©μλμ λ§€κ° λ³μ μΈμλ‘ μ€μ ν μ μλ€.
λν Bounded Wild Cardμλ extends μ λ°λλλ super μμ½μ΄κ° μ‘΄μ¬νλ€. ν΄λΉ Bounded Wild Cardλ Lower Bounded Card, extendsμ κ²½μ°λ Higher Wild CardλΌκ³ μΉνλ€.
π Higher Bounded Card : νμ μ λμμ΄ λ κ°μ²΄μ μμ κ°μ²΄λ€κΉμ§ νμ μΌλ‘ νμ© ν μ μλ€.
π Lower Bounded Card : νμ μ λμμ΄ λ κ°μ²΄μ λΆλͺ¨ κ°μ²΄λ€κΉμ§ νμ μΌλ‘ νμ© ν μ μλ€.
Generic Method
public class BoundedWildCardTest {
public static void main(String[] args) {
List<Parent> parents = new ArrayList<>();
...
List<Child> children = new ArrayList<>();
...
List<String> stringList = new ArrayList<>();
...
BoundedWildCardTest test = new BoundedWildCardTest();
test.genericMethod(parents, new Parent(4));
test.genericMethod(children, new Child(4));
test.genericMethod(stringList, "abc");
}
public <T> void genericMethod(List<T> list, T type) {
System.out.println("리μ€νΈ νμ
: " + list.getClass());
System.out.println("T : " + type.getClass());
list.add(type);
for (Object obj : list) {
System.out.println(obj.toString());
}
}
}
Wild Card ννΈμμ Wild Cardλ μΈμλ‘ λμ΄μ¨ λ°μ΄ν°λ₯Ό μ½λ κ²μ κ°λ₯νμ§λ§ μ°λ κ²μ λΆκ°λ₯νλ€κ³ νλ€. νμ§λ§ μμ ν λΆκ°λ₯ν κ²μ μλλ€. λ©μλμ Generic Typeμ μ§μ νλ€λ©΄ λ§€κ° λ³μ μΈμλ‘ μ λ¬λ κ°μ²΄μ μ°κΈ°κ° κ°λ₯νλ€.
Generic Type Erasure
μμ 곡λΆν λ΄μ©μ λ€μ λμ§μ΄λ³΄μ. Genericμ΄ λ±μ₯νκΈ° μ μλ νλ³νμ λν νμ 체ν¬κ° λ°νμμμ μΌμ΄λκΈ° λλ¬Έμ λ§μ λ¬Έμ μ μ λ°μμμΌ μ΄λ₯Ό ν΄κ²°νκΈ° μν΄μ Genericμ κ°λ μ΄ λμ λμκ³ , λ±μ₯ μ΄νλΆν°λ μ»΄νμΌ νμμμ κ°ν νμ 체ν¬κ° μΌμ΄λ λ°νμ μ μ λ¬Έμ λ₯Ό ν΄κ²° ν μ μκ² λμλ€.
μ΄λ»κ² Genericμ κ°ν νμ 체ν¬λ μ»΄νμΌ μμ μμ νμΈ ν μ μλ κ²μΌκΉ? Genericμ μκ±° νλ‘μΈμ€λ₯Ό μ μ©νμ¬ μλλλλ°, μ΄λ μ»΄νμΌ μμ μμ νμ 체ν¬λ₯Ό μνν ν ν΄λΉ κ°μ²΄μ νμ μ 보λ₯Ό λ°νμ μμ κΉμ§ κ°μ Έκ°μ§ μλ κ²μ μλ―Ένλ€.
μ΄λ₯Ό Type ErasureλΌκ³ λΆλ₯΄λλ°, λ°μ΄νΈ μ½λλ₯Ό νμΈν΄λ³΄λ©΄ νμ μ΄ μ€μ λ λͺ¨λ κ°μ²΄λ€μ νμ μ λ³΄κ° μ‘΄μ¬νμ§ μλ κ²μ νμΈ ν μ μλ€.
...
L14
LINENUMBER 26 L14
ALOAD 4
ALOAD 2
INVOKEVIRTUAL generic/BoundedWildCardTest.boundedTest (Ljava/util/List;)V
L15
LINENUMBER 28 L15
ALOAD 4
ALOAD 1
NEW generic/Parent
DUP
ICONST_4
INVOKESPECIAL generic/Parent.<init> (I)V
INVOKEVIRTUAL generic/BoundedWildCardTest.genericMethod (Ljava/util/List;Ljava/lang/Object;)V
...
Type Erasureλ μλμ κ°μ λ°©μμΌλ‘ μ»΄νμΌ νμμμ νμ μ²΄ν¬ μν ν, κ°μ²΄μ νμ μ μκ±°νλ€.
π₯ μ»΄νμΌ μ, Genericμ΄ μ μ©λ κ°μ²΄μμλ ν΄λΉνλ νμ νλΌλ―Έν°(void example(T t))λ Objectλ‘ λ³κ²½ν΄μ€λ€.
π₯ λ§μ½ Generic Typeμ΄ Objectλ‘ λ³κ²½λμλ€λ©΄ νμ© κ°λ₯ν νμ μ μ νμ΄ μλ€λ μλ―Έ(unbounded)λ‘, Type Erasure κ·μΉμ λν Genericμ΄ μ μ© κ°λ₯ν λ²μλ μΌλ°μ μΈ ν΄λμ€λ λ©μλ νΉμ μΈν°νμ΄μ€λ§ ν΄λΉλλ€.
π₯ Genericμ ν¬μ©μ±μ λκΈ° λλ¬Έμ, λ€νμ±μ΄ κΉ¨μ§ μ μλ€. λλ¬Έμ μμ λ°°μ΄ Generic Methodλ₯Ό νμ©νμ¬ Bridge Methodλ₯Ό μμ±ν΄ νμ μ§μ μ λ체νλ€.
π₯λ§μ½ Genericμ΄ Bounded νκ² μ€μ λ κ²½μ°, μ»΄νμΌλ¬λ ν΄λΉ κ°μ²΄μ νμ μ Objectκ° μλ Comparble<E>λ‘ λ³κ²½νλ€.
βοΈ μ λ€λ¦μ μ¬μ©νλ κ°μ²΄λ λλΆλΆ μ€μ²΄ν λΆκ° νμ , Object[] κ°μ κ°μ²΄λ μ€μ²΄ν νμ μ΄λΌκ³ νλλ°, μ€μ²΄ν νμ μ κ²½μ° λ°νμ μ€ μ¬λ°λ₯΄μ§ μμ νμ μΌλ‘ μΊμ€ν λ κ²½μ° λ°νμ μλ¬κ° λ°μ ν μ μκΈ° λλ¬Έμ μ»΄νμΌ νμμμ μ€μ²΄ννμ§ λͺ»νκ² νμ μ μκ±°νλ 리μ€νΈκ°μ μ€μ²΄ν λΆκ° νμ μ μ¬μ©νλ κ²μ΄ μ’λ€.
π₯ μ£Όλ§μ μ§ννλ € νλ λ΄μ©μΈλ°, μ£Όλ§μλ νμ¬μΌμ νλλΌκ³ μ§κΈκΉμ§ λΆμ‘κ³ μκ² λμλ€.
νμ§λ§ κ·Έλ§νΌ 곡λΆν λ΄μ©λ€μ λ¨Έλ¦ΏμμΌλ‘ μ 리ν μκ°μ΄ λ§μλλ°, λλΆμ μ΅λν λ΄κ° μ΄ν΄ν λ΄μ©λ§μΌλ‘ μμ±νλ €κ³ λ Έλ ₯ ν μ μμλ€. μμ§ Genericμ λν΄μ μ λΆ μλ κ²μ μλμ§λ§ μ΄λμ λ λ¨Έλ¦Ώμμ ꡬ체νλ κ² κ°μ κΈ°μλ€!
λ€μμ μκ° μ¬μ κ° μκΈ΄λ€λ©΄, Compable<E> μ λν΄μλ 곡λΆλ₯Ό ν΄λ΄μΌκ² λ€.
μ°Έκ³ λ¬Έμ
'Programming > Java' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
F015 - Set (μμ± μ€) (0) | 2021.05.31 |
---|---|
F014 - List (ArrayList, LinkedList, Vector, Stack) (0) | 2021.05.30 |
F012 - Annotation (0) | 2021.05.24 |
F011 - java.lang.ref (0) | 2021.05.19 |
F010 - System.out.println(), Logger (0) | 2021.05.19 |