java 泛型
Posted Heavy sea
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java 泛型相关的知识,希望对你有一定的参考价值。
一、泛型类的引入
1、问题提出
假设现在有这样的一个需求:需要产生多个对象,每个对象的逻辑完全一样,只是对象内的成员变量的类型不同,那我们如何做。
方法一:
创建多个类文件,给每个类中的成员变量设置指定的数据类型
class Cs1
private int a;
public Cs1(int a)
this.a = a;
public int getData()
return a;
class Cs2
private String a;
public Cs2(String a)
this.a = a;
public String getData()
return a;
public class Test
public static void main(String[] args)
Cs1 cs1 = new Cs1(12);
System.out.println(cs1.getData());
Cs2 cs2 = new Cs2("heavy sea");
System.out.println(cs2.getData());
很显然这种方式会导致类的膨胀,重用性太差
方法二:
由于int和String都继承自Object数据类型,故可以创建一个类文件,给这种类中的成员变量设置Object数据类型。
class Cs1
private Object a;
public Cs1(Object a)
this.a = a;
public Object getData()
return a;
public class Test
public static void main(String[] args)
Cs1 cs1 = new Cs1(12);
System.out.println(cs1.getData());
Cs1 cs2 = new Cs1("heavy sea");
System.out.println(cs2.getData());
但如果对结果类型强制转换,编译的时候正常,运行的时候可能会异常。
除这两种方法外,有没有更好的方法呢?
2、泛型简介:
在JDK 1.5 以后引入,泛型可以在编译的时候检查类型安全,并且所有的强制转换都是自动和隐式的。
泛型的原理就是“类型的参数化” 即把类型看做参数,也就是说把所操作的数据类型看作参数,就像方法的形式参数是运行时传递的值的占位符一样。
简单来说,类型变量扮演的角色就如同一个参数,它提供给编译器用来类型检查的信息。
泛型可以提高代码的扩展性和重用性。
泛型类及特点:
1.泛型的类型参数可以是泛型类
2.泛型类可以同时设置多个类型参数
3.泛型类可以继承泛型类
4.泛型类可以实现泛型接口
泛型类应用实例
// 泛型类
class Cs1 <T>
private T a;
public Cs1(T a)
this.a = a;
public T getData()
return a;
public class Test
public static void main(String[] args)
Cs1<Integer> cs1 = new Cs1<Integer>(12);
System.out.println(cs1.getData());
Cs1<String> cs2 = new Cs1<String>("heavy sea");
System.out.println(cs2.getData());
/**
* 泛型类可以继承泛型类
* 泛型类可以同时设置多个类型参数
*/
class Cs2 <T,T2> extends Cs1 <T>
private T2 b;
public Cs2(T a,T2 b)
super(a);
this.b = b;
public T2 getData2()
return b;
interface Cs3<T3>
abstract void printfData3(T3 a);
/**
* 泛型类可以实现泛型接口
*/
class Cs4<T3> implements Cs3<T3>
@Override
public void printfData3(T3 a)
System.out.println("a="+a);
二、限制泛型可用类型
1、extends关键字限制泛型可用类型
在定义泛型类别时,默认在实例化泛型类的时候可以使用任何类型,但是如果想要限制使用泛型类型的时候,只能用某个特定类型或者是其子类型才能实例化该类型时,可以在定义类型时,使用extends关键字指定这个类型必须是继承某个类,或者实现某个接口。
class Generic< T extends Animal >
当没有指定泛型继承的类型或接口时,默认使用extends Object,所以默认情况下任何类型都可以作为参数传入。
2、类型通配声明
同一泛型类,如果实例化时给定的实际类型不同,则这些实例的类型是不兼容的,不能互相赋值。
泛型类实例之间的不兼容性会带来使用的不便,我们可以使用泛型通配符(?)声明泛型类的变量就可以解决。
类型通配 例子:
?代表任意一个类型
Generic < Dog > f1 = new Generic< Dog >( );
Generic<?> f = f1;
和限制泛型的上限相似 同样可以使用extends关键字限定通配类型的上限
Generic< Dog > f1 = new Generic< Dog >();
Generic<? extends Animal> f = f1;
还可以使用super关键字将通配符类型限定为某个类型的下限
Generic< Animal > f1 = new Generic< Animal >( );
Generic<? super Dog> f = f1;
class Animal
class Dog extends Animal
class Generic<T>
private T a;
public Generic(T a)
this.a = a;
public T getA()
return a;
public class Test2
public static void main(String[] args)
Generic<String> g = new Generic<String>("11");
Generic<Integer> g2 = new Generic<Integer>(12);
// g = g2; 实例化类型不同,会报错
Generic<?> g3 = g;
// 限制通配符的上限 必须是该类或者该类的子类
Generic<? extends Animal> g4;
Generic<Dog> g5 = new Generic<Dog>(new Dog());
g4 = g5;
// 限制通配符的下限 必须是该类或者该类的父类
Generic<? super Dog> g6;
Generic<Animal> g7 = new Generic<Animal>(new Animal());
g6 = g7;
三、泛型方法:
不仅类可以声明泛型,类中的方法也可以声明仅用于自身的泛型,这种方法叫做泛型方法。
定义格式为:
访问修饰符<泛型列表> 返回类型 方法名参数
在泛型列表中声明的泛型,可用于该方法的返回类型声明 参数列表声明 和代码中的局部变量的类型声明
类中的其他方法不能使用当前方法声明的泛型
注意:是否拥有泛型方法,与所在类是否泛型没关系
class Generic<T>
T a;
public void printInfo()
System.out.println("a="+a);
class A
// 泛型方法
public <T>void printInfo(T a)
System.out.println(a);
public class Test5
public static void main(String[] args)
// 泛型类
Generic <String>g = new Generic<String>();
g.printInfo();
// 普通类
A a1 = new A();
a1.printInfo("hahaaha");
什么时候使用泛型方法,而不是泛型类呢
添加类型约束只作用于一个方法的多个参数之间,而不涉及类中的其他方法
施加类型约束的方法为静态方法,只能将其定义为泛型方法,因为静态方法不能使用其所在类的类型参数。
以上是关于java 泛型的主要内容,如果未能解决你的问题,请参考以下文章