Java泛型

泛型简介

Java泛型是J2 SE1.5中引入的一个新特性

泛型可以在编译的时候检查类型安全,并且所有的强制转换都是自动和隐式的。

泛型的原理就是 “类型的参数化”,即把类型看做参数。也就是说把所要操作的数据类型看做参数,就像方法的形式参数一样,是运行时传递的值的占位符一样。

简单的说,类型变量扮演的角色就如同一个参数,它提供给编译器用来类型检查的信息。

泛型可以提高代码的扩展性和重用性。


class Cls1 <T>   //定义泛型类
{
	T a;
	public Cls1(T a){
		this.a = a;
	}
	public T getData(){
		return a;
	}
}

public class Test {
	public static void main(String[] args) {
		Cls1<Integer> cls1 = new Cls1<Integer>(20);  //使用泛型类
		System.out.println(cls1.getData());
		
		Cls1<String> cls2 = new Cls1<String>("木易");
		System.out.println(cls2.getData());
	}
}

泛型类及特点

泛型的类型参数可以是泛类型

class Cls1 <T>
{
	T a;
	public Cls1(T a){
		this.a = a;
	}
	public T getData(){
		return a;
	}
}
public class Test {
	public static void main(String[] args) {
		Cls1<Cls1<Integer>> cls1 = new Cls1<Cls1<Integer>>(new Cls1<Integer>(20));
		System.out.println(cls1.getData().getData());
	}
}

执行结果:
结果

泛型类可以同时设置多个类型参数

class Cls2 <T,T2>
{
	T a;
	T2 b;
	public Cls2(T a,T2 b){
		this.a = a;
		this.b = b;
	}
	public T getData(){
		return a;
	}
	public T2 getData2(){
		return b;
	}
}

public class Test {
	public static void main(String[] args) {
		Cls2<Integer,String> cls3 = new Cls2<Integer,String>(500,"wang");
	 	System.out.println(cls3.getData());
	 	System.out.println(cls3.getData2());
	 	
	 	System.out.println(cls3.getData()+cls3.getData2());
	 	
	 	Cls2<Integer,Integer> cls4 = new Cls2<Integer,Integer>(500,20);
	 	System.out.println(cls4.getData()+cls4.getData2());
	}
}

执行结果:
结果

泛型类可以继承泛型类


class Cls1 <T>
{
	T a;
	public Cls1(T a){
		this.a = a;
	}
	public T getData(){
		return a;
	}
}
class Cls2 <T,T2> extends Cls1<T>
{
	T2 b;
	public Cls2(T a,T2 b){
		super(a);
		this.b = b;
	}
	public T2 getData2(){
		return b;
	}
}

public class Test {
	public static void main(String[] args) {
		Cls1<Cls1<Integer>> cls1 = new Cls1<Cls1<Integer>>(new Cls1<Integer>(20));
		System.out.println(cls1.getData().getData());
		
		Cls2<Integer,String> cls = new Cls2<Integer,String>(40,"zhang");
		System.out.println(cls.getData()+" "+cls.getData2());
		
		
	}
}

执行结果:
结果

继承抽象类:

abstract class Cls1 <T>
{
	T a;
	public Cls1(T a){
		this.a = a;
	}
	public T getData(){
		return a;
	}
	abstract void printinfo();
}
class Cls2 <T,T2> extends Cls1<T>
{
	T2 b;
	public Cls2(T a,T2 b){
		super(a);
		this.b = b;
	}
	public T2 getData2(){
		return b;
	}
	void printinfo() {
		// TODO Auto-generated method stub
		System.out.println("输出");
	}
}

public class Test {
	public static void main(String[] args) {
		
		Cls2<Integer,String> cls = new Cls2<Integer,String>(40,"zhang");
		System.out.println(cls.getData()+" "+cls.getData2());
		cls.printinfo();
		
		
	}
}

执行结果:
结果

泛型类可以实现泛接口


abstract class Cls1 <T>
{
	T a;
	public Cls1(T a){
		this.a = a;
	}
	public T getData(){
		return a;
	}
	abstract void printinfo();
}

interface Cls3<T3>
{
	abstract void printInfoCls3(T3 t);
}

class Cls2 <T,T2,T3> extends Cls1<T> implements Cls3<T3>
{
	T2 b;
	public Cls2(T a,T2 b){
		super(a);
		this.b = b;
	}
	public T2 getData2(){
		return b;
	}
	void printinfo() {
		// TODO Auto-generated method stub
		System.out.println("输出");
	}
	public void printInfoCls3(Object t) {
		// TODO Auto-generated method stub
		System.out.println(t);
	}
}

public class Test {
	public static void main(String[] args) {
		
		Cls2<Integer,String,String> cls = new Cls2<Integer,String,String>(80,"木易");
		System.out.println(cls.getData()+" "+cls.getData2());
		cls.printinfo();
		cls.printInfoCls3("测试");
		
		
	}
}

执行结果:
结果

限制泛型可用类型

