Java语言学习总结 扩展篇 泛型的概念定义及使用

泛型

泛型的概念

泛型是一种未知的数据类型,是在定义某些类时,我们不知道使用什么数据类型时,就可以用泛型。然后在创建对象时,确定泛型的数据类型。
泛型也可以看出是一个变量,用来接受数据类型
例如ArrayList在定义的时候不知道集合中都会存储什么类型的数据,所以类型使用泛型。
E:未知的数据类型
例如有如下ArrayList类,定义时用泛型
public class ArrayList{
public boolean add(E e) {}
public String get(int index) {}
}
创建集合对象的时候,如下:
ArrayList list = new ArrayList();
就会把数据类型String传给泛型E。

使用泛型的好处

创建集合对象时,不适用泛型的好处:
默认类型就是Object类型,可以存储任意类型的数据
弊端:
不安全,会引发异常
代码示例:

import java.util.ArrayList;
import java.util.Iterator;
public class EClass {	
	private static void show01() {
		ArrayList list = new ArrayList();	
		list.add("ab");
		list.add(1);
		list.add(2);
		list.add(3);
		list.add(4);
		
		//接下来使用迭代器遍历list集合
		//获取迭代器
		Iterator it = list.iterator();
		while(it.hasNext()) {
			Object obj = it.next();
			System.out.println(obj);
			
			//如果想要用String类特有的方法,
			//length获取字符串的长度,不能使用,
			//多态Object需要向下转型
			String s = (String)obj;
			System.out.println(s.length());
		}
	}
	public static void main(String[] args) {
		show01();
	}
}

ArrayList可以存储任意类型的数据,所以在向下转型为String使用length()方法求字符串长度时,容易出错。会提示类型转换异常。

创建集合对象,使用泛型的好处

  1. 避免了类型转换的麻烦,存储的是什么类型,取出来就是什么类型
  2. 把运行期异常(代码运行之后会出现的异常,提升到了编译期(写代码时候会报错) 。
    弊端:
    泛型是什么类型,就只能存储什么类型的数据
	private static void show02() {
		ArrayList<String> list = new ArrayList<>();
		list.add("abcdefg");
		list.add("abcdef");
		list.add("abcde");
		list.add("abcd");
		list.add("abc");
		list.add("ab");
		list.add("a");
		//list.add(1);   //此时会报异常,add(int, String) 
		//in the type ArrayList<String> is not applicable 
		//for the arguments (int)
		
		//使用迭代器遍历list集合
		Iterator<String> it = list.iterator();
		while(it.hasNext()) {
			String s = it.next();
			System.out.println(s + "->" + s.length());
		}
		
	}

调用这个方法输出结果如下:
输出结果
用了泛型之后并且讲创建对象时把泛型定义为String之后,只能存储String类型的数据,所以取出来的一定是String类型,可以直接用length()方法求字符串长度。不需要向下转型,也不会出现类型转换异常。

泛型的定义和使用

泛型,用来灵活地将数据类型应用到不同的类,方法,接口当。将数据类型作为参数进行传递。

定义含有泛型的类

定义格式
修饰符 class 类名 <代表泛型的变量> { }
class ArrayList{
public boolean add(E e){ }

public E get(int index){   } 
.....

}
示例代码如下(E为泛型):

public class GenericClass<E> {
	private E name;
	
	public E getName() {
		return name;
	}
	public void setName(E name) {
		this.name = name;
	}
}
public class DemoTestClass {

	public static void main(String[] args) {
		//如果不写泛型 则默认为Object类型
		GenericClass gc= new GenericClass();
		gc.setName("字符串");
		Object obj = gc.getName();
		
		//创建GenericClass对象泛型用Integer类型
		GenericClass<Integer> gc1 = new GenericClass<>();
		gc1.setName(1);
		Integer name = gc1.getName();
		System.out.println(name);

		//创建GenericClass对象泛型用String类型
		GenericClass<String> gc2 = new GenericClass<>();
		gc2.setName("132456asc");
		String str = gc2.getName();
		System.out.println(str);
	}
}
```输出结果:
![输出结果](https://img-blog.csdnimg.cn/20200131184806229.png)

### 定义含有泛型的方法
泛型定义在方法的修饰符和返回值类型之间
格式:
**修饰符 <泛型> 返回值类型 方法名(参数列表 (使用泛型)){
方法体;
}**
含有泛型的方法,在调用方法的时候确定泛型的数据类型,传递什么类型的数据,泛型就是什么类型

示例代码:

```java
public class GenericClassTwo {
	//定义一个含有泛型的方法
	public <M> void method(M m) {
		System.out.println(m);
	}
	
	//定义一个含有泛型的静态方法
	public static <S> void method02(S s) {
		System.out.println(s);
	}

}


public class DemoTestClass02 {

	public static void main(String[] args) {
		//创建GenericMethod对象
		GenericClassTwo gm = new GenericClassTwo();
		//调用method方法时,传递的是什么类型,泛型就是什么类型
		gm.method(1);
		gm.method("avf");
		
		GenericClassTwo.method02("静态方法");

	}

}

泛型通配符

当使用泛型类或者接口时,传递的数据中,泛型类型不确定,可以通过通配符<?>表示。但是一旦使用泛型的通配符后,只能使用0bject类中的共性方法,集合中元素自身方法无法使用。

泛型通配符:
?: 代表任意的数据类型
使用方式:
不能创建对象使用
只能作为方法的参数使用

import java.util.ArrayList;
import java.util.Iterator;
public class TongPeiFuClass {
	/**
	 * 定义一个方法,能够遍历任意类型ArrayList的集合
	 * 如果不知道ArrayList集合使用什么数据类型,可以
	 * 用泛型的通配符?来接收数据类型
	 * 注意; 泛型没有继承概念
	 * @param list
	 */
	public static void printArray(ArrayList<?> list) {
		Iterator<?> it = list.iterator();
		while(it.hasNext()) {
			//it.next()取出的元素Object类型,可以接受任意的数据类型
			Object o = it.next();
			System.out.println(o);
		}
	}

	public static void main(String[] args) {
		ArrayList<Integer> list01 = new ArrayList<>();
		list01.add(1);
		list01.add(2);
		
		ArrayList<String> list02 = new ArrayList<>();
		list02.add("aa");
		list02.add("dd");

		printArray(list01);
		printArray(list02);
	}

}

输出结果:
输出结果

发布了72 篇原创文章 · 获赞 3 · 访问量 6191

猜你喜欢

转载自blog.csdn.net/Ace_bb/article/details/104126326