栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java3——泛型

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java3——泛型

一、概念

泛型实际上就是使程序员定义安全的类型,是一种参数化类型的机制。避免了Object引用进行向下转型及向上转型时,某些强制类型转换的错误不被编译器捕捉,而运行后出现异常。泛型的使用会让:编译器会自动帮我们检查,从而使得程序具有更好的安全性。泛型:增加可读性安全性! 二、类型擦除

Java 中的泛型基本上都是在编译器这个层次来实现的。在生成的 Java 字节代码中是不包含泛型中的类型信息的。

工作如下:
编译器编译源码时,先进行类型检查,后进行类型擦除;
并且在类型参数出现的地方插入强制转换的相关指令。

// 在编译期间,所有的泛型信息都会被擦除,List和List类型,
// 在编译后都会变成List类型(原始类型)
public void chachu() {
    ArrayList strings = new ArrayList<>();
    ArrayList integers = new ArrayList<>();
    System.out.println(strings.getClass() == integers.getClass()); //true
}

// ArrayList泛型信息在编译之后被擦除了,只保留了原始类型,
// 类型变量(T)被替换为Object,在运行时,我们可以行其中插入任意类型的对象。
// Java中的泛型基本上都是在编译器这个层次来实现的“伪泛型”。
public void reflectInGeneric() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
    ArrayList array=new ArrayList();
    // 这样调用add方法只能存储整形,因为泛型类型的实例为Integer
    array.add(1);
    // 通过泛型可以突破泛型类型约束
    array.getClass().getMethod("add", Object.class).invoke(array, "asd");
    for (int i=0;i 
三、泛型类型 
// java编译器是通过先检查代码中泛型的类型,然后再进行类型擦除,
// 再进行编译的,变为原始类型。
// 擦除getValue()的返回类型后将返回Object类型,编译器自动插入Integer的强制类型转换
// 编译器把这个方法调用翻译为两条字节码指令:
    // 对原始方法Pair.getValue的调用
    // 将返回的Object类型强制转换为Integer
public void run() {
    Pair pair=new Pair ();
    pair.setValue(3);
    Integer integer=pair.getValue();
    System.out.println(integer);
}
//泛型类型
class Pair {
    private T value;
    public T getValue() {
        return value;
    }
    public void setValue(T  value) {
        this.value = value;
    }
}

//原始类型 擦除类型变量,并替换为限定类型(T为无限定的类型变量,用Object替换)。
class Pair {
    private Object value;
    public Object getValue() {
        return value;
    }
    public void setValue(Object  value) {
        this.value = value;
    }
}
四、泛型方法
public class GenericMethod {
    public static  void print(List a) {
        for (E i : a) {
            System.out.println(i);
        }
    }

    public static void main(String[] args) {
        List objects = new ArrayList();
        objects.add("11");
        GenericMethod.print(objects);
    }
}
五、一些细节
    泛型类型引用传递问题
ArrayList arrayList1=new ArrayList();//编译错误
ArrayList arrayList1=new ArrayList();//编译错误
 
    泛型类型变量不能是基本数据类型
    因为当类型擦除后,ArrayList的原始类中的类型变量(T)替换为Object,但Object类型不能存储基本数据类型值。运行时类型查询
    类型擦除之后,ArrayList只剩下原始类型,泛型信息不存在了。JVM看到的都是ArrayList。泛型在静态方法和静态类中的问题
    泛型类中的静态方法和静态变量不可以使用泛型类所声明的泛型类型参数;
    对象都没有创建,不能确定这个泛型参数是何种类型。List和List 之间的区别:
    List可以接受任何继承自T的类型的List
    List可以接受任何T的父类构成的List数组不支持泛型
    public class GenericTest {
        public static void main(String[] args) {
            Animal[] cats = new Animal[5]; //这里会报错!
            Object[] animals = cats;
            animals[0] = new Animal();
            Cat cat = cats[0].get(); //假设可以泛型数组,这里获取到的就错了!
        }
    }
    
    class Animal {
        private T name;
    }
    class Cat{}
    class Dog{}
    
      Java中List和原始类型List之间的区别:
      在编译时编译器不会对原始类型进行类型安全检查,却会对带参数的类型进行检查
      可以把任何带参数的泛型类型传递给接受原始类型List的方法,
      但却不能把List传递给接受List的方法Java中List和List之间的区别是:
      List是一个未知类型的List,而List其实是任意类型的List。
      可以把List, List赋值给List,却不能把List赋值给List
      List listOfAnyType;
      List listOfObject = new ArrayList();
      List listOfString = new ArrayList();
      List listOfInteger = new ArrayList();
      
      listOfAnyType = listOfString; //legal
      listOfAnyType = listOfInteger; //legal
      listOfObjectType = (List) listOfString; //compiler error - in-convertible types
       
      
        List和原始类型List之间的区别:
        带参数类型是类型安全的,而且其类型安全是由编译器保证的,但原始类型List却不是类型安全的。
        不能把String之外的任何其它类型的Object存入String类型的List中,而可以把任何类型的对象存入原始List中。
        使用泛型的带参数类型不需要进行类型转换,但是对于原始类型,则需要进行显式的类型转换
      转载请注明:文章转载自 www.mshxw.com
      我们一直用心在做
      关于我们 文章归档 网站地图 联系我们

      版权所有 (c)2021-2022 MSHXW.COM

      ICP备案号:晋ICP备2021003244-6号