Java如何理解泛型

我认为泛型可理解为类的形参(类似方法的参数)。当定义了泛型以后,就可通过不同类型参数的构造方法声明该类的对象。该形参可以传入任何Object

public class Main_01 {
	public static void main(String[] args) {
		//先拿list举例
		List<String> list = new ArrayList<String>();
		list.add(2);//此处会出红线,因为上一行约定好必须要为String对象
		list.add("2");//正常,后面在使用的时候便不需要加类型转换
		//自己举的例子
		Test<Main_01> m = new Test<Main_01>(new Main_01());
	}
	//下面这个方法的定义会报错。。看来方法的定义必须要明确参数类型。不能使用泛型
	public void TestMethod(E name){
	}
}
//类的形参E
class Test<E> {
	private E element;

	public Test(E element) {
		this.element = element;
	}
	public E getElement() {
		return element;
	}
	public void TestMethod(E name) {
	}
}

但是从上面这个例子并没有看出来出来泛型的好处
从HashMap的源码来看:

//声明HashMap类,可忽略父类和引入的接口
public class HashMap<K,V> extends AbstractMap<K,V>
    implements Map<K,V>, Cloneable, Serializable{}
//put方法
public V put(K key, V value) {}
//get方法
public V get(Object key) {}

在声明HashMap的时候有感受到泛型的帮助么!确实有帮助,例:

//1.没有约束的声明
HashMap hm1 = new HashMap();
hm1.put("s", "B");
hm1.put("b", 2);//what?你让我get出来你干啥!
//2.声明好边具有约束作用
HashMap<String, HashMap<String,String>> hm = new HashMap<String, HashMap<String,String>>();
hm.put("Key","报错例子")
HashMap<String,String> Value = new HashMap<String, String>();
hm.put("Key", Value);//正确例子

如代码所示:hm1对象的get方法并不知道Value的类型。而hm对象的get方法可以放心使用!因为不是HashMap类型的方法根本没有办法put进去!

综上所述:泛型的好处列出来了!(fuck?你确定能看出来这么多好处,还有这些都是啥好处啊。。。)

Java语言引入泛型的好处是安全简单。泛型的好处是在编译的时候检查类型安全,并且所有的强制转换都是自动和隐式的,提高代码的重用率。

泛型在使用中还有一些规则和限制:
1、泛型的类型参数只能是类类型(包括自定义类),不能是简单类型。
2、同一种泛型可以对应多个版本(因为参数类型是不确定的),不同版本的泛型类实例是不兼容的。
3、泛型的类型参数可以有多个。
4、泛型的参数类型可以使用extends语句,例如<T extends superclass>。习惯上成为“有界类型”。
5、泛型的参数类型还可以是通配符类型。例如Class<?> classType = Class.forName(Java.lang.String);

Java泛型中的标记符含义:
E - Element (在集合中使用,因为集合中存放的是元素)
T - Type(Java 类)
K - Key(键)
V - Value(值)
N - Number(数值类型)
? - 表示不确定的java类型
S、U、V - 2nd、3rd、4th types

上面说到HashMap里面有这么一个构造方法:

public HashMap(Map<? extends K, ? extends V> m) {}

忍不住百度了一下:
原来是通配符:
通配符有三种:

1、无限定通配符 形式<?>
2、上边界限定通配符 形式< ? extends Number> //用Number举例
3、下边界限定通配符 形式< ? super Number> //用Number举例
1:界定通配符的上边界
Vector<? extends 类型1> x = new Vector<类型2>();
类型1指定一个数据类型,那么类型2就只能是类型1或者是类型1的子类

Vector<? extends Number> x = new Vector<Integer>();//这是正确的
Vector<? extends Number> x = new Vector<String>();//这是错误的

2:界定通配符的下边界
Vector<? super 类型1> x = new Vector<类型2>();
类型1指定一个数据类型,那么类型2就只能是类型1或者是类型1的父类

Vector<? super Integer> x = new Vector<Number>();//这是正确的
Vector<? super Integer> x = new Vector<Byte>();//这是错误的
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值