java基础--泛型

        泛型是将数据类型参数化以达到代码复用提高程序开发效率的一种特性。java泛型的提出是针对List集合存入对象时不会记忆数据类型,再次取出对象时就变成object类型而提出的一种解决方式。因此泛型的应用在底层代码封装中广泛使用。


    自java 5以后,java引入参数化类型概念,使用泛型,例如:List<String>,表明该集合只能存储String对象。


    先看一下泛型类的定义:

public class Apple<T>
{
	private T info;
	public Apple(){
		
	}
	public Apple(T info){
		this.info=info;
	}
	
	public void setInfo(T info){
		this.info=info;
	}
	
	public T getInfo{
		return this.info;
	}
	
	public static void main(String[] args){
		Apple<String>a1=new Apple<>("苹果");//泛型的菱形定义
		System.out.println(a1.getInfo());
		
		Apple<Double>a2=new Apple<>(5.66);
		System.out.println(a2.getInfo());
	}
}


    该泛型类的定义是在类定义后面使用尖括号<>引入参数。使用时传入了String,则a1就只能保存String对象;传入Double,则a2只能保存Double数据。


    (1)泛型的继承必须要明确指明存储的数据类型,且泛型集合类不能使用静态方法,例如:

public class A1 extends Apple<String>{...}

    如果上面的apple改成Apple<T>则编译时是无法通过的。


    (2)泛型的“父类”可以通过通配符来表示,通常用作限定通配符,例如:

        public abstract class Person{
		public abstract void work();
	}
	public class man extends Person{
		public void work(){
			System.out.println("男人的工作");
		}
	}
	public class womman extends Person{
		public void work(){
			System.out.println("女人的工作");
		}
	}
	
	public class PepoleWork{
		public void doWork(List<? extends Person> persons){   //限定通配符只能是person,在方法类中定义具体的类
			for(object obj :persons){
				Person p=(Person)(obj);
				p.work();
			}
		}
	}


    这样,通过List<? extends Person>作为限定,则doWork方法将传入参数限定在Person类以及它的子类当中,不能传入其他类型参数。


    当需要限定多个参数类型时则可以通过&进行连接:

public class Apple<T Number & java.io.Serializable>
	{
		...;
	}


   (3)泛型方法:

//将指定的数组转化为集合
	static <T> void formArrayToCollection(T[]a,Collection<T> c){
		for(T o:a){
			c.add(o);
		}
	}
	
	public static void main(String[] args){
		Object[] oa=new Object[100];
		Collection<object> co=new ArrayList<>();
		formArrayToCollection(oa,co);
		
		String[] sa=new String[100];
		Collection<String> cs=new ArrayList<>();
		formArrayToCollection(sa,cs);
		
	}

    如上面的实例,将数组转化为集合,泛型方法定义时在返回类型前面多了一个类型参数。该方法可以将多种类型的数组转化为集合。


    当两个转化参数不一致时必须有参数继承关系,如下实例:

public class RightTest
	{
		static <T> void test(Collection<? extends T>form,Collection<T> to){
			for(T ele:form){
				to.add(ele);
			}
		}
public static <T> T copy(Collection<? super T> dest,Collection<T> src){
		T last=null;
		for(T ele:src){
			last=ele;
			dest.add(ele);
		}
		return last;
	}
		
		public static void main(String[] args){
			List<object> ao=new ArrayList<>();
			List<String> as=new ArrayList<>();
			
			//String类型集合转化为Object类型集合
			test(as,ao);
		}
	}


    该方法将String类型集合转化为Object类型集合。


    (4)泛型集合与通配符的关系


     一般情况下通配符均可以转化为泛型方法,例如:

public interface Collection<E>
	{
		boolean containsAll(Collection<?> c);
		boolean addAll(Collection<? extends E>c);
	}
	
	/*类型形参T只使用一次,则应该使用通配符:支持灵活的子类化*/
	public interface Collection<E>{
		<T> boolean containsAll(Collection<T> c);
		<T extends E>boolean addAll(Collection<T> c);
	}

    当类型参数只使用一次时,应该使用通配符:支持灵活的子类化;一个类型参数a或者返回值类型依赖于另一个形参b的类型,则考虑泛型方法,例如java里面Collections类的copy()方法:

public class Collections{
		public static<T>void copy(List<T> dest,List<? extends T> src){...};
	}


    根据上面实例的展示,泛型的使用能够为java类和方法提供更好的封装。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 21
    评论
评论 21
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值