让你滚滚一直的Java的泛型常识点梳理
副问题[/!--empirenews.page--]
最近技能交换群里,有伴侣问:Object和泛型T有啥区别。答复完题目,不禁在想,口试在即,尚有那么多伴侣不了泛型?是时辰给各人清算一篇泛型相干的文章了,一篇文章全面搞定泛型,让各人再也不愁口试或实践中泛型相干的题目了。 什么是泛型 泛型是在JDK 5时就引入的新特征,也就是“参数化范例”,普通来讲就是将原本的详细范例通过参数化来界说,行使或挪用时再传入详细的范例(范例实参)。 泛型的本质是为了参数化范例(在不建设新范例的条件下,通过泛型指定的差异范例来节制形参详细的范例)。在泛型行使进程中,操纵的数据范例被指定为一个参数,这种参数范例可以用在类、接口和要领中,别离被称为泛型类、泛型接口、泛型要领。 为什么行使泛型 未行使泛型时,可以通过Object来实现参数的“恣意化”,但这样做的弱点就是必要显式的逼迫范例转换,这就必要开拓者知道现实的范例。 而逼迫范例转换是会呈现错误的,好比Object将现实范例为String,强转成Integer。编译期是不会提醒错误的,而在运行时就会抛出非常,很明明的安详隐患。 Java通过引入泛型机制,将上述的隐患提前到编译期举办搜查,开拓职员既可明晰的知道现实范例,又可以通过编译期的搜查提醒错误,从而晋升代码的安详性和结实性。 行使泛型前后的比拟 拿一个经典的例子来演示一下未行使泛型会呈现的题目。 List list = new ArrayList(); list.add(1); list.add("zhuan2quan"); list.add("措施新视界");
for (int i = 0; i < list.size(); i++) { String value = (String) list.get(i); System.out.println("value=" + value); } 上述代码在编译器并不会报任何错误,但当执行时会抛出如下非常: java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String 那么,是否可以在编译器就办理这个题目,而不是在运行期抛出非常呢?泛型应运而生。上述代码通过泛型来写之后,酿成如下情势: List<String> list = new ArrayList<>(); list.add(1); list.add("zhuan2quan"); list.add("措施新视界");
for (String value : list) { System.out.println("value=" + value); } 可以看出,代码变得越发清新简朴,并且list.add(1)这行代码在IDE中直接会提醒错误信息: Required type: String Provided: int 提醒错误信息即是泛型对向List中添加的数据发生了束缚,只能是String范例。 泛型中通配符 在行使泛型时常常会看到T、E、K、V这些通配符,它们代表着什么寄义呢? 本质上它们都是通配符,并没有什么区别,换成A-Z之间的任何字母都可以。不外在开拓者之间倒是有些不成文的约定: T (type) 暗示详细的一个java范例; K V (key value) 别离代表java键值中的Key Value; E (element) 代表Element; 为什么Java的泛型是假泛型 为了做到向下兼容,Java中的泛型仅仅是一个语法糖,并不是C++那样的真泛型。 照旧上面的例子,在直接向泛型为String的List中添加int范例会提醒错误: List<String> list = new ArrayList<>(); list.add(1); 针对上述代码,我们回收反射间接地挪用add要领: @Test public void test3() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { List<Integer> list = new ArrayList<>(); list.add(1); Method add = list.getClass().getMethod("add", Object.class); add.invoke(list,"措施新视界"); System.out.println(list); System.out.println(list.get(1)); } 执行上述代码,我们发明措施并没有抛出非常,正常打印进出: [1, 措施新视界] 措施新视界 本来只能装入Integer的List,乐成装入了一个String范例的值。由此可见,所谓的泛型确实是假泛型。 同时,我们还可以通过字节码来证明。拿上面行使了泛型的实例代码,通过javap -c呼吁来看看字节码: Code: (编辑:湖南网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |