泛型
泛型的来源,首先我们知道类是存在聚合的,就是这个类有其他类的对象;那么问题来了,我今天用你,明天用别人;怎么办呢?
|
|
然后泛型自然就出来;
元组类库
- 就是通过泛型聚合多个类对象;使得一个对象可以携带多个对象,而且还是可以随便更改的对象;
泛型方法
- 不靠泛型类,方法泛型就行,就像下面
- static方法如果使用泛型必须成为泛型方法,简单的讲,因为static方法和类一起加载,那时就可以直接调用static方法了,而你的tpye是啥都不知道;而构造函数虽然也是隐藏的static,但我们就是通过人家获得的tpye的,soso。。12345678910111213public class GenericMethods {public <T> void f(T x){System.out.println(x.getClass().getName());}public static void main(String [] arg){GenericMethods genericMethods = new GenericMethods();genericMethods.f("");genericMethods.f(1);genericMethods.f(new HelloA());}}
吐槽
编程思想这本书真的是,有太多和java思想无关的内容,而只是经验之谈,还有一些事设计模式,说的太杂;
泛型擦除
|
|
协变
- 子类可以赋值给父类,就称为协变;
- 数组也可以协变,但是这货会存在陷阱一样的错误1234567891011121314151617181920212223class Fruit {}class Apple extends Fruit {}class Jonathan extends Apple {}class Orange extends Fruit {}public class CovariantArrays {public static void main(String[] args) {Fruit[] fruit = new Apple[10];fruit[0] = new Apple(); // OKfruit[1] = new Jonathan(); // OK// Runtime type is Apple[], not Fruit[] or Orange[]:try {// Compiler allows you to add Fruit:fruit[0] = new Fruit(); // ArrayStoreException} catch(Exception e) { System.out.println(e); }try {// Compiler allows you to add Oranges:fruit[0] = new Orange(); // ArrayStoreException} catch(Exception e) { System.out.println(e); }}} /* Output:java.lang.ArrayStoreException: Fruitjava.lang.ArrayStoreException: Orange
然后就是泛型了,它不支持协变,父类和子类不能直接赋值;
通配符
<?>和<? extends E>的只读性
通配符<?>和<? extends E>具有只读性,即可以对其进行读取操作但是无法进行写入。
原因在于:?就是表示类型完全无知,? extends E表示是E的某个子类型,但不知道具体子类型,如果允许写入,Java就无法确保类型安全性。假设我们允许写入,如果我们传入的参数是List
超类型<? super E>
超类型通配符允许写入,例子如下:
这个很好理解,list的参数类型是String的上界,必然可以添加String类型的元素。