泛型<E>

1. 泛型

  • 泛型:是一种未知的数据类型,当不知道会使用什么数据类型(或同一个方法可能接受不同数据类型),用泛型
  • 泛型也可以作为变量接受数据类型
  • E:未知的数据类型,即泛型,(在JAVA源码统一使用E,但其实可以是任意字母或单词)
  • 在创建对象时会确定泛型E的数据类型,并将数据类型作为参数传递,赋值给泛型E
  • 泛型没有继承的概念,< Integer >并不是< Object >的继承泛型
  • 泛型可以作为返回值,参数,数据类型,如:
    public class ArrayList< E >;
    public bollean add(E e);
    public E get (int index);
    

2. 不使用泛型创建集合

利:默认类型Object,可以存储任意类型
弊:不安全,可能引发异常
```java
 ArrayList list =new ArrayList();
 list.add("asd");//可以添加任意类型
 list.add(1);
 for (Object obj:list)
 {
     System.out.println(obj);
     //如果想使用String特有的方法,需要向下转型
     String s=(String)obj;
     System.out.println(s.length());
     //ClassCastException异常:类型转换异常
     //因为list中含有Integer类型数据,不能转换到String
```

3. 使用泛型创建集合

利:避免了类型转换,把运行期代码异常,提前到了编译器期
弊:只能存储单一类型数据

4. 自定义含泛型的类

加在类名之后
```java
package linxu.day17;
public class myEclass<E> {//在类名后加<E>,其内所有和此E相同的数据类型都有E替换
    private E name;
    public myEclass() {
    }
    public myEclass(E name) {
        this.name = name;
    }
    public E getName() {
        return name;
    }
    public void setName(E name) {
        this.name = name;
    }
}

package linxu.day17;

import java.util.ArrayList;
import java.util.Iterator;
public class demomain {
    public static void main(String[] args) {
        demo2();
    }
	public static void demo2(){
	    myEclass<String> str= new myEclass<>();//创建自定义泛型数据
	    str.setName("灵虚");
	    System.out.println(str.getName());
	}
}
```

5. 自定义含泛型参数的方法

泛型定义在修饰符和返回值之间,在调用方法时确定泛型的数据类型
格式:`修饰符 < E > 返回值 方法名(参数列表(泛型))`
必须在修饰符和返回值之间加上泛型符号,参数列表才能使用泛型作为参数
```java
package linxu.day17;
public class demomain {
    public static void main(String[] args) {
    method(1);
    method("sdc");
    }
    public static <M> void method(M m){
        System.out.println(m);
    }//这里是一个普通的方法;也可以在其他类中定义含泛型的成员方法,静态方法等等
}
```

6. 含泛型的接口

含有泛型的接口,有俩种使用方式
  1. 定义接口的实现类,同时指定泛型的数据类型
    //接口
    package linxu.day17;
    public interface myEinterface<I> {//在接口名后加泛型
        public abstract void method(I i);
    }
    //实现类
    package linxu.day17;
    public class myEimpl implements myEinterface<String>{//在实现类名后跟具体的泛型数据类型
        @Override
        public void method(String s) {
            System.out.println(s);
        }
    }
    //使用
    package linxu.day17;
    public class demo2 {
        public static void main(String[] args) {
            myEimpl m=new myEimpl();
            m.method("灵虚");
        }
    }
    
  2. 接口使用什么泛型,实现类也跟着接口(相当于定义含义泛型的类,创建对象时才确定数据类型)
    //实现类
    package linxu.day17;
    public class myEimpl2<E> implements myEinterface<E>{
        @Override
        public void method(E e) {
            System.out.println(e);
        }
    }
    //使用
    package linxu.day17;
    public class demo2 {
        public static void main(String[] args) {
            myEimpl2 m2=new myEimpl2();//不使用泛型,默认Object类型
            m2.method("灵虚天");
            m2.method(3.3);
            myEimpl2<Integer> m3=new myEimpl2();//创建对象时确定数据类型
            m3.method(666);
        }
    }
    

7. 泛型通配符

当使用泛型类或接口,传递的数据仍然不能确定数据类型,使用泛型通配符<?>
但是,一旦使用了泛型通配符,那么只能使用Objects的共性方法集合中元素自身的方法无法使用
但是泛型没有继承的概念,< Object >并不能表示接受所有数据类型

  1. 使用方法:
    不能创建对象使用,只能作为方法参数使用
  2. 示例:
    package linxu.day17;
    import java.util.ArrayList;
    import java.util.Iterator;
    public class demo3 {
        public static void main(String[] args) {
            ArrayList<Integer> arrayList1=new ArrayList<>();
            ArrayList<String> arrayList2=new ArrayList<>();
            arrayList1.add(1);
            arrayList1.add(2);
            arrayList2.add("王五");
            arrayList2.add("张三");
            myprint3(arrayList1);
            myprint3(arrayList2);
    
        }
        //泛型通配符作为参数
        public static void myprint3(ArrayList<?> list){
            Iterator<?> it =list.iterator();
            while(it.hasNext())
                 System.out.println(it.next());
        }
        
    }
    
  3. 泛型通配符作为参数和泛型作为参数
    public static void myprint3(ArrayList<?> list)//泛型通配符作为参数
    public static <M> void method(M m)//泛型作为参数
    //通过上面俩个例子,我们发现,泛型通配符作为参数一般是在使用集合,且集合在使用时传递数据类型不确定时使用,可以使用集合的方法
    //而泛型作为参数,只能对泛型做基本操作,即只能调用Objects类的方法
    
  4. 受限泛型——通配符的高级使用
    (1)泛型的上限
    格式:数据类型 <? extends 类>对象名
    意义:只能接受该类型及其子类
    (2)泛型的下限
    格式:数据类型 <? super 类>对象名
    意义:只能接受该类型及其父类
 public static void myprint3(ArrayList<? extends Object> list){//限制传入的参数只能是Object及其子类
        Iterator<?> it =list.iterator();
        while(it.hasNext())
             System.out.println(it.next());
    }
  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值