为什么要有泛型Generic?
解决数据类型的安全性问题,其主要原理是在类声明时通过一个标识表示类中某个属性的类型或者是某个方法的返回值及参数类型。这样在类声明或实例化时只要指定好需要的具体的类型即可。
Java中的泛型,只在编译阶段有效
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
List list =new ArrayList();
list.add(111);
list.add("sss");
list.add(true);
//需求 只能在集合中存放字符串
List<String> l =new ArrayList<String>();
}
}
泛型的使用
1,泛型类
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
A<String> a =new A<String>();
a.setKey("ssss"); //set必须是字符串,在new的时候指定泛型是String
String s=a.getKey();
A<Integer> a1 =new A<Integer>();
a1.setKey(5);
Integer i =a1.getKey();
//同样的类 但new对象的时候泛型指定了不同的数据类型,这些类型不能相互赋值
}
}
/**
* 这里的泛型可以任意取名,A,b
* T 意为type
* @author xrh
*
* @param <T>
*/
class A<T>{
private T key;
public void setKey(T key) {
this.key=key;
}
public T getKey() {
return this.key;
}
}
2,泛型接口
public class Test1 {
public static void main(String[] args) {
B <String>b=new B<String>();
B1 b2=new B1(); //不用写泛型了
}
}
interface I<T>{
T test(T t);
}
//未传入泛型实参时,与泛型类的定义相同,在声明类的时候,需将泛型的声明也一起加到类中
class B <T> implements I <T>{
@Override
public T test(T t) {
return t;
}
}
//如果实现接口是指定接口的泛型的具体数据类型
//这个类实现接口所有方法的位置都要泛型替换实际的具体数据类型
class B1 implements I<String>{
@Override
public String test(String t) {
return t;
}
}
3,泛型方法
public class Test1 {
public static void main(String[] args) {
Cc<Object> c =new Cc<Object>();
//泛型方法在调用之前没有固定的数据类型
//在调用时传入什么类型就会把泛型改成什么类型
int i =c.test1(11);
String s =c.test1("sss");
}
}
class Cc<E> {
private E e;
/**
* 静态方法的泛型
*/
public static void tt() {
//静态方法中无法使用类定义的泛型,如果使用参考下面ttt方法
}
public static<T> void ttt(T t) {
System.out.println(t); //静态方法的泛型
}
public <T>void test(T s) { //无返回值的方法
T t =s;
System.out.println(this.e);
}
public<T> T test1(T s) { //有返回值的方法
return s;
}
public void test2(String...strs) { //可变参数的方法
for(String s:strs) {
System.out.println(s);//for each遍历,取strs的值赋给s
}
}
public <T>void test3(T...strs) { //可变参数的方法
for(T s:strs) {
System.out.println(s);//for each遍历,取strs的值赋给s
}
}
}
通配符
import java.util.ArrayList;
import java.util.List;
public class Test2 {
public static void main(String[] args) {
Dd d =new Dd();
List<String>l =new ArrayList<String>();
d.test(l);
List<Integer>ll =new ArrayList<Integer>();
d.test(ll);
}
}
class Dd{
public void test(List<?>list) {//test方法一个list集合参数,不确定集合中的元素具体的数据类型
}
}
有限制的通配符
<? extends Person> (无穷小 , Person] 只允许泛型为Person及Person子类的引用调用 <? super Person > [Person , 无穷大) 只允许泛型为Person及Person父类的引用调用 <? extends Comparable> 只允许泛型为实 现Comparable接口的实现类的引用调用