在定义泛型类别时,默认在实例化泛型的时候可以使用任何类型,但是如果想要限制使用泛型类型时,只能用某个特定类型或者是其子类型才能实例化该类型时,可以在定义该类型时,使用extends关键字指定这个类型必须是继承某个类,或者实现某个接口

当没有指定泛类型继承的类型或接口时,默认使用extends Object,所以默认情况下任何类型都可以做为参数传入

限定泛类型只能是String:


abstract class Cls1 <T extends String>   //限定泛类型T只能是String
{
	T a;
	public Cls1(T a){
		this.a = a;
	}
	public T getData(){
		return a;
	}
	abstract void printinfo();
}

interface Cls3<T3>
{
	abstract void printInfoCls3(T3 t);
}

class Cls2 <T extends String,T2,T3> extends Cls1<T> implements Cls3<T3>
{
	T2 b;
	public Cls2(T a,T2 b){
		super(a);
		this.b = b;
	}
	public T2 getData2(){
		return b;
	}
	void printinfo() {
		// TODO Auto-generated method stub
		System.out.println("输出");
	}
	public void printInfoCls3(Object t) {
		// TODO Auto-generated method stub
		System.out.println(t);
	}
}

public class Test {
	public static void main(String[] args) {
		
		Cls2<String,String,String> cls = new Cls2<String,String,String>("muyi","木易");
		System.out.println(cls.getData()+" "+cls.getData2());
		cls.printinfo();
		cls.printInfoCls3("测试");
		
		
	}
}

执行结果:
结果

限定泛类型只能继承类:


class Animal
{
	
}

class Dog extends Animal
{
	
}

abstract class Cls1 <T extends Animal>
{
	T a;
	public Cls1(T a){
		this.a = a;
	}
	public T getData(){
		return a;
	}
	abstract void printinfo();
}

interface Cls3<T3>
{
	abstract void printInfoCls3(T3 t);
}

class Cls2 <T extends Animal,T2,T3> extends Cls1<T> implements Cls3<T3>
{
	T2 b;
	public Cls2(T a,T2 b){
		super(a);
		this.b = b;
	}
	public T2 getData2(){
		return b;
	}
	void printinfo() {
		// TODO Auto-generated method stub
		System.out.println("输出");
	}
	public void printInfoCls3(Object t) {
		// TODO Auto-generated method stub
		System.out.println(t);
	}
}

public class Test {
	public static void main(String[] args) {
		
		Cls2<Dog,String,String> cls = new Cls2<Dog,String,String>(new Dog(),"木易");
		System.out.println(cls.getData()+" "+cls.getData2());
		cls.printinfo();
		cls.printInfoCls3("测试");
	}
}

限定泛类型只能继承某个接口:


interface Move
{
	abstract void test();
}

abstract class Cls1 <T extends Move>
{
	T a;
	public Cls1(T a){
		this.a = a;
	}
	public T getData(){
		return a;
	}
	abstract void printinfo();
}

interface Cls3<T3>
{
	abstract void printInfoCls3(T3 t);
}

class Cls2 <T extends Move,T2,T3> extends Cls1<T> implements Cls3<T3>
{
	T2 b;
	public Cls2(T a,T2 b){
		super(a);
		this.b = b;
	}
	public T2 getData2(){
		return b;
	}
	void printinfo() {
		// TODO Auto-generated method stub
		System.out.println("输出");
	}
	public void printInfoCls3(Object t) {
		// TODO Auto-generated method stub
		System.out.println(t);
		a.test();
	}
}

public class Test {
	public static void main(String[] args) {
		Move a = new Move() {
			public void test() {
				// TODO Auto-generated method stub
				System.out.println("test");
			}
		};
		
		Cls2<Move,String,String> cls = new Cls2<Move,String,String>(a,"木易");
		a.test();
		cls.printInfoCls3("测试");
		
	}
}

执行结果:
结果

泛型通配声明

同一泛类型,如果实例化时给定的实际类型不同,则这些实例的类型是不兼容的,不能相互赋值。

Generic < Boolean > f1 = new Generic < Boolean >();
Generic < Integer> f2 = new Generic < Integer >();

f1 = f2  //会发生编译错误

Generic < Object> f = f1;  //f1和f类型并不兼容,发生编译错误
f = f2;                //f2和f类型同样不兼容,也会发生编译错误

泛类型实例之间的不兼容性会带来使用的不便。所以可以使用泛型通配符(?)声明泛型类的变量就可以解决这个问题。

泛型统配的方式

  • “ ? ”任意一个类型
Generic < Boolean > f1 = new Generic < Boolean >();
Generic < ? > f = f1;
class Cls1 <T>
{
	T a;
	public Cls1(T a){
		this.a = a;
	}
	public T getData(){
		return a;
	}
}
public class Test {
	public static void main(String[] args) {
		Cls1<Integer> c1 = new Cls1<Integer>(20);
		Cls1<Double> c2 = new Cls1<Double>(10.3);
		Cls1<?> c3;
		c3 = c1;
		c3 = c2;
	}
}
  • 和限制泛类型的上限相似,同样可以使用extends关键字限定通配类型的上限
Generic < Dog> f1 = new Generic < Dog >();
Generic < ? extends Animal > f = f1;
class Cls1 <T>
{
	T a;
	public Cls1(T a){
		this.a = a;
	}
	public T getData(){
		return a;
	}
}
public class Test {
	public static void main(String[] args) {
		Cls1<Integer> c1 = new Cls1<Integer>(20);
		Cls1<? extends Integer> c3;
		c3 = c1;
	}
}

class Animal
{	
}
class Dog extends Animal
{
}
class Cls1 <T>
{
	T a;
	public Cls1(T a){
		this.a = a;
	}
	public T getData(){
		return a;
	}
}
public class Test {
	public static void main(String[] args) {
		Cls1<Dog> c1 = new Cls1<Dog>(new Dog());
		Cls1<? extends Animal> c3;
		c3 = c1;
	}
}
  • 可以使用super关键字将通配符匹配类型限定为某个类型
Generic < Animal > f1 = new Generic < Animal >();
Generic < ? super Dog > f = f1;
class Animal
{	
}
class Dog extends Animal
{
}
class Cls1 <T>
{
	T a;
	public Cls1(T a){
		this.a = a;
	}
	public T getData(){
		return a;
	}
}
public class Test {
	public static void main(String[] args) {
		Cls1<Dog> c1 = new Cls1<Dog>(new Dog());
		Cls1<? super Dog> c3;
		c3 = c1;
	}
}

泛型方法

不仅类可以声明泛型,类中的方法也可以声明仅用于自身的泛型,这种方法叫做泛型方法。

定义:

访问修饰符 < 泛型列表 > 返回类型 方法名 ( 参数列表 ) {
	实现代码
}

在泛型列表中声明的泛型,可用于该方法的返回类型声明、参数类型声明和方法代码中的局部变量的类型声明。

类中其它方法不能使用当前方法声明的泛型

注意:是否拥有泛方法,与其所在的类是否泛型没有关系。要定义泛方法,只需将泛型参数列表置于返回值前。

泛型方法使用场景

添加类型约束只作用于一个方法的多个参数之间、而不涉及到类中的其它方法时。

施加类型约束的方法为静态方法,只能将其定义为泛方法,因为静态方法不能使用其所在类的类型参数

基础泛应用:


class A<T>
{
	public void printInfo(T t){
		System.out.println(t);
	}
}

class B
{
	//泛型方法
	public <T> void printInfo(T t){
		System.out.println(t);
	}
	//泛型方法的重载
	public <T,T2> void printInfo(T t,T2 t2){
		System.out.println(t);
		System.out.println(t2);
	}
	//方法的重载
	public void print1(int a){
		System.out.println(a);
	}
	public void print1(char a){
		System.out.println(a);
	}
	public void print1(String a){
		System.out.println(a);
	}
}

public class Test {
	public static void main(String[] args) {
		A<String> a = new A<String>();
		a.printInfo("木易");
		
		B b = new B();
		b.printInfo("yang");
		b.printInfo(123);
		b.printInfo(5.8);
		b.printInfo('b');
		
		b.printInfo("小黄", 180);
		
		b.print1('r');
		b.print1(20);
		b.print1("天哭");

	}
}

执行结果:
结果

限制约束泛型方法:


class Animal
{
	public void eat(){
		System.out.println("动物吃");
	}
}

class Dog extends Animal
{
	public void eat(){
		System.out.println("狗啃骨头");
	}
}

class Cat extends Animal
{
	public void eat(){
		System.out.println("猫吃鱼");
	}
}

class B
{
	//泛型方法
	public <T> void printInfo(T t){
		System.out.println(t);
	}
	//泛型方法的重载
	public <T,T2> void printInfo(T t,T2 t2){
		System.out.println(t);
		System.out.println(t2);
	}
	public <T extends Animal> void printInfo2(T t){
		t.eat();
	}
}

public class Test {
	public static void main(String[] args) {
		B b = new B();
		b.printInfo("yang");
		b.printInfo(123);
		b.printInfo(5.8);
		b.printInfo('b');
		b.printInfo("小黄", 180);
		
		b.printInfo2(new Dog());
		b.printInfo2(new Cat());
		b.printInfo2(new Animal());
	}
}

执行结果:
结果

静态方法应用:

class Animal
{
	public void eat(){
		System.out.println("动物吃");
	}
}
class Dog extends Animal
{
	public void eat(){
		System.out.println("狗啃骨头");
	}
}
class Cat extends Animal
{
	public void eat(){
		System.out.println("猫吃鱼");
	}
}
class B
{
	public static <T extends Animal> void printInfo2(T t){
		t.eat();
	}
}
public class Test {
	public static void main(String[] args) {
		B.printInfo2(new Dog());
		B.printInfo2(new Cat());
		B.printInfo2(new Animal());
	}
}

执行结果:
结果

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值