泛型

泛型(Generic)

所谓泛型:就是变量类型的参数法

  • 泛型是JDK1.5中一个最重要的特征。通过引入泛型,我们将获得编译时类型的安全和运行时更小地抛出ClassCastExceptions的可能。

泛型之前

  • 类别定义时的逻辑完全一样,只是里面成员变量的类型不同
  • 如果需要多个相似的类,需要定义多个文件,不同的只是变量的类别,而逻辑是完全一样的
  • 对之前代码的一些改写
    例1
public class GenericFoo<T>
{
	private T foo;
	
	public T getFoo()
	{
		return foo;
	}

	public void setFoo(T foo)
	{
		this.foo = foo;
	}

	public static void main(String[] args)
	{
		//foo1 里面成员变量是Boolean类型
		GenericFoo<Boolean> foo1 = new GenericFoo<Boolean>();
		//foo1 里面成员变量是Integer类型
		GenericFoo<Integer> foo2 = new GenericFoo<Integer>();
		
		foo1.setFoo(new Boolean(false));
		foo2.setFoo(new Integer(3));
		
		Boolean b = foo1.getFoo();
		Integer i = foo2.getFoo();
		
		System.out.println(b);
		System.out.println(i);
		
		//foo1 = foo2;
		
		GenericFoo a = new GenericFoo();
		
		a.setFoo("hello");
		
		String str = (String)a.getFoo();
		
		System.out.println(str);
	}
}

例2

public class Generic<T1, T2>
{
	private T1 foo1;
	
	private T2 foo2;

	public T1 getFoo1()
	{
		return foo1;
	}

	public void setFoo1(T1 foo1)
	{
		this.foo1 = foo1;
	}

	public T2 getFoo2()
	{
		return foo2;
	}

	public void setFoo2(T2 foo2)
	{
		this.foo2 = foo2;
	}
	
	public static void main(String[] args)
	{
		Generic<Integer, Boolean> foo = new Generic<Integer, Boolean>();
		
		foo.setFoo1(new Integer(-20));
		foo.setFoo2(new Boolean(false));
		
		System.out.println(foo.getFoo1());
		System.out.println(foo.getFoo2());
	}

使用泛型编写一个简易版AraayList

public class SimpleCollection<T>
{
	private T[] objArr;
	
	private int index = 0;
	
	public SimpleCollection()
	{
		objArr = (T[])new Object[10];  
	}
	
	public SimpleCollection(int capacity)
	{
		objArr = (T[])new Object[capacity];
	}
	
	public void add(T t)
	{
		objArr[index++] = t;
	}
	
	public int getLength()
	{
		return this.index;
	}
	
	public T get(int i)
	{
		return objArr[i];
	}
	
	public static void main(String[] args)
	{
		SimpleCollection<Integer> c = new SimpleCollection<Integer>();
		
		for(int i = 0; i < 10; i++)
		{
			c.add(new Integer(i));
		}
		
		for(int i = 0; i < 10; i++)
		{
			Integer in = c.get(i);
			
			System.out.println(in);
		}
		
	}
	

限制泛型的可用类型

  • 在定义泛型类别时,预设可以使用任何的类 型来实例化泛型类型中的类型,但是如果想要限制使用泛型类别时,只能用某个特定类型或者是其子类型才能实例化该类型时,可以在定义类型时,使用extends关键字指定这个类型必须是继承某个类,或者实现某个接口
  • 参见程序 ListGenericFoo.java
  • 没有指定泛型继承的类型或接口时,默认 使用T extends Object,所以默认情况下任 何类型都可以作为参数传入
  • 使用<?>或是<? extends SomeClass> 的声明方式,意味著您只能通过该名称來 取得所参考实例的信息,或者是移除某些信息,但不能增加它的信息,因为只知 道当中放置的是SomeClass的子类,但不 确定是什么类的实例,编译器不让您加入 信息, 理由是,如果可以加入信息的話, 那么您就得記得取回的实例是什么类型, 然后转换为原來的类型方可进行操作,这 就失去了使用泛型的意义
public class ListGenericFoo<T extends List<String>> {//限制的泛型时也可以有泛型
    private T[] fooArray;

    public T[] getFooArray() {
        return fooArray;
    }

    public void setFooArray(T[] fooArray) {
        this.fooArray = fooArray;
    }

    public static void main(String[] args) {
        ListGenericFoo<LinkedList<String>> foo1 = new ListGenericFoo<LinkedList<String>>();
        ListGenericFoo<ArrayList<String>> foo2 = new ListGenericFoo<ArrayList<String>>();

        LinkedList[] linkedList = new LinkedList[10];
        LinkedList<String> list = new LinkedList();
        list.add("asd");
        linkedList[1] = list;
        foo1.setFooArray(linkedList);

        ArrayList[] arrayList = new ArrayList[10];

        foo2.setFooArray(arrayList);

        //ListGenericFoo<HashMap> foo3 = new ListGenericFoo<HashMap>();

    }


}
		
	}

例3


public class GenericTest<T> {
    private T foo;

    public T getFoo() {
        return foo;
    }

    public void setFoo(T foo) {
        this.foo = foo;
    }
    //<T> 声明为泛型方法
    public <T> Map<String, T> setFoos(T foo) {
        Map<String, T> map = new HashMap<>();
        map.put("cx", foo);
        return map;
    }


    public static void main(String[] args) {


        GenericTest<? extends List> ge = null;

        ge = new GenericTest<ArrayList>();
        ge = new GenericTest<LinkedList>();

        //泛型方法 传什么T就是什么类型
        Map<String, String> map = ge.setFoos("asd");

        //ge = new GenericTest<HashMap>();
        //泛型层次在List之上
        GenericTest<? super List> ge2 = null;

        ge2 = new GenericTest<Object>();

        GenericTest<String> ge3 = new GenericTest<String>();
        ge3.setFoo("hello world");

        GenericTest<? extends Object> ge4 = ge3;

        System.out.println(ge4.getFoo());

        ge4.setFoo(null);

        System.out.println(ge4.getFoo());
		/*
			此时ge4的类型约定是Object及以下此时set进去值是String类型
			我们在取的时候包含Object类型,String类型是Object类型子类却
			能取出来String的父类此时就需要强制类型转换就失去了泛型的意义
		 */
        //ge4.setFoo("welcome");


    }
}

在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值