java泛型概述

从JDK1.5开始提供泛型的概念,泛型实质上就是使程序员定义安全的类型。在没有出现泛型之前,java也提供了对Object的引用"任意化"操作,这种任意化操作就是对Object引用进行"向下转型"及"向上转型"操作,但某些强制类型转换的错误也许不会被编译器捕捉,而在运行后出现异常,可见强制类型转换存在安全隐患。

1. 定义泛型

在JDK1.5以后出现了泛型机制,其语法如下:

类名<T>

其中T代表了一个类型的名称。

实例如下所示:

public class OverClass<T> {
    private T over;

    public T getOver() {
        return over;
    }

    public void setOver(T over) {
        this.over = over;
    }

    public static void main(String[] args) {
        // 实例化一个Boolean型的对象
        OverClass<Boolean> over1 = new OverClass<Boolean>();
        // 实例化一个Float型的对象
        OverClass<Float> over2 = new OverClass<Float>();
        over1.setOver(true);// 不需要进行类型转换
        over2.setOver(12.3f);// 不需要进行类型转换
        Boolean b = over1.getOver();
        Float f = over2.getOver();
        System.out.println(b);
        System.out.println(f);
    }
}

从上面的程序可以看出,使用泛型定义的类在声明该类对象时可以根据不同的需求指定<T>真正的类型,而在使用类中的方法传递或返回数据类型时将不再需要进行类型转换操作,而是使用在声明泛型类对象时<>符号中设置的数据类型。

使用泛型这种形式将不会发生ClassCastException异常,因为在编译器中就可以检查类型匹配是否正确。

在定义泛型类时,一般将类型名称使用T来表述,而容器的元素使用E来表述。

2. 泛型的常规用法

2.1 定义泛型类时声明多个类型

在定义泛型类时可以声明多个类型,语法如下:

MutiOverClass<T1,T2>

其中,MutiOverClass代表泛型类名称,T1和T2为可能被定义的类型。

这样在实例化指定类型的对象时就可以指定多个类型,例如:

MutiOverClass<Boolean,Float> m=new MutiOverClass<Boolean,Float>;

2.2 定义泛型类时声明数组类型

定义泛型类时也可以声明数组类型。如下所示实例:

public class ArrayClass<T> {
    private T[] array;

    public T[] getT() {
        return array;
    }

    public void setT(T[] array) {
        this.array = array;
    }

    public static void main(String[] args) {
        ArrayClass<String> a = new ArrayClass<String>();
        String[] array = { "成员1", "成员2", "成员3", "成员4", "成员5" };
        a.setT(array);// 调用Set()方法
        for (int i = 0; i < a.getT().length; i++) {
            System.out.println(a.getT()[i]);// 调用getT()方法返回数组中的值
        }
    }
}

运行效果如下:

可以使用泛型声明一个数组,但是不可以使用泛型来建立数组的实例。如下所示是错误的用法:

public class ArrayClass<T> {
//private T[] array=new T[10];//不可以使用泛型来建立数组的实例
}

3. 集合类声明容器的元素

可以使用K和V两个字符代表容器中的键值和与键值对相对应的具体值。如下示例所示:

public class MutiOverClass<K, V> {
    public Map<K, V> m = new HashMap<K, V>();// 定义一个集合HashMap实例

    // 设置put()方法,将对应的键值和键名存入集合对象中
    public V get(K k) {
        return m.get(k);
    }

    public void put(K k, V v) {
        m.put(k, v);
    }

    public static void main(String[] args) {
        // 实例化泛型类对象
        MutiOverClass<Integer, String> mu = new MutiOverClass<Integer, String>();
        for (int i = 0; i < 5; i++) {
            // 根据集合的长度循环将键名与具体值放入集合中
            mu.put(i, "我是集合成员:" + i);
        }

        for (int i = 0; i < mu.m.size(); i++) {
            // 调用get方法获取集合中的值
            System.out.println(mu.get(i));
        }
    }
}

其实上面定义集合的泛型类在集合框架中已经都被泛型化了,可以直接使用。

