Java 泛型的作用及其基本概念

一、泛型的基本概念

java与c#一样,都存在泛型的概念,及类型的参数化。java中的泛型是在jdk5.0后出现的,但是java中的泛型与C#中的泛型是有本质区别的,首先从集合类型上来说,java 中的ArrayList<Integer>和ArrayList<String>是同一个类型,在编译时会执行类型擦除,及java中的类型是伪泛型,伪泛型将会在后面介绍,其次,对于像集合中添加基本类型的数据时,例如int,会首先将int转化成Integer对象,即我们通常所说的装箱操作,在取出元素的时候需要将Interger对象转换成int值类型,即拆箱操作。而在c#中,List<int>和List<string>是不同的类型,泛型参数在编译后会是一个占位符,并没有被擦除,在运行时被赋予正真的类型,它们在系统运行期生成,有自己的虚方法表和类型数据,这种实现称为类型膨胀(针对类型膨胀,即时编译器已经做了很多的优化工作来解决这一问题),这就是所谓的真泛型。与此同时,在对集合中添加基本元素如int时,不需要装箱操作,取出元素时不需要拆箱操作,因此,性能上较java的集合泛型要好。

java中泛型的引入主要是为了解决两个方面的问题:1.集合类型元素在运行期出现类型装换异常,增加编译时类型的检查,2. 解决的时重复代码的编写,能够复用算法。下面通过例子来说明编译器的类型检查。

首先我们看一个没有使用泛型的例子:

ArrayList al = new ArrayList();
 al.add("abc");
al.add("124");
al.add("32L");

我们可以向al集合中添加任何类型的数据。当我们在取出数据的时候需要时候类型转换,如:

String s = (String)al.get(0);
String s1 = (String)al.get(1); //在运行期,会报错,类型转换错误
Long l = (Long)al.get(2);

由此可以看到,没有泛型的时候,减少了编译时的类型检查,在取出元素时需要程序员对每个元素的类型都了解,否则很可能在运行时出现类型转换的异常。

那么下面我们通过泛型集合来看看他给我们带来的好处。

ArrayList<String> al1 = new ArrayList<String>();
al1.add("abc");
al1.add(1);   //编译时报错,

当我们用String参数类型实例化al1后,我们是不能添加int元素的,否则编译器会报错,通常在IDE编辑器,如eclipse中会有错误标识,与此同时,在取出元素也不需要类型转换.

string value = al1.get(0); //不需要类型转换

这便是泛型所带来的好处。

那么算法的复用主要是体现在,方法的复用,如ArrayList的Add方法可以使用在任何类型上或限定的类型上。

二、泛型的使用

     java中的泛型主要使用在类,方法,与接口中。首先,我们来简单的看看在类上的使用:

class Factory<T>{
    private T value;
    public T getValue()
    {
        return value;
    }
    public void setValue(T v)
    {
        this.value = v;
    }
}

  添加测试方法:

Factory<String> f = new Factory<String>();
f.setValue("factory in use");
System.out.println(f.getValue());

  泛型接口的使用:

interface MyInterface<T,U>{

    void show(T t, U u);
}

class ShowTest implements MyInterface<String,Integer>{

    @Override
    public void show(String t, Integer u) {
        System.out.println(t);
        System.out.println(u);

    }

}

泛型类型参数作用于类上的时候主要是对多个字段及方法签名之间的类型约束。作用于方法的时候主要是对方法的的多个参数做相应的约束,在这里方法的泛型类型参数不再举例,下面我们主要介绍类型参数的约束。

三、类型参数约束

  我们看一个小例子,如下代码所示:

public static <T> T get(T t1,T t2) {
    if(t1.compareTo(t2)>=0);//编译错误  ,the method compareTo(T) is undefined for the type T.
    return t1;
} 

可以看到编译器报错的信息,对于类型T没有定义compareTo方法,在java中类型需要比较的话需要实现Comparable接口,从而重写该方法。 那么我们做如下修改:

public static <T extends Comparable> T get(T t1,T t2) { //添加类型限定
        if(t1.compareTo(t2)>=0);
        return t1;
    }

通过限定T extends Comparable 表明,T是实现了Comparable的接口的类型,因此也实现了compareTo方法,因此不会产生编译期错误。

类型的多个限定时我们可以使用&来进行分割,并且限定的关键词只能使用extends。与此同时在接口与类型都存在的情况下,类只能放在第一个,并且只能有一个,如下所示:

<T extends Object&Comparable&Serializable>

参考来源:http://blog.csdn.net/lonelyroamer/article/details/7864531

原文地址:https://www.cnblogs.com/caiba/p/10579870.html

时间: 2024-10-14 22:19:06

Java 泛型的作用及其基本概念的相关文章

java泛型的作用及其基本概念

一.泛型的基本概念 java与c#一样,都存在泛型的概念,及类型的参数化.java中的泛型是在jdk5.0后出现的,但是java中的泛型与C#中的泛型是有本质区别的,首先从集合类型上来说,java 中的ArrayList<Integer>和ArrayList<String>是同一个类型,在编译时会执行类型擦除,及java中的类型是伪泛型,伪泛型将会在后面介绍,其次,对于像集合中添加基本类型的数据时,例如int,会首先将int转化成Integer对象,即我们通常所说的装箱操作,在取出

java泛型的作用和好处

转载于:https://blog.csdn.net/u012760183/article/details/52092692 之前参加面试的时候遇到面试官问泛型的作用,只是说了大概自己的理解, 在此转载记录一下,加深印象 泛型好处: 泛型简单易用 类型安全 泛型的主要目标是实现java的类型安全. 泛型可以使编译器知道一个对象的限定类型是什么,这样编译器就可以在一个高的程度上验证这个类型 消除了强制类型转换 使得代码可读性好,减少了很多出错的机会 Java语言引入泛型的好处是安全简单.泛型的好处是

Java泛型中的协变和逆变

Java泛型中的协变和逆变 一般我们看Java泛型好像是不支持协变或逆变的,比如前面提到的List<Object>和List<String>之间是不可变的.但当我们在Java泛型中引入通配符这个概念的时候,Java 其实是支持协变和逆变的. 看下面几行代码: // 不可变 List<Fruit>fruits =newArrayList<Apple>();// 编译不通过 // 协变 List<?extendsFruit>wildcardFruit

【java】泛型的作用是在编译阶段防止错误输入,绕过编译就绕过泛型,可用反射验证

1 package com.tn.collect; 2 3 import java.lang.reflect.Method; 4 import java.util.ArrayList; 5 6 public class Fanxin { 7 public static void main(String[] args){ 8 //泛型的作用是在编译阶段防止错误输入,绕过编译就绕过了泛型 9 //反射都是绕过编译操作 10 ArrayList<String> str=new ArrayList&l

2017.4.5 Java 泛型

Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型. 泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数. 假定我们有这样一个需求:写一个排序方法,能够对整形数组.字符串数组甚至其他任何类型的数组进行排序,该如何实现? 答案是可以使用 Java 泛型. 使用 Java 泛型的概念,我们可以写一个泛型方法来对一个对象数组排序.然后,调用该泛型方法来对整型数组.浮点数数组.字符串数组等进行排

Java泛型学习

先引用一段Java编程思想中的一段话 Java泛型的核心概念:告诉编译器你想使用什么类型,然后编译器帮你处理一切细节. 关于类型推断: 类型推断只对赋值操作有效,其他时候并不起作用.如果你见过一个泛型方法调用的结果 作为参数传递给另一个方法,这时编译器不会执行类型推断.在这种情况下,编译器认为:调用泛型 方法后,其返回值被付给了一个Object变量.当然现在在Java8先已经可以了

jdk学习之路---java泛型

1:java泛型的好处是可以实现类型检查,比较安全,可以实现功能的扩展化,增强功能. 2:泛型的概念就是参数化的类型,相当于方法中的形式参数一样,先做一个占位符然后再在使用的时候传递真正的参数进去. 3: package generic; /** * 自定义泛型类 * @author PC * */ public class GenericModel <T>{ private T data; public GenericModel(){ } public GenericModel(T data

Java 泛型(Generics) 综述

一. 引子 一般的类和方法,只能使用具体类型:要么是基本类型,要么是自定义类型.如果要编写可以应用于多种类型的代码,这种刻板的限制对代码的束缚就会很大. 多态算是一种泛化机制,但对代码的约束还是太强(要么继承父类,要么实现接口). 有许多原因促成了泛型的出现,而最引人注目的一个原因,就是为了创造容器类.(泛型的主要目的之一就是用来指定容器要持有什么类型的对象,而且由编译器来保证类型的正确性) 例如,在 Java 实现加入泛型前,ArrayList 只维护一个 Object 类型的数组: publ

Java泛型学习笔记 - (七)浅析泛型中通配符的使用

一.基本概念:在学习Java泛型的过程中, 通配符是较难理解的一部分. 主要有以下三类:1. 无边界的通配符(Unbounded Wildcards), 就是<?>, 比如List<?>. 无边界的通配符的主要作用就是让泛型能够接受未知类型的数据. 2. 固定上边界的通配符(Upper Bounded Wildcards): 使用固定上边界的通配符的泛型, 就能够接受指定类及其子类类型的数据. 要声明使用该类通配符, 采用<? extends E>的形式, 这里的E就是