工作笔记-Java 泛型和泛型参数

泛型是Java1.5以后的特性,在各种开源框架的源码当中可以看到很多泛型的使用,如果不对泛型做到了如指掌的话,看源码真的会有阻碍。下面是泛型的一个简单的例子。

public class GenericsDemo<T> {
	private T demoProp;
	
	public T getDemoProp(){
		return demoProp;
	}
	
	public void setDemoProp(T demoProp){
		this.demoProp = demoProp;
	}
}

GenericsDemo类声明了一个泛型参数,T可以代表任何一个类型,在编译时,编译器并不知道对象在实例化过程中使用的T类型到底是什么,泛型是运用在编译时期的技术。

GenericsDemo的成员变量demoProp是T类型的,这个变量的类型也是在对象实例化的过程中才会指定的。

	public static void main(String args[]){
		GenericsDemo<String> demoStr = new GenericsDemo<String>();
		GenericsDemo<Integer> demoInt = new GenericsDemo<Integer>();
		GenericsDemo<Double> demoDoub = new GenericsDemo<Double>();
		
		String str = demoStr.getDemoProp();
		Integer inte = demoInt.getDemoProp();
		Double doub = demoDoub.getDemoProp();
	}

在使用过程中,分别指定String, Integer, Double为参数对GenericsDemo进行实例化,然后分别用这三个类型去接收demoProp的值,不会有error或者warning。

但是如果使用比如int会报错,因为泛型参数只能替换为对象类型,而int类型是基础数据类型,不是对象。

		GenericsDemo<int> demoInt = new GenericsDemo<int>();//编译报错

接收的变量类型和实例化对象时使用的泛型参数类型不匹配时也会报错

		String inte = demoInt.getDemoProp();//编译报错

类声明时可以指定不止一个泛型参数

public class GenericsDemo<T,E> {
	private T demoProp;
	
	public T getDemoProp(){
		return demoProp;
	}
	
	public void setDemoProp(T demoProp){
		this.demoProp = demoProp;
	}
	
	public void process(E element){
		System.out.println("processing");
	}

}

如果我们预设实例化时,T,E传入的是某一类对象,并且想使用对象的方法和属性,我们就必须对T,E进行限定。不做限定的T,E只能使用Object的方法,因为所有对象都派生自Object。

public class GenericsDemo<E> {
	
	public void process(E element){
        //可以使用Object的getClass()方法
		System.out.println(element.getClass().getName());
	}

}

可以使用extends和super对泛型参数添加限定,extends的使用举例,定义People类,实现了Action接口。

public class People implements Action{
	
	public void walk() {
		System.out.println("walking");
	}

}
public interface Action {

	public void walk();
}
public class Male extends People{

	public void shave(){
		System.out.println("only man can shave");
	}
}

重新定义GenericsDemo

public class GenericsDemo<T extends People> {
	private T demoProp;
	
	public T getDemoProp(){
		return demoProp;
	}
	
	public void setDemoProp(T demoProp){
		this.demoProp = demoProp;
	}
	
	public void move(){
		demoProp.walk();
	}
}

<T extends People>代表泛型参数T是People的子类型,对T进行限定了以后,编译器知道T肯定是People的子类型,就可以使用People的方法了。上例中通过demoProp.walk()直接调用。

实例化GenericsDemo时,可以传入People或者其子类

public static void main(String args[]){
	GenericsDemo<People> demoPeople = new GenericsDemo<People>();
	GenericsDemo<Male> demoMale = new GenericsDemo<Male>();
	demoPeople.setDemoProp(new People());
	demoPeople.move();
		
	demoMale.setDemoProp(new Male());
	demoMale.move();
}

没有报错,运行正常,说明extends边界包含T本身。

但是要注意的是,extends和我们继承时候使用的extends不是相同的,这里的extends是子类型的意思,不是子类,对于接口也是可行的,比如这么写


public class GenericsDemo<T extends Action> {
	private T demoProp;
	
	public T getDemoProp(){
		return demoProp;
	}
	
	public void setDemoProp(T demoProp){
		this.demoProp = demoProp;
	}
	
	public void move(){
		demoProp.walk();
	}

}

依然能够正常编译和运行,是因为People和Male都实现了Action接口,也是Action派生出来的类。

super和extends相反,通过super限定的泛型参数,比如<? super Male>,代表泛型参数是指定类型的父类型。

super只能用在泛型参数,不能用在类声明中,很好理解,对于extends的情况,编译器知道继承的具体父类型是谁,所以自然对象可以使用哪些方法是具体的。对于super的情况,编译器并不知道父类具体是谁,所以父类型有哪些方法编译器是不知道的,所以在类的声明中,<? super Male> 和<T>在编译器看来没什么区别。

//编译报错
public class GenericsDemo<T super Male> {
}

通配符?

在泛型类的使用中,有时候不知道最后传入的参数是什么类型的对象,会使用通配符?来代替,比如

	public static void main(String args[]){
		GenericsDemo<?> demoPeople;
		demoPeople = new GenericsDemo<People>();
		demoPeople = new GenericsDemo<Male>();

		demoPeople.move();
		}

比如我们使用?来声明demoPeople,没有给他指定特定的对象类型,所以他的对象类型是可以任意的,所以可以使用People和Male来初始化他,都不会报错。

?不能出现在等号右边,必须告诉编译器你打算用什么类型初始化。

?通配符声明的对象在初始化以后不能对泛型成员变量进行set。

//报错
demoPeople = new GenericsDemo<?>();
//报错
demoPeople.setDemoProp(new People());

通配符和限定词配合使用


public class GenericsESDemo {
	public void testSuper(GenericsDemo<? super Male> generic){
		System.out.println("testing super");
	}
	
	public void testExtends(GenericsDemo<? extends People> generic){
		System.out.println("testing extends");
	}
	
	
	public static void main(String args[]){
		GenericsESDemo demo = new GenericsESDemo();
		demo.testSuper(new GenericsDemo<People>());
		demo.testExtends(new GenericsDemo<Male>());
		
	}
}

可以限制传入的泛型参数是某些特定类型的父类型或者子类型,使用可以更加灵活。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
东南亚位于我国倡导推进的“一带一路”海陆交汇地带,作为当今全球发展最为迅速的地区之一,近年来区域内生产总值实现了显著且稳定的增长。根据东盟主要经济体公布的最新数据,印度尼西亚2023年国内生产总值(GDP)增长5.05%;越南2023年经济增长5.05%;马来西亚2023年经济增速为3.7%;泰国2023年经济增长1.9%;新加坡2023年经济增长1.1%;柬埔寨2023年经济增速预计为5.6%。 东盟国家在“一带一路”沿线国家中的总体GDP经济规模、贸易总额与国外直接投资均为最大,因此有着举足轻重的地位和作用。当前,东盟与中国已互相成为双方最大的交易伙伴。中国-东盟贸易总额已从2013年的443亿元增长至 2023年合计超逾6.4万亿元,占中国外贸总值的15.4%。在过去20余年中,东盟国家不断在全球多变的格局里面临挑战并寻求机遇。2023东盟国家主要经济体受到国内消费、国外投资、货币政策、旅游业复苏、和大宗商品出口价企稳等方面的提振,经济显现出稳步增长态势和强韧性的潜能。 本调研报告旨在深度挖掘东南亚市场的增长潜力与发展机会,分析东南亚市场竞争态势、销售模式、客户偏好、整体市场营商环境,为国内企业出海开展业务提供客观参考意见。 本文核心内容: 市场空间:全球行业市场空间、东南亚市场发展空间。 竞争态势:全球份额,东南亚市场企业份额。 销售模式:东南亚市场销售模式、本地代理商 客户情况:东南亚本地客户及偏好分析 营商环境:东南亚营商环境分析 本文纳入的企业包括国外及印尼本土企业,以及相关上下游企业等,部分名单 QYResearch是全球知名的大型咨询公司,行业涵盖各高科技行业产业链细分市场,横跨如半导体产业链(半导体设备及零部件、半导体材料、集成电路、制造、封测、分立器件、传感器、光电器件)、光伏产业链(设备、硅料/硅片、电池片、组件、辅料支架、逆变器、电站终端)、新能源汽车产业链(动力电池及材料、电驱电控、汽车半导体/电子、整车、充电桩)、通信产业链(通信系统设备、终端设备、电子元器件、射频前端、光模块、4G/5G/6G、宽带、IoT、数字经济、AI)、先进材料产业链(金属材料、高分子材料、陶瓷材料、纳米材料等)、机械制造产业链(数控机床、工程机械、电气机械、3C自动化、工业机器人、激光、工控、无人机)、食品药品、医疗器械、农业等。邮箱:market@qyresearch.com

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值