4. 泛型的高级用法

泛型的高级用法包括限制泛型可用类型和使用类型通配符等。

4.1 限制泛型可用类型

默认可以使用任何类型来实例化一个泛型类对象,但java中也对泛型类实例的类型作了限制,语法如下:

Class 类名称<T extends anyClass>

其中,anyClass是指某个接口或类。

使用泛型限制后,泛型类的类型必须是实现或继承了anyClass这个接口或类。无论anyClass是接口或类,在进行泛型限制时,都必须使用extends关键字。示例如下所示:

public class LimitClass<T extends List> {
    public static void main(String[] args) {
        // 可以实例化已经实现List接口的类
        LimitClass<ArrayList> l1 = new LimitClass<ArrayList>();
        LimitClass<LinkedList> l2 = new LimitClass<LinkedList>();
        // 这句是错误的,因为HashMap没有实现List()接口
        // LimitClass<HashMap> l3 = new LimitClass<HashMap>();
    }
}

4.2 使用类型通配符

在泛型机制中提供了类型通配符,其主要作用是在创建一个泛型类对象时限制这个泛型类的类型实现或继承某个接口或类的子类。要声明这样一个对象可以使用"?"通配符来表示,同时依然使用extends关键字来对泛型加以限制。

使用泛型类型通配符的语法如下:

泛型类名称<? extends List> a=null;

其中,<? extends List>表示类型未知,当需要使用该泛型对象时,可以单独实例化。
如下所示:

A<? extends List> a=null;
a=new A<ArrayList>();
a=new A<LinkedList>();

如果实例化没有实现List接口的泛型对象,编译器将会出错。

除了可以实例化一个限制泛型类型的实例之外,还可以将该实例放置在方法的参数中。如下所示:

public void doSomething(A<? extends List>){}

在上述代码中,定义方式有效限制了传人doSomething()方法的参数类型。

如果使用A<?>这种形式实例化泛型类对象,则默认表示可以将A指定为可以实例化Object及以下的子类类型。如下所示:

List<String> l1=new ArrayList<String>();
l1.add("成员");
List<?> l2=l1;
List<?> l3=new LinkedList<Integer>();

泛型类型限制除了可以向下限制之外,还可以进行向上限制,只要在定义时使用super关键字即可。例如,"A<? super List> a=null;" 这样定义后,对象a只接受List接口或上层父类类型,如"

a=new A<Object>();"

4.3 继承泛型类与实现泛型接口

定义为泛型的类和接口也可以被继承与实现。如下所示:

public class ExtendClass<T1> {

}

class SubClass<T1, T2, T3> extends ExtendClass<T1> {
}

如果在SubClass类继承ExtendClass类时保留父类的泛型类型,需要在继承时指明,如果没有指明,直接使用extends ExtendClass<T1>语句进行继承操作,则SubClass类中的T1,T2和T3都会自动变为Object,所以在一般情况下都会将父类的泛型类型保留。

定义的泛型接口也可以被实现,如下所示:

interface i<T1> {

}

class SubClass2<T1, T2, T3> implements i<T1> {
}

5. 泛型用法总结

泛型的类型参数只能是类类型,不可以是简单类型,如A<int> 这种泛型定义就是错误的。

泛型的类型个数可以是多个。

可以使用extends关键字限制泛型的类型。

可以使用通配符限制泛型的类型。

时间: 2024-11-24 22:36:09

java泛型概述的相关文章

Java学习笔记_26_泛型概述

                                                               泛型概述 在Java中存入容器中的对象再取出时需要转换类型,因为对象加入容器会被转换成Object类型,而取出时要转换成实际类型.但向  下类型转换都 是存在潜在危险的,因此应该尽量避免它们.  Java的泛型: 所谓泛型就是在定义(类.方法.形参.成员变量等等)的时候,指 定它们为通用类型,也就是数据类型可以是任意类型. 泛型为提高大型程序的类型安全和维护带来了很大的潜

学习记录 java泛型资料

