Re: [問題] Generic 的 cast 問題

作者: changyuheng (張昱珩)   2014-12-18 19:53:13
抱歉有點遲回,謝謝!
AbsList.newInstance("string").go();
可以讓程式動是因為 E 和 T 在 compilation time 可以被推定為 String。
但是
AbsList.newInstance("number").go();
程式執行結果應該是非預期的。
valueToAdd 恰如其名,但是我想要的參數是 typeToAdd。
在改過的 AbsList 中看起來藉由讓 generic type 由參數本身的 type 推定是合適的,
但是如果想由 typeToAdd 這個 string 來決定可以嗎?
是不是不適合這樣設計?
像是這樣 (compiling error):
import java.util.ArrayList;
import java.util.List;
public class AbsList<T> {
private List<T> mList = new ArrayList<T>();
private String mType;
public AbsList(String type) {
mType = type;
}
public static <E> AbsList<E> newInstance(String type) {
switch (type) {
case "string":
return new AbsList<String>(type);
case "number":
return new AbsList<Number>(type);
default:
return new AbsList<Object>(type);
}
}
public void go() {
switch (mType) {
case "string":
mList.add("string");
break;
case "number":
mList.add(1);
break;
}
for (T element : mList) {
System.out.println(element.getClass().getName());
System.out.println(String.valueOf(element));
}
}
public static void main(String args[]) {
AbsList.newInstance("number").go();
}
}
※ 引述《adrianshum (Alien)》之銘言:
: public class AbsList<T> {
: private List<T> mList = new ArrayList<T>();
: private T valueToAdd;
: private AbsList(T valueToAdd) {
: this.valueToAdd = valueToAdd;
: }
: // 你本身的 factory method 不合理,修改成這樣
: public static <E> AbsList<E> newInstance(E valueToAdd) {
: return new AbsList<E>(valueToAdd);
: }
: public void go() {
: this.mList.add(valueToAdd);
: for (T element : mList) {
: System.out.println(String.valueOf(element));
: }
: }
: public static void main(String args[]) {
: AbsList.newInstance("string").go();
: }
: }
: 或有點 syntax eror, 意思懂就好
: ※ 引述《changyuheng (張昱珩)》之銘言:
: : 希望下面的 mList 可以不 cast 直接使用,請問是不是做不到?
: : import java.util.LinkedList;
: : import java.util.List;
: : public class AbsList {
: : private List<?> mList;
: : private String mType;
: : public AbsList newInstance(String type) {
: : mType = type;
: : switch (type) {
: : case "String":
: : mList = new LinkedList<String>();
: : break;
: : case "Number":
: : mList = new LinkedList<Number>();
: : }
: : return this;
: : }
: : public void go() {
: : switch (mType) {
: : case "String":
: : ((List<String>) mList).add("A");
: : for (String s : (List<String>) mList)
: : System.out.println(s);
: : break;
: : case "Number":
: : ((List<Number>) mList).add(0);
: : for (Number n : (List<Number>) mList)
: : System.out.println("" + n);
: : }
: : }
: : public static void main (String[] args) {
: : new AbsList().newInstance("String").go();
: : }
: : }
作者: swpoker (swpoker)   2014-12-19 11:17:00
不太懂為什麼你要堅持用字串來判別型別,直接用型別就好
作者: ssccg (23)   2014-12-19 12:47:00
Generic是compile-time的檢查,用一個run-time的參數字串來決定就不是generic,但是你又想要compile-time不檢查型別(不用cast),Java是做不到的generic基本上還是static型別系統,你想要的要dynamic型別不是不能這樣設計,但是Java沒有dynamic型別所以就只能cast
作者: changyuheng (張昱珩)   2014-12-19 17:04:00
謝謝!

Links booklink

Contact Us: admin [ a t ] ucptt.com