第二十七条:优先使用泛型方法

一、泛型方法的优点(一)

优点:泛型方法能够推断出输入参数中的参数类型
例:
public <E> E getType(E type){
  return type;
}
//当使用该方法的时候,虚拟机能够推断出输入的参数的类型是什么,并返回该类型。
举例:合并两个Set列表,用原生类型方法与泛型方法比较
//原生类型方法
public Set union(Set set1,Set set2){
    Set set = mew HashSet(s1);
    set.addAll(set2);
    return set;
}
使用原生类型方法虚拟机会出现类型不安全的警告。
//泛型方法
public <E> Set<E> union(Set<E> set1,Set<E> set2){
  Set<E> set = new HashSet<E>(set1);
  set.addAll(set2);
  return set;
}  
//由于虚拟机能够推断出输入参数的参数类型,所以E是已知的,不会出现类型不安全的警告。
使用:
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Set<String> firstSet = new HashSet<String>(
				Arrays.asList("Bady","Tim","Alice"));
		Set<String> secondSet = new HashSet<String>(
				Arrays.asList("Come","On","Go","With","Me"));
		Set<String> set = union(firstSet, secondSet);
		System.out.println(set);
	}

二、泛型的优点(二)

优点:能够推断出被赋值对象的类型参数。
例:泛型的静态工厂方法
	public static void main(String[]args){
		HashMap<String, String> map = newHashMap();
	}
	//泛型方法
	public static <K,V> HashMap<K,V> newHashMap(){
		return new HashMap<K, V>();
	}
这就是虚拟机能够根据被赋值对象的类型参数,推断出K,V的值是String,String。这样K,V就是已知类型。
我们以前写含有泛型的容器的时候都是:
HashMap<String,String> hashMap = new HashMap<String,String>();
在new 的时候还需要再重写一遍类型参数。一个两个还好,当数量多的时候呢。
所以利用泛型的静态工厂是一种方便的方法。

三、泛型的优点(三)

优点:能够推断出被赋值对象的类型。
是不是跟优点(二)有点像。不过这个是能够推断被赋值对象的类型,优点二则是推断被赋值对象的类型参数,不要弄混了。
例:
在Android中声明layout中的View到代码中的时候,都要使用(View)findViewById(R.id.xxx);
就像这样:Button btn = (Button)findViewById(R.id.xxx);每次有需要强制转换是一种很繁琐的事情。
我们可以这样构建一个方法
	public void onCreate(Bundle bundle) {
		// TODO Auto-generated method stub
		Button btn = getViewById(R.id.xxx);
	}
        //泛型方法
<span style="white-space:pre">	@SuppressWarnings("unchecked")</span>
	public <VT> VT getViewById(int id){
		return (VT)findViewById(id);
	}
因为虚拟机能够推断出被赋值对象的类型,也就是能够推断出VT为Button类型。这样VT就是确定的类型,就不会出现类型不安全的问题。这样就能放心的消除警告了

注:优点(二)(三)方法使用的基础,都是基于赋值给被赋值对象。如果没有被赋值对象,直接调用方法会发生什么情况呢?
就像这样:
  @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setView(getViewById(R.id.main_tv));//报错
    }

    //所有Button,等控件都是View的子类。
    //作用:将生成的View放入该方法中
    public void setView(View view){
        View myView = view;
    }


    public <VT> VT getViewById(int id){
        return (VT)findViewById(id);
    }
如果没有被赋值对象,虚拟机就无法进行判断,返回的类型就是Object,就是说getViewById()返回的是Object。
因为Object != View 所以肯定会出错

四、有限制的类型参数的特殊形式(递归的类型限制)
形式:<E extends Comparable<E>>
表述:可以与自身比较的E类
使用情形:一般用于Comparable类
例:求List容器中的最大值
	public <T extends Comparable<T>> T calculateMax(List<T> list){
		Iterator<T> iterator = list.iterator();
		T result = iterator.next();
		while (iterator.hasNext()){
			T t = iterator.next();
			//需要判断大小
			if (result.compareTo(t) < 0){
				result = t;
			}
		}
		return result;
	}







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值