Java 读书笔记 15泛型

    xiaoxiao2021-03-25  119

    泛型

    泛型的来源,首先我们知道类是存在聚合的,就是这个类有其他类的对象;那么问题来了,我今天用你,明天用别人;怎么办呢?

    public class Automobile { //普通模式有这么一个类 } public class Holder1 { private Automobile a; //类间聚合;但是你必须编译的时候就定义啊; public Holder1(Automobile a) //完全不能改变的时候 { this.a=a; } Automobile get() { return a; } private Object b; //定义Object可以通过向下转型的方式储存其他对象,但是自然是麻烦的; public Holder1(Object b) { this.b=b; } public void setB(Object b) { this.b = b; } public Object getB() { return b; } }

    然后泛型自然就出来;

    public class Holder2<T> { //定义一个Tpye,谁来换成谁,多好; private T a; public Holder2(T a) { this.a = a; } public T getA() { return a; } public void setA(T a) { this.a = a; } }

    元组类库

    就是通过泛型聚合多个类对象;使得一个对象可以携带多个对象,而且还是可以随便更改的对象;

    泛型方法

    不靠泛型类,方法泛型就行,就像下面static方法如果使用泛型必须成为泛型方法,简单的讲,因为static方法和类一起加载,那时就可以直接调用static方法了,而你的tpye是啥都不知道;而构造函数虽然也是隐藏的static,但我们就是通过人家获得的tpye的,soso。。 public 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思想无关的内容,而只是经验之谈,还有一些事设计模式,说的太杂;

    泛型擦除

    public class Foo<T> { T a; List<T> create (T t,int n) { List<T> result = new ArrayList<T>(); for (int i = 0;i< n ;i++) { result.add(t); } return result; } public String toString() { return a.getClass().getName(); } public static void main(String []arg) { Foo<Holder1> holder1Foo= new Foo<>(); Foo<String> foo = new Foo<>(); List<String> list= foo.create("hello",4); System.out.println(list); //虽然擦除了类型,但是编译器还是知道你存的是什么, System.out.println(holder1Foo.getClass().getName()); //简单说,编译器帮我们又转型了; System.out.println(holder1Foo.toString()); //报错,因为它根本不知道是哪个类的 } }

    协变

    子类可以赋值给父类,就称为协变;数组也可以协变,但是这货会存在陷阱一样的错误 class 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(); // OK fruit[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: Fruit java.lang.ArrayStoreException: Orange

    然后就是泛型了,它不支持协变,父类和子类不能直接赋值;

    通配符

    public static void printList(List<?> list) { for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i)); } //一下操作不可以 list.add(1); list.add("123"); }

    原因在于:?就是表示类型完全无知,? extends E表示是E的某个子类型,但不知道具体子类型,如果允许写入,Java就无法确保类型安全性。假设我们允许写入,如果我们传入的参数是List,此时进行add操作,可以添加任何类型元素,就无法保证List的类型安全了。

    超类型

    public static void printList(List<? super String> list) { for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i)); } list.add("123"); list.add("456"); }

    这个很好理解,list的参数类型是String的上界,必然可以添加String类型的元素。

    转载请注明原文地址: https://ju.6miu.com/read-15016.html

    最新回复(0)