Java编程思想之泛型小结

看这一章花了好些时间,直到现在依然有一些不明朗的地方。如果有个人认识不正确的地方,烦请指出。
1.[quote]有许多原因促成了泛型的出现,而最引人注目的一个原因,就是为了创造[b]容器类[/b]。[/quote]

class Automobile {}
public class Holder1 {
private Automobile a;
public Holder1(Automobile a) {this.a = a;}
public void set(Automobile a) { this.a = a; }
public Automobile get() { return a; }
}
这个类持有一个Automobile类型的对象a,但重用性很差,如果要持有其他非Automobile类型需重写。

public class Holder2 {
private Object a;
public Holder2(Object a) { this.a = a; }
public void set(Object a) { this.a = a; }
public Object get() { return a; }
}
这个类持有Object类型的对象a,但可以往里随意set各种类型的对象。但我们只需要持有一种特定类型,并且想保证类型的正确性,所以请用泛型吧。

public class Holder3<T> {
private T a;
public Holder3(T a) { this.a = a; }
public void set(T a) { this.a = a; }
public T get() { return a; }

public static void main(String[] args) {
Holder3<Pet> h3 = new Holder3<Pet>(new Cat());
h3.set(new Dog());
Pet a = h3.get();
}
}
这个类持有的是T类型的对象a,当创建Holder3对象时,只需告诉编译器要使用Pet类型。并且当h3对象被创建出来,它就只能持有Pet类型或其子类型,如本例中的Cat和Dog,但你不能给它set People类型的对象,即编译器会做类型检查。

2.Java泛型局限之一,基本类型无法作为类型参数。但可以使用包装类型,与基本类型进行转换。

3.关于擦除:
[quote]在泛型代码内部,无法获得任何有关泛型参数类型的信息[/quote]举个例子就是new ArrayList<String>().getClass()与new ArrayList<Integer>().getClass()所得到的是相同的实例。
[quote]Java泛型是使用擦除来实现的,这意味着当你在使用泛型时,任何具体的类型信息都被擦除了,你唯一知道的就是你在使用一个对象。因此List<String>和List<Integer>在运行时事实上是相同的类型。这两种形式都被擦除成它们的“原生”类型,即List。[/quote]

4.关于边界:
[quote]边界使得你可以再用于泛型的参数类型上设置条件。[/quote]
因为擦除了类型信息,所以类似List<T>这种无界泛型参数的写法实际运行时只认为参数是一个Object类型。设置泛型边界使用[b]extends[/b]关键字,如:class Colored<T extends HasColor>。

5.关于通配符“?”:
假设有如下的类继承关系:
class Fruit {}
class Apple extends Fruit {}

在泛型的使用中,却不能这样初始化:List<Fruit> list = new ArrayList<Apple>();
这里用个人做的练习28的代码来理解用法,注意里面关键字super和extends的使用:
class GenericSet<T> {
public void setMethod(T param) {
}
}

class GenericGet<T> {
private T param;
public T getMethod() {
return param;
}
}

public class Practise28 {

static <T> void setMethod(GenericSet<? super T> param, T item ) {
param.setMethod(item);
}

static <T> void getMethod(GenericGet<? extends T> param) {
param.getMethod();
}

public static void main(String[] args) {
GenericSet<Fruit> individual1 = new GenericSet<Fruit>();
GenericGet<Fruit> individual2 = new GenericGet<Fruit>();
setMethod(individual1, new Apple());
getMethod(individual2);
}
}


6.关于自限定类型:
使用个人做的练习34的代码来理解(不要吐槽命名。。。):
abstract class MyAbstract<T extends MyAbstract<T>>
{
abstract T method(T i);

T invoke(T i) {
System.out.println(i.getClass().getSimpleName());
return method(i);
}
}

public class Practise34 extends MyAbstract<Practise34> {

public static void main(String[] args) {
System.out.println(new Practise34().invoke(new Practise34()));
}

@Override
Practise34 method(Practise34 i) {
return i;
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值