java 方法泛型参数_1.4 常用的泛型:使用泛型参数来编写方法

1.4  常用的泛型:使用泛型参数来编写方法

Java5+

前面的小节介绍了泛型可以简化Java代码并使代码能够防范ClassCastException错误。除了作为JDK的一部分来使用泛型之外,还可以编写你自己的泛型。当对类型相同的对象进行操作时泛型是很有用的,但是对象的具体类型直到对类实例化时才能知道。这种方式非常适合于包含关联项目的集合或涉及查找的类。

下面编写一个使用泛型参数的方法。回想一下前面是怎样使用ArrayList类的—— 只在构造ArrayList时才指定它使用哪些对象类型。注意,在定义类时并不知道其类型,并且不能将java.lang.Object作为类型使用,因为最后将遇到类似以前的类型强制转换问题。当定义泛型时,必须使用一种特殊的语言来代表类型。当声明类名时要完成此操作。在下面的示例中,表示一种类将使用的类型:

public class RandomSelection { }

这里,类型指示符的尖括号看起来类似HTML语法,但实际上和HTML没有关系,它们也不表示小于或大于!尖括号在一个泛型的类名与一个类型相结合的情况下使用,正如前面的ArrayList那样。尽管直到调用构造函数时才知道真实的类型,但我们可以在方法定义中使用替换类型。假定定义了一个叫做RandomSelection的类,该类使用另一个类的某个类型,暂时将该类型称为T。但是,此类的名字仍是RandomSelection。另外,每次可以对多个类型执行这种操作,正如java.util.Map的定义所示的那样。在这种情况下,在类名之后使用一个由逗号分隔的标识符列表即可。

public class MyGeneric { }

上面定义的MyGeneric类涉及到三个类型,它们分别称为T、U和V。下面编写一个方法来扩展RandomSelection类,该方法将一个项目添加到一个由内部管理的泛型(类型为T)的ArrayList中:

public class RandomSelection {

private ArrayList list;

public RandomSelection() {

list = new ArrayList();

}

public void add(T element) {

list.add(element);

}

}

注意,实际上并不是处理一个叫作T的类。T代表当某人创建RandomSelection的一个实例时使用的任意类。Java规范允许使用任意标识符,但是一般是使用单个大写字母来和普通的类名进行区别。既然已经定义add方法接受一个类型T参数,则只能使用在构造RandomSelection实例时采用的相同的类型来调用此方法。以下的代码是非法的并会产生一个编译错误:RandomSelection rs = new RandomSelection();

rs.add(new Date()); // illegal for a RandomSelection

如果希望一个方法返回一个泛型类型,可以将方法签名的返回类型设为T,正如下面的定义所示:

import java.util.Random;

public class RandomSelection {

private java.util.Random random = new Random();

// ..... earlier methods omitted

public T getRandomElement() {

int index = random.nextInt(list.size());

return list.get(index);

}

}

getRandomElement方法返回一个类型T,即与在类声明中定义的类型相同。通过构造一个类型实例,现在可以使用刚才定义的RandomSelection类:

RandomSelection selector = new RandomSelection();

selector.add(2);

selector.add(3);

selector.add(5);

selector.add(7);

selector.add(11);

Integer choice = selector.getRandomElement();

System.out.println(choice);

给一个整型变量choice赋值是安全的,因为selector的getRandomElement方法返回的总是一个Integer。情况确实如此,因为是使用Integer作为泛型类型来构造的selector实例。Add和getRandomElement方法的定义具有和构造函数的定义相同的类型,并且编译器将会强制执行此约束。尝试在构造函数中以一个不同的类型来使用RandomSelection类,这次使用前面定义的Fruit enum类:

RandomSelection fruitSelector = new RandomSelection();

fruitSelector.add(Fruit.APPLE);

fruitSelector.add(Fruit.ORANGE);

fruitSelector.add(Fruit.GRAPEFRUIT);

fruitSelector.add(Fruit.BANANA);

fruitSelector.add(Fruit.DURIAN);

Fruit fruitChoice = fruitSelector.getRandomElement();

System.out.println(fruitChoice);

可以看出,能够直接使用来自getRandomElement方法的Fruit返回值,正如前面对待Integer那样。如果你想要一个类与某种类型(直到构造该类时才知道具体的类型)的对象协同操作以及希望编译器严格执行类型限制,那么你可以定义自己的泛型。这样做的主要优点体现在它的安全和便利性上。若想了解有关泛型的更多信息,请查阅网址http:// java.sun.com/j2se/1.5.0/docs/guide/language/generics.html上的Generics Tutorial(泛型指南) 和Java 5文档。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值