java泛型资料: 1. 概述在引入范型之前,Java类型分为原始类型.复杂类型,其中复杂类型分为数组和类.引入范型后,一个复杂类型就可以在细分成更多的类型.例如原先的类型List,现在在细分成List<Object>, List<String>等更多的类型.注意,现在List<Object>, List<String>是两种不同的类型,他们之间没有继承关系,即使String继承了Object.下面的代码是非法的    List<String>

【转载】Java泛型详解

[转载]http://www.importnew.com/24029.html 对java的泛型特性的了解仅限于表面的浅浅一层,直到在学习设计模式时发现有不了解的用法,才想起详细的记录一下. 本文参考java 泛型详解.Java中的泛型方法. java泛型详解 1. 概述 泛型在java中有很重要的地位,在面向对象编程及各种设计模式中有非常广泛的应用. 什么是泛型?为什么要使用泛型? 泛型,即"参数化类型".一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参.那么参数化

JAVA泛型知识点

JAVA泛型 1.概述 泛型:即"参数化类型".将类型由原来的具体类型参数化,类似于方法中的变量参数,此时类型同样定义为参数形式,只有在调用/运行时才传入具体的类型. 泛型的本质:为了参数化类型,即在不创建新的类型的情况下,通过反省制定的不同类型来控制形参具体显限制的类型,也就是说在使用泛型的过程中,操作的数据类型被指定为某一参数时,改类型可以用在泛型类.泛型接口.泛型方法中. 2.特性 泛型只在编译阶段有效--->由于JVM的泛型类型擦除. List<String>

Java基础11:Java泛型详解

Java基础11:Java泛型详解 泛型概述 泛型在java中有很重要的地位,在面向对象编程及各种设计模式中有非常广泛的应用. 什么是泛型?为什么要使用泛型? 泛型,即"参数化类型".一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参.那么参数化类型怎么理解呢?顾名思义,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参). 泛型的本质是为了参数化类型(在不创建新的类型的

java 泛型详解-绝对是对泛型方法讲解最详细的,没有之一 (zhuan)

对java的泛型特性的了解仅限于表面的浅浅一层,直到在学习设计模式时发现有不了解的用法,才想起详细的记录一下. 本文参考java 泛型详解.Java中的泛型方法. java泛型详解 https://www.cnblogs.com/coprince/p/8603492.html 1. 概述 泛型在java中有很重要的地位,在面向对象编程及各种设计模式中有非常广泛的应用. 什么是泛型?为什么要使用泛型? 泛型,即“参数化类型”.一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参.那么

【转】java 泛型详解

java 泛型详解 对java的泛型特性的了解仅限于表面的浅浅一层,直到在学习设计模式时发现有不了解的用法,才想起详细的记录一下. 本文参考java 泛型详解.Java中的泛型方法. java泛型详解 1. 概述 泛型在java中有很重要的地位,在面向对象编程及各种设计模式中有非常广泛的应用. 什么是泛型?为什么要使用泛型? 泛型,即“参数化类型”.一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参.那么参数化类型怎么理解呢? 顾名思义,就是将类型由原来的具体的类型参数化,类似于

Java泛型/泛型限定

一.泛型概述: 1.来源:1.5jdk出现的新特性:用于解决安全问题,是一个安全机制: //下面代码,编译不报错,运行报错,加上泛型给与集合类型限定: 2.好处:减少运行时的问题,在编译时体现:避免强制转换的麻烦: 3.关键字:<数据类型> public class Test { public static void main(String[] args) { ArrayList arrayList = new ArrayList(); arrayList.add("1")

(转)java 泛型详解-绝对是对泛型方法讲解最详细

对java的泛型特性的了解仅限于表面的浅浅一层,直到在学习设计模式时发现有不了解的用法,才想起详细的记录一下. 本文参考java 泛型详解.Java中的泛型方法. java泛型详解 1. 概述 泛型在java中有很重要的地位,在面向对象编程及各种设计模式中有非常广泛的应用. 什么是泛型?为什么要使用泛型? 泛型,即“参数化类型”.一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参.那么参数化类型怎么理解呢? 顾名思义,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此