第十五章:泛型(伪泛型)

一般的类和方法,只能使用具体的类型:要么是基本类型,要么是自定义的类。如果要编写可以应用于多种类型的代码,这种刻板的限制对代码的束缚就会很大。
关键字:伪泛型,泛型擦除

1.简单泛型

在JavaSE5之后,出现了泛型。从而使容器类和引用类型数组的编译更加的合理化,减少后期类型转化的错误。
package com.myboy.generic;
import java.util.ArrayList;
import java.util.List;
public class Test1 {
public static void main(String[] args) {
List<String> list=new ArrayList();//debug list=ArrayList<E>;E的概念很重要
}
}

2.泛型接口

泛型引用于接口。比如生成器(generator),这是一种专门负责创建一类类型对象的类。
package com.myboy.generic;

import java.util.Iterator;
import java.util.Random;

interface Generator<T> {
T next();// 返回参数T
}

class Mike {// 基类
private static long counter = 0;
private final long id = counter++;

@Override
public String toString() {
return getClass().getSimpleName() + "-----" + id;
}
}

class A extends Mike {
}

class B extends Mike {
}

class C extends Mike {
}

class D extends Mike {
}

class E extends Mike {
}

class MikeGenetaor implements Generator<Mike>, Iterable<Mike> {
private Class[] types = { A.class, B.class, C.class, D.class, E.class, };
private static Random rand = new Random(47);

public MikeGenetaor() {
};

private int size = 0;

public MikeGenetaor(int sz) {
size = sz;
}

@Override
public Iterator<Mike> iterator() {// 迭代器设计模式
return new MikeIterator();
}
private class MikeIterator implements Iterator{//内部类的研究,真的java有点牛逼
int count=size;
@Override
public boolean hasNext() {
return count>0;
}

@Override
public Object next() {
count--;
return MikeGenetaor.this.next();//调用外部类
}

@Override
public void remove() {//暂时不实现这个方法
}
}
@Override
public Mike next() {
try {
return (Mike) types[rand.nextInt(types.length)].newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}catch(Exception e){
throw new RuntimeException();
}
return null;

}
}
public class Test4{
public static void main(String[] args) {
MikeGenetaor mg=new MikeGenetaor();
for(int i=0;i<5;i++){
System.out.println(mg.next());
}
for(Mike m:new MikeGenetaor(5)){//MikeGenetaor实现的接口是<Mike>泛型
System.out.println(m);
}
MikeGenetaor mgg=new MikeGenetaor(5);
for(Iterator<Mike> it=mgg.iterator();it.hasNext();){//测试迭代器模式
System.out.println(it.next());
}
}
}
3.泛型方法
在一个类中存在参数化方法,那么这个类可能是泛型类,也可能不会泛型类。
package com.myboy.generic;

import java.util.HashMap;
import java.util.Map;

public class Test3 {
public static <K,V> Map<K,V> newmap(){//泛型方法
return new HashMap<K,V>();
}
public <T> void f(T x){//泛型方法
System.out.println(x.getClass().getSimpleName());
}
public static void main(String[] args) {
Test3 t3=new Test3();
t3.f(1);
t3.f("SS");
t3.f(1d);
}
}
----
package com.myboy.generic;

import java.util.ArrayList;
import java.util.List;

public class Test2 {
public static <T> List<T> make(T...args){//泛型方法
/**
* 可变参数方法,直接可进行for()???
*/
List<T> list=new ArrayList<T>();
for(T t:args){
list.add(t);
}
return list;
}
public static void main(String[] args) {
List<String> list=new ArrayList<String>();
list=Test2.make("ssss");
System.out.println(list);//out ssss
list=Test2.make("aaaaaaaaaaaaaadfsasdfasf".split(""));
System.out.println(list);//out [, a, a, a, a, a, a, a, a, a, a, a, a, a, a, d, f, s, a, s, d, f, a, s, f]
}
}

4.泛型事项

不管泛型用在那里,最好的操作是尽量是泛型所存在的范围大一点,除非知道确切的类型信息。

5.泛型擦除(伪泛型特点)

用多了泛型之后,必须承认的事实是:在泛型代码运行的时候,并不会得到所有泛型的类型信息。
package com.myboy.generic;
import java.util.ArrayList;
public class Test5 {
public static void main(String[] args) {
Class claz1=new ArrayList<String>().getClass();
Class claz2=new ArrayList<Integer>().getClass();
System.out.println(claz1==claz2);//out true;
/**
* claz1 和 claz2的泛型信息都被擦除了,泛型类Class<T>
*/
}
}
泛型的存在方便后后期的类型转化和编译时期的代码优化

6.擦除的补偿,边界(了解)

因为泛型被擦除,所以可以用无界泛型参数调用的方法,只是可以调用Object所调用的方法。但是如果能将类型设计在某个基类的本身及其子类,那么就可以用到其基类的方法。java中用extends来处理泛型的下一步。
package com.myboy.generic;
interface Hzhulu{
String getString();
}
class Hhaha<T extends Hzhulu>{
private T t;
public String getString(){
return t.getString();//此处并没有报错,而且还可以调用getString();
}
}
public class Test6 {

}

7.通配符(?)

8.泛型所要注意的问题

1.基础类型不能作为泛型信息,当可以用包装类去操作
2.一个类不能同时继承或实现不同泛型的信息
3.转型和警告:使用带有泛型类型的转型或Instanceof不会有任何效果。可以将内部将各个值存储为Object,并在获取这些值时,再将他们转型回T。
4.重载
public class UserList<W,t>{
void f(List<T> v){};
void g(List<W> v){};
}

9.动态类类型安全

因为可以向JavaSE5之前的代码传递泛型容器,所以旧式代码依依旧可能会破坏你的容器。Java SE5的java.util.Collentions中有静态方法,checkedCollecction(),checkList,checkMap,checkSet()....;
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值