Java泛型浅解

我觉得学习一个东西,首先得从概念上明白它大概是什么?

  “泛型”就是“参数化类型”,也就是是把类型当成了一种参数。之前我们看到得函数方法比如:

public long add(int num1,int num2){...}

  其中add()方法的两个参数均是int类型的,而int数值范围是固定不变的,假如有时候加数的值比较大,可能是long类型,那么我们难道还专门去写一个函数吗?

public long add(long num1,long num2){...}

  如果采取这样的方式,首先绝对能实现,但是代码的利用率貌似很低,因为加数有各种各样的类型,且不方便统一管理。

  我感觉泛型的功能主要就是解决这个问题的,将原来具体的类型参数化(类型形参),在调用的时候再传入具体的类型(类型实参)。泛型可以用在类、接口和方法中,分别称为:泛型类、泛型接口、泛型方法。当然,使用泛型最广的地方往往还是在使用集合的时候。

  来看一个相当经典的例子:

package date11_23;

import java.util.ArrayList;

/**
 * 泛型的功能就是将原来具体的类型参数化(类型形参)
 * 在调用的时候再传入具体的类型(类型实参)。
 * 泛型可以用在类、接口和方法中
 * 使用泛型最广的地方是在使用集合的时候
 * @author 
 *be cast to 转换为
 *集合中添加的数值类型都会自动装箱,说明数值的类型均是其对应的包装类,
 *而不是基本数据类型。
 *集合就是存储对象的容器!!!
 */
public class FXStudy {

	public static void main(String[] args) {
		// TODO Auto-generated method stub

		ArrayList list=new ArrayList();
		list.add(123);
		list.add("234");
		list.add("i8w34");
		for(int i=0;i<list.size();i++)
		{
			System.out.println((String)list.get(i));
		}
	}

}

  运行结果:

  

  抛出异常:Integer不能转换成String。同时也说明一个问题,集合中添加的数值类型都会自动装箱,也就说名数值的类型均是其对应的包装类,而不是基本数据类型,这里也再次印证一句话:集合就是存储对象的容器。

  接着学习,因为集合类均可以存储任意类型的对象,所以Integer、String等等都可以存储,但是上例中,我们再次使用时,却都以String类型进行使用,所以程序肯定会报错的。这时候,我们就可以使用泛型,让程序在编译的时候就不能通过。参数化类型的具体格式: 

ArrayList<参数化类型> 变量名=new ArrayList<参数化类型>();

  如果“参数化类型”是String,那么该集合中就被限定只能存储String类型的元素。

  那我就按照上述手段修改一下那个例子,看看结果:

  果然如此,添加了泛型后,该集合添加了一个Double类型的数据123.8,显然它不是String类型,所以在敲代码的时候(编译阶段)直接报错了。

泛型的特点:

  泛型只发生在编译阶段,就是在程序运行的过程中,不包含一切有关泛型的信息。例如:

package date11_23;
import java.util.*;
public class FXStudy2 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub

		ArrayList<String> list=new ArrayList<String>();
		list.add("123");
		ArrayList list1=new ArrayList();
		Class Stringclass=list.getClass();
		Class NormalClass=list1.getClass();
		if(Stringclass==NormalClass)
		{
			System.out.println("1、"+list.toString()+"\t"+Stringclass);
			System.out.println("2、"+list1.toString()+"\t"+NormalClass);
			System.out.println("类型相同!");
		}
		System.out.println(list.toString());
	}

}

输出结果:

  上面代码在运行过程中,list与list1的类型均是ArrayList。这里为了让我自己理解得更加深入,我决定研究一下泛型的来龙去脉,都知道泛型是JDK1.5之后才出现的技术,那么之前是怎么实现类似于泛型的技术呢?

  老师说了,因为在Java中所有类的超级父类就是Object类型,所以那时候我们一般这样写:

package date11_23;
import java.util.*;
//学习泛型
public class FXStudy3 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub

		//生成一个Double类型的
		objectC demoDouble=new objectC(11.3);
		//String类型的
		objectC demoString=new objectC("SG");
		System.out.println(demoDouble.getTemp());
		System.out.println((Double)demoDouble.getTemp());
		System.out.println(demoString.getTemp());
		System.out.println((String)demoString.getTemp());
	}

}
class objectC{
	private Object temp;

	public Object getTemp() {
		return temp;
	}

	public void setTemp(Object temp) {
		this.temp = temp;
	}

	public objectC(Object temp) {
		
		this.temp = temp;
	}
	
}

运行结果:

11.3
11.3
SG
SG

  注意观察代码的11行与12行,都存在强制转型,并且从Object转型到String(或Double),属于向下转型,大家都知道向上转型是安全的,但是向下转型不是安全的,在这个例子中,就是我们必须知道Object对象到底指代的是字符串型还是整数型或者其他数据类型,才能让它转换成相应的形式,否则运行时会出现“类型不匹配”的异常。这样来实现的“泛型”真是比较繁琐,而且容易出错。然而在JDK1.5以后引入了真正的泛型技术,在应用层面上那就简单了很多,前面已经举过例子了。

泛型类是什么鬼?

  集合类就属于泛型类。看最开始的例子,限定存储什么类型,那么就只能存储什么类型,而且我觉得对于我自己来讲,可能应用最多的场合也就是泛型类。所以明白了上面举的例子,至少看懂别人的Java代码问题不大。不过,既然学习,再深入一点吧。

  泛型类的一般格式:

class 类名称 <泛型标识:可以随便写任意标识号,标识指定的泛型的类型>{
  private 泛型标识 
package date11_23;
import java.util.*;
/**
 * 真正的泛型
 * @author 
 *
 */
public class FXStudyReal {

	public static void main(String[] args) {
		// TODO Auto-generated method stub

		//生成一个Double 类型的
		NowFX demoDouble =new NowFX(123.0);
		//String 类型
		NowFX demoString=new NowFX("sdf");
		System.out.println(demoDouble.getTemp());
		System.out.println(demoString.getTemp());
	
	}

}
//泛型类的具体写法
class NowFX<T>{
	private T temp;
	public NowFX(T x)
	{
		temp=x;
	}
	public T getTemp() {
		return temp;
	}
	public void setTemp(T temp) {
		this.temp = temp;
	}
	
	
}

  必须明确的是,T只是一个代表类型的符号,且只能是类类型,不能是基本数据类型(如int、double等,不过它们的包装类属于类类型)。泛型接口和泛型类定义方法类似,不再赘述,多看看别人优秀的源码即可。不过要注意一点就是在写泛型接口的实现类的时候,需要将泛型的声明一起加入到该类中,也就是说该类是一个泛型类。

转载:[Java之泛型浅解](https://www.cnblogs.com/Cirgo/p/8446539.html)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值