Java笔记(9)-泛型和通配符简要介绍

1.泛型的简单介绍和使用

  • 泛型是JDK1.5之后增加的,可以用来建立类型安全的集合;
  • 什么是类型安全的集合?就我看来,就是说只能使用某一个指定了的类,而不能使用其他类的对象;
  • 在使用自定义的泛型时,也就是在类中声明时,一般使用<T,E,V>。当然也可以用其他的字母来表示,但是最好还是用这些常用的字母;
  • 泛型的<>中存放的是包装类,所谓的包装类,就是将基本类型进行装箱后的一种Java类;比如像是Integer,Short,等总计8个;我前面博客有介绍;
public class TextGeneric {
	
	public static void main(String[] args) {
		Animal<String> ani= new Animal<String>();//在这里面定义该类中规定的类型为String
		Animal<String> ani1 = new Animal<String>();//那么这些对象中后面所有方法引入的也必须是这个String类型;
		ani.setName("dog");
		ani1.setName("cat");
//		ani.setName(123);//如果定义的类型与前面的String不同就无法写入;会报错;
		System.out.println(ani1.getName());
	}
}

class Animal<E>{//定义一个带泛型的类,当然如果想多带一个参数类型,只需要在后面再添一个,如Animal<E,V>;
	private E name;
	
	public E getName() {
		return name;
	}
	public void setName(E name) {
		this.name = name;
	}
	public Animal() {
	}
}

这个基本就是泛型的使用方法;

2.了解基础的通配符

首先通配符的使用是在了解泛型的基础上,能熟练使用通配符,不说多的,至少代码的简洁性一定有,至于其它相关的东西,边学边记录吧;

public class TestTo {
    public static void main(String[] args) {
//        首先定义两个ArrayList的对象;
        List<String> list = new ArrayList<>();
        List<Object> list1 = new ArrayList<>();

//        分别给两个对象添加一些东西;
        list.add("string");
        list.add("神");
        list1.add("神秘的天");
        list1.add("sdd");

        //通过调用下方使用了通配器的方法;迭代输出list和list1中的值
        new TestTo().show(list1);
        new TestTo().show(list);

    }

    //在这里就可以使用通配符,
    public void show(List<?> list) {
        //  当然是用for循环更简单,但是使用一下迭代器输出,就当回顾之前的知识吧;
        Iterator<?> iterator = list.iterator();
        while(iterator.hasNext()){
            Object o = iterator.next();
            System.out.println(o);
        }
 /*       for (Object o : list) {
            System.out.println(o);
        }*/
    }
}

运行结果:
在这里插入图片描述
如上例在通配符中,List<?>这个其实属于List<Object>和List<String>的一种父类吧,所以就像是利用了多态一样;这样就不需要重载几个方法了;我这里只是通过方法显示了通配符的用处,其实按道理,有很多的地方都可以用到通配符;而且为什么不直接使用List<Object>代替List<?>,那是因为,List<String>其实并不继承List<Object>;

最后需要注意的是,如下图:如果定义了一个这样的list,那么list后面不能添加其它的数据;比如;

List<?> list;
//list.add("dd");这是错误的写法;最多就只能把list置空;
//比如下面:
list=null;

2.1有限制条件的通配符

有限制条件的通配符主要是指就像是给大小进行判断一样,比如前面只有<?>的时候,可以看做是没有范围,什么泛型都可以是它的子类;但是当如下时<? extends TestClose>的子类泛型就必须是TestClose的子类;怎么了解呢,我们通过多态的赋值进行解释;如下程序;

public class TestClose {
    public void test() {

        //这里定义一下这两种类型的通配符;
        List<? super TestClose> list1 = null;//看意思大致是TestClose的父类;
        List<? extends TestClose> list2 = null;//这里可能是继承自TestClose的子类;

        List<Test> list3 = null;//定义比较类;
        List<TestClose> list4 = null;
        List<Object> list5 = null;

        //通过赋值就可以知道这些通配符的含义;
        //list1=list3;只有这个赋值给list1的时候报错,由此证明list1只能接受比他TestClose大的父类或等于它;
        list1 = list4;
        list1 = list5;

        list2 = list3;
        list2 = list4;
        //list2=list5;这个赋值的时候报错,也由此知道list2只能接受TestClose的子类或者它本身的泛型;
    }

}

class Test extends TestClose {
}

以下程序主要稍微详细的理解一下限制性的通配符:

   public static void main(String[] args) {
        List<? super Person> list1 = new ArrayList();
        list1.add(new Person("dss"));//可以插入
        Object l = list1.get(0);//可以取值,但不能确定值的类型;只能用最大的object修饰;
        System.out.println(l.toString());

        List<? extends Person> list =new ArrayList<>();
//       list.add(new Person());这是错的,但其实在我之前的理解,我一直以为它是对的;为什么错误,下面解释;
        Person p = list.get(0);//相较于上面取值的广泛,在这里取值的时候范围更加明确;
        List<Person> list3;
    }

首先就是在<? extends A>中,可以这样看,那个?的大致范围是要继承A类的;那么在List的容器中,就只有比它小的类的对象才能放进去;但是这个很小的类是不明确的,所以使用add方法添加值的时候,就只能添加null,否则程序本身就会报错;

为了让自己下次复习的时候看不懂,我还是简单的再讲讲自己的想法;
首先List<? extends A>,我们假设B继承A,那么?就可以用B来代替是吧,然后就是在容器中,使用add方法时;你所添加的按照多态来说你,你最大的类都不过是A,而且极有可能取到的类是A的子类,那么如果我们按最大的来添加,也最多list.add(new A());何况我们根本无法确定它的准确取值,这样我们是无法add的,这就是为什么上面的添加会报错的终极原因;

猜你喜欢

转载自blog.csdn.net/dxsdcyy/article/details/105317456