亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

為什么Java類型參數沒有下限?

為什么Java類型參數沒有下限?

飲歌長嘯 2019-11-18 10:10:19
我認為您不能將Java泛型類型參數綁定到下限(即使用super關鍵字)。我正在閱讀Angelika Langer泛型常見問題解答對此主題的看法。他們說,這基本上可以歸結為無用的下限(“沒有任何意義”)。我不相信。我可以想象它們的用途是幫助您更靈活地調用產生類型化結果的庫方法的調用者。想象一下一個方法,該方法創建了用戶指定大小的數組列表,并用空字符串填充了該列表。一個簡單的聲明是public static ArrayList<String> createArrayListFullOfEmptyStrings(int i);但這對您的客戶沒有必要的限制。他們為什么不能像這樣調用您的方法://should compileList<Object> l1 = createArrayListFullOfEmptyStrings(5); List<CharSequence> l2 = createArrayListFullOfEmptyStrings(5);List<String> l3 = createArrayListFullOfEmptyStrings(5);//shouldn't compileList<Integer> l4 = createArrayListFullOfEmptyStrings(5);在這一點上,我很想嘗試以下定義:public static <T super String> List<T> createArrayListFullOfEmptyStrings(int size) {  List<T> list = new ArrayList<T>(size);  for(int i = 0; i < size; i++) {     list.add("");  }  return list;}但是它不會編譯;super在這種情況下,關鍵字是非法的。我上面的例子是不好的例子嗎(忽略我在下面說的話)?為什么下限在這里沒有用?并且,如果有用的話,Java不允許使用的真正原因是什么?聚苯乙烯我知道更好的組織可能是這樣的:public static void populateListWithEmptyStrings(List<? super String> list, int size);List<CharSequence> list = new ArrayList<CharSequence>();populateListWithEmptyStrings(list, 5);我們是否可以出于這個問題的目的假裝由于一項要求而需要在一個方法調用中同時執行這兩種操作?編輯@Tom G(合理地)詢問a相List<CharSequence>對于a有什么好處List<String>。首先,沒有人說返回的列表是不可變的,所以這是一個優點:List<CharSequence> l2 = createArrayListFullOfEmptyStrings(5);l2.add(new StringBuilder("foo").append("bar"));
查看完整描述

3 回答

?
白衣非少年

TA貢獻1155條經驗 獲得超0個贊

基本上,它不夠有用。


我認為您的示例指出了下限的唯一優勢,即FAQ所稱的功能Restricted Instantiation:


底線是:“超級” 綁定將為您提供的所有限制是,只有Number的超類型可以用作類型實參。....


但是,正如其他帖子所指出的那樣,即使此功能的實用性也可能受到限制。


由于多態性和專業化的性質,如FAQ(訪問非靜態成員和清除類型)所述,上限比下限有用得多。我懷疑下限引入的復雜性不值得其有限的價值。


OP:我想補充一點,我想您確實表明它很有用,只是不夠用。提出毫無疑問的殺手級用例,我將支持JSR。:-)


查看完整回答
反對 回復 2019-11-18
?
守著一只汪

TA貢獻1872條經驗 獲得超4個贊

規范確實談到了類型參數的下限,例如


4.10.2


類型變量是其下限的直接超類型。


5.1.10


一個新鮮的類型變量...其下界


看起來,如果類型變量是通配符捕獲的合成變量,則它只有一個(非空)下限。如果語言允許所有類型參數的下限怎么辦?可能不會引起很多麻煩,并且僅是為了使泛型更簡單而已被排除在外(好吧……)。更新:據說對下界類型參數的理論研究尚未徹底進行。


更新:一篇聲稱下限的論文是可以的:Daniel Smith撰寫的“ Java類型推理被打破:我們可以解決它”


RETRACT:以下參數是錯誤的。OP的示例是合法的。


您的特定示例不是很令人信服。首先,它不是類型安全的。返回的列表確實是List<String>,將其視為另一種類型是不安全的。假設您的代碼可以編譯:


    List<CharSequence> l2 = createArrayListFullOfEmptyStrings(5);

然后我們可以向其添加非字符串,這是錯誤的


    CharSequence chars = new StringBuilder();

    l2.add(chars); 

好吧List<String>不是,但有點像CharSequence的列表。使用通配符可以解決您的需求:


public static  List<String> createArrayListFullOfEmptyStrings(int size)  


// a list of some specific subtype of CharSequence 

List<? extends CharSequence> l2 = createArrayListFullOfEmptyStrings(5);


// legal. can retrieve elements as CharSequence

CharSequence chars = l2.get(0);


// illegal, won't compile. cannot insert elements as CharSequence

l2.add(new StringBuilder());


查看完整回答
反對 回復 2019-11-18
?
繁花如伊

TA貢獻2012條經驗 獲得超12個贊

這不僅僅是一個答案,這是另一個(可能是殺手??)用例。我有一個ModelDecorator助手。我希望它具有以下公共API


class ModelDecorator<T>{

    public static <T> ModelDecorator<T> create(Class<T> clazz);

    public <SUPER> T from(SUPER fromInstance);

}

因此,給定的類A,B擴展了A,則可以這樣使用它:


A a = new A();

B b = ModelDecorator.create(B.class).from(a);

但是我想對T和SUPER進行限制,所以我確保只能使用API實例化子句。目前,我可以執行以下操作:


C c = new C();

B b = ModelDecorator.create(B.class).from(c);

其中B不從C繼承。


顯然,如果可以的話:


    public <SUPER super T> T from(SUPER fromInstance);

那會解決我的問題。


查看完整回答
反對 回復 2019-11-18
  • 3 回答
  • 0 關注
  • 471 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號