方法参数泛型_无参数泛型方法反模式
方法參數泛型
最近,有關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
方法參數泛型
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的方法参数泛型_无参数泛型方法反模式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 科乐美宣布《合金装备:大师合集 Vol.
- 下一篇: 「逐际动力」发布全新四轮足机器人W1 第