网站设计与制作的过程,珠海网站建设 旭洁科技,女孩更严重的新冠异常,广州市网站建设制作设计平台方法参数泛型最近#xff0c;有关Java泛型的一个非常有趣的问题发布到Stack Overflow和reddit上。 请考虑以下方法#xff1a; X extends CharSequence X getCharSequence() {return (X) hello;
}尽管这种不安全的转换看起来有些古怪#xff0c;并且您… 方法参数泛型 最近有关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 ListT emptyList() { ... }
} 此方法没有参数但返回通用ListT 。 无论T的具体推论如何为什么都能保证正确性 由于其语义。 无论您要查找的是一个空的ListString还是一个空的ListInteger 由于是空的并且是不可变的语义尽管擦除都可以为这些T中的任何一个提供相同的实现。 另一个例外是构建器例如javax.persistence.criteria.CriteriaBuilder.Coalesce 它是通过通用的无参数方法创建的 T CoalesceT 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方法参数泛型