日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

无参数泛型方法反模式

發布時間:2023/12/3 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 无参数泛型方法反模式 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

最近,有關Java泛型的一個非常有趣的問題發布到Stack Overflow和reddit上。 考慮以下方法:

<X extends CharSequence> X getCharSequence() {return (X) "hello"; }

盡管不安全的轉換看起來有些古怪,并且您可能會猜這里有些問題,但是您仍然可以繼續并在Java 8中編譯以下賦值:

Integer x = getCharSequence();

這顯然是錯誤的,因為Integer是final ,因此沒有可能也可以實現CharSequence Integer子類型。 但是,Java的泛型類型系統并不關心類是否為final final,因此,在將類型轉換為Integer之前,它會推斷X的交集類型Integer & CharSequence 。 從編譯器的角度來看,一切都很好。 在運行時: ClassCastException

盡管上面的內容“顯然是可疑的”,但真正的問題出在其他地方。

(幾乎)永遠不會使方法僅在返回類型上通用

此規則有例外。 這些例外是類似的方法:

class Collections {public static <T> List<T> emptyList() { ... } }

此方法沒有參數,但是它返回通用List<T> 。 無論<T>的具體推論如何,為什么都能保證正確性? 由于其語義。 無論您要查找的是空的List<String>還是空的List<Integer> ,由于是空的(并且是不可變的!)語義,盡管擦除,都可以為這些T中的任何一個提供相同的實現。

另一個例外是構建器,例如javax.persistence.criteria.CriteriaBuilder.Coalesce< ,它是通過通用的無參數方法創建的:

<T> Coalesce<T> coalesce();

生成器方法是最初構造空對象的方法。 空虛是關鍵。

但是,對于大多數其他方法,這是不正確的,包括上述的getCharSequence()方法。 此方法唯一保證的正確返回值是null 。

<X extends CharSequence> X getCharSequence() {return null; }

…因為在Java中, null是可以分配(和強制轉換)給任何引用類型的值。 但這不是該方法作者的意圖。

以函數式編程的方式思考

方法是函數(大部分是函數),因此,預期不會有任何副作用。 無參數函數應始終返回完全相同的返回值。 就像emptyList()一樣。

但實際上,這些方法并非沒有參數。 它們確實具有類型參數<T>或<X extendds CharSequence> 。 同樣,由于泛型類型擦除,此參數在Java中“并未真正計數”,因為缺乏規范化,因此無法從方法/函數內部進行自省。

因此,請記住以下幾點:

(幾乎)永遠不會使方法僅在返回類型上通用

最重要的是,如果您的用例只是為了避免Java 5之前的版本轉換,例如:

Integer integer = (Integer) getCharSequence();

是否想在您的代碼中找到令人討厭的方法?

我正在使用番石榴來掃描類路徑,您可能還會使用其他東西。 此代碼段將在類路徑上生成所有通用的無參數方法:

import java.lang.reflect.Method; import java.util.Comparator; import java.util.stream.Stream;import com.google.common.reflect.ClassPath;public class Scanner {public static void main(String[] args) throws Exception {ClassPath.from(Thread.currentThread().getContextClassLoader()).getTopLevelClasses().stream().filter(info -> !info.getPackageName().startsWith("slick")&& !info.getPackageName().startsWith("scala")).flatMap(info -> {try {return Stream.of(info.load());}catch (Throwable ignore) {return Stream.empty();}}).flatMap(c -> {try {return Stream.of(c.getMethods());}catch (Throwable ignore) {return Stream.<Method> of();}}).filter(m -> m.getTypeParameters().length > 0 && m.getParameterCount() == 0).sorted(Comparator.comparing(Method::toString)).map(Method::toGenericString).forEach(System.out::println);} }

翻譯自: https://www.javacodegeeks.com/2016/04/parameterless-generic-method-antipattern.html

總結

以上是生活随笔為你收集整理的无参数泛型方法反模式的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。