Java泛型疑难知识点备忘

Java泛型

关于泛型的知识点

JDK5引入的特性,为了解决使用Object强转带来的可读性问题,泛型的本质是将变量的类型参数化

泛型只在编译阶段有效,运行时擦除

静态方法中不能使用类的泛型,因为泛型引用在实例化时定义,而静态资源在实例化之前

泛型方法可以是静态的,因为它的泛型是调用方法时确定的,而不是实例化类时确定的

泛型有三种使用方法:泛型类,泛型方法,泛型

异常类不能是泛型

泛型的使用

泛型类

public class Map<K,V>{
    private K key;
    private V value;
    
    public Map(K key,V value){
        this.key = key;
        this.value = value;
    }
    public void setKey(K key){
        this.key = key;
    }
    public K getKey(){
        return key;
    }
    public void setValue(V value){
        this.value = value;
    }
    public V getValue(){
        return value;
    }
}

public class Test{
    public static void main(String[] args){
        Map<String ,String> map = new Map<>("key","value");
    }
}
//如果泛型类实例化时没有指名类的泛型,则默认为Object类
//建议实例化时要指名泛型

泛型接口

//接口
public interface Generator<T>{
    public T next();
}

public interface Generator<T1,T2>{
    public T1 next();
    public T2 next();
}
//继承接口,接口是泛型,实现时将泛型参数确定
//实例化时不需要指明泛型
public class StringGenerator implements Generator<String>{
    @Override
    public String next(){
        return "String";
    }
}
//接口泛型未声明,实现类也要标注泛型
public class SonOfGenerator<T> implements Generator<T> {
    parivate T next;
    public SonOfGenerator(T next){
        this.next = next;
    }
    public T next(){
        return next;
    }
}
//实现类部分保留接口的引用
public class SonOfGenerator2<T2> implements Generator2<String T2>{}
//接口确定了类型,但实现类又新定义了泛型引用
public class SonOfGenerator3<A,B> implements Generator2<Integer,String>{}
//接口泛型应用保留,实现类又新定义了泛型
public class SonOfGenerator4<T1,T2,A,B> implements Generator2<T1,T2>{}
//接口部分保留泛型引用,实现类又新定义泛型
public class SonOfGenerator5<T2,A,B> implements Generator2<Integer,T2>{}

//实例化
public class Test{
    public static void main(String[] args){
        Generator<String> generator = new SonOfGenerator<>("value"); 
        Generaotr<String> generaotr2 = new StringGeneraotr();
    }
}

泛型方法

public class Data<T>{
    private T data;
    //泛型方法的泛型参数和类泛型参数不同
    public <E> List<E> getList(E[] arr){
        ArrayList<E> list = ArrayList<E>();
        for(e:arr){
            list.add(e);
        }
        return list;
    }
}
通配符: ?

通配符的使用

//通配符解决的问题

public class Test{
    public void main(String[] args){
        List<String> list1 = null;
        List<Integer> list2  = null;
        
        //下面语句编译时会报错
        //list1 = list2;
        
        //解决问题
        List<?> list = null;
        list = list1;
        list = list2;
        
        //通配符的泛型类不能添加数据,除了null
        list。add(null);
        //以下代码报错
        //list.add("aa");
        
       
        
        
    }
}

有限制的通配符

public class Test{
    public static void main(String[] args){
         
        
        //有限制的通配符
        //?可以是子类,也可以是本类()
        List<? extends Person> list1 = null;
        //?可以是本类,也可以是父类
        List<? super Person> list2 = null;
        
        //Student extends Person
		List<Person> list3 = new ArrayList<Person>();
        List<Student> list4 = new ArrayList<Student>();
        List<Object> list5 = new ArrayList<Object>();
        
        //下列赋值  不报错
        list1 = list3;
        list1 = list4;
        //下列赋值  报错
        list1 = list5;
        list2 = list3;
        //下列赋值  不报错
        list2 = list4;
        list2 = list5;
        
        //读取数据
        list1 = list3;
        Person person = list1.get(0);
        //下列赋值  报错
        Student student = list1.get(0);
        
        list2 = list4;
        Object obj = list2.get(0);
        //下列赋值  报错, ?有可能比Person更大
        //Person person = list2.get(0);
        
        //写入数据
        //下面代码  报错: ?可能是student的子类
        //list1.add(new Student());
        
        //不报错
        list2.add(new Person());
        //<? super Person> 限制传入对象必须是person及其父类,但传入数据可以是person子类
        list2.add(new Student());
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值