Java泛型(笔记20)

Java泛型

一、泛型概述

泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。 Java语言引入泛型的好处是安全简单。
jdk 1.5 以后出现的特性
泛型的好处:
1) 提高安全性,把运行时可能出现的问题,转到在编译期就能发现
2) 可以省去强转的麻烦

二、泛型应用 

//例一,不使用泛型带来的问题
下面的c 在声明的时候,没有使用泛型,所以什么类型都可以存入
  Collection c=new ArrayList(); //Collection is a raw type. References to generic type Collection<E> should be parameterized  泛型参数化
  c.add("中国");
  c.add(789);
  c.add(true);
  c.add(new Student());  
  
  Iterator it=c.iterator();
  while(it.hasNext()){
  System.out.println(((String)it.next()).length());  //可能出错,遇到非String类型,出现异常
  }

//例二,使用泛型
public class Test {
public static void main(String[] args) {
TreeSet<String> ts=new TreeSet<String>( new StrLenComp() );
ts.add("dsdgfhf");
ts.add("sdf");
ts.add("54");
ts.add("ghgjgh");
ts.add("s");
ts.add("565rthdfgdfg");
Iterator<String> it=ts.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
}

class StrLenComp implements Comparator<String>{
public int compare(String o1, String o2) {
return o1.length()-o2.length();  //会去重
}
}

三、自定义泛型类

泛型类,在定义类的时候,声明泛型,例如
class Dog<T> 
以后在类体中的任意位置(静态成员,方法,代码块除外),就可以把T当做一个类型使用了

//例一
public class Test {
public static void main(String[] args) {
Cat<String> c=new Cat<String>();
c.test1("中国", 90);
//c.test1(89, 90);  不可以
c.setObj("法国");
String str=c.getObj();
System.out.println(str);
Cat<Integer> nc=new Cat<Integer>();
nc.test1(80,90); //ok
//nc.test1("中国",90); 出错
nc.setObj(900);
//nc.setObj("字串");  不行
Integer result=nc.getObj();
System.out.println(result);
}
}

class Cat<T>  {
T obj;
public void test1(T param1, int a){
System.out.println("传进来的第一个参数是"+param1);
System.out.println("传进来的第二个参数是"+a);
}
public void setObj(T t){
this.obj=t;
}
public T getObj(){
return this.obj;
}
}

//例二 使用多个泛型
public class Test {
public static void main(String[] args) {
Cat<String,Integer,Person> cat=new Cat<String,Integer,Person>();
cat.test1("中国",80,new Person());
}
}

class Cat<S,V,K>  {
S obj;
public void test1(S param1, V a, K k){
System.out.println("传进来的第一个参数是"+param1);
System.out.println("传进来的第二个参数是"+a);
System.out.println("传进来的第三个参数是"+k);
}
public void setObj(S t){
this.obj=t;
}
public S getObj(){
return this.obj;
}
}
class Person{
}


四、泛型方法

//例一
class Cat {
//静态方法不能访问类上的泛型,所以静态方法的泛型,要在方法上直接声明
public static <T> void test(T  p1, T p2){
System.out.println("参数一是:"+p1);
System.out.println("参数一是:"+p2);
}
/*
public <S> S  getOjb(){
return new S();  //出错,声明为泛型的类型,是不能new的,因为编译器没有办法在编译的时候读取S对应的字节码文件
}
*/
public <S> S  getOjb(Class<S> clazz){
try {
return clazz.newInstance();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}

//例二
public class Test {
public static void main(String[] args) {
Dog dog=new Dog();
dog.wangwang("汪汪汪", 9999);
}
}

class Dog{
//泛型方法
<T,S> void wangwang(T t, S s){
System.out.println("第一个参数是"+t);
System.out.println("第一个参数是"+s);
}
}

五、 泛型接口

//泛型接口
interface UserDao <U,N,P>{
public U getUser(N name, P password);  
}

//使用上面的泛型接口
class UserDaoImpl implements UserDao<UserInfo,String,Integer>   {
public UserInfo getUser(String name, Integer password) {
return new UserInfo();
}
}

class UserInfo{
}

六、 泛型限定

 
1) 泛型限定上限 <? extends E>   //表示可以接收 E 或 E 的子类型
2) 泛型限定下限 <? super E>     //表示可以接收 E 或 E 的父类型
? 表示所有的
 
例一 泛型限定上限
public class Test {
public static void main(String[] args) {
List<Person> list1=new ArrayList<Person>();
test(list1);
List<Student> list2=new ArrayList<Student>();
test(list2);
}
static void test(List <? extends Person>list){
}
}

class Person{
}

class Student extends Person{
}
 
例二 泛型限定下限  
public class Test {
public static void main(String[] args) {
/*List<Person> list1=new ArrayList<Person>();
test(list1);
List<Student> list2=new ArrayList<Student>();
test(list2);*/
List<Object> list2=new ArrayList<Object>();
test2(list2);
List<Person> list3=new ArrayList<Person>();
test2(list3);
}
//表示传过来的list中的类型必须是Person或它的子类
static void test(List <? extends Person>list){  //对于上限限定来说,不能进行add这类的添加操作
//list.add(new Person());  //编译通不过
}
//表示传过来的list中的类型必须是Person 或其父类
static void test2(List <? super Student>list){  //对于下限限定来说,可以进行add操作
list.add((Student)new Person());  //OK
list.add(new Student());  //OK
}
}

class Person{
}

class Student extends Person{
}

七、关于   <?>

/*static <T> void show(Student <T> stu){
}*/
上面的写法,尽量用 下面的表示
static   void show(Student <?> stu){
}

猜你喜欢

转载自blog.csdn.net/weixin_41205479/article/details/80222040