另一博客镜像
Java可变参数列表,泛型方法,以及泛型中的extends,super,?等规则
http://www.blogjava.net/Carter0618/archive/2007/08/19/137889.html 这篇文章讲的也不错。
是Java SE5引进的新特性,
正如上面的那篇文章所提到:
a,当调用方法时,方法的参数的类型或个数未知,称之为可变参数列表。在以前的java
代码中用Object数组来实现,
b,对于类型未知,因为所有的类都继承自Object,那么用 Object的数组可解
c,对于个数未知,在Think In Java一书的P98,$5.8数组初始化有讲到:要定义一个数组,只需要在类型名后加上一对空方括号即可: int[] a1;………编译器不允许指定数组大小!!… 现在拥有的只是对数组的一个引用(你已经为该数组分配了足够的存储空间),而且也没有给数组对象本身分配任何空间。为了给数组分配相应的存储空间,必须写初始化表达式(new int[5],或者{1,2,3})。也就是说数组在声明时仅是一个引用,并不知道其大小,只有在初始化时才确定其大小。那么我将参数声明为一个数组,在方法内部用到的时候再去初始化,相当于在这个时候才确定其大小,正好可以接方法的参数个数不定的问题.
d,示例代码如下:
01 |
package org.simoncook.examtest; |
02 |
03 |
public class DynimacArg { |
04 |
05 |
static void printArray(Object[] args){ |
06 |
07 |
for (Object eachArg:args){ |
08 |
09 |
System.out.println(eachArg.toString()); |
10 |
11 |
} |
12 |
13 |
} |
14 |
15 |
|
16 |
17 |
public static void main(String[] args) { |
18 |
19 |
printArray( new Object[]{ 1 , 2 .0f, "a" }); |
20 |
21 |
} |
22 |
23 |
} |
e,在Java SE5中可变参数列表加了进来,就再也不用显示的编写数组语法了,当你指定参数时,编译器实际上会为你去填充数组,你获取的仍旧是一个数组,所有foreach迭代仍然是可行的
示例代码如下:
package org.simoncook.examtest;
public class NewVarArgs {
static void printArray(String... args){
for(String eachargs:args){
System.out.println(eachargs.toString());
}
}
public static void main(String[] args) {
printArray(new String[]{"new","var","args","-=-=-="});
}
}
当然你将0个参数传进去也是可行的(P103)
2.泛型方法
以下是一个基本原则:无论何时,只要你能做到,你就尽量使用泛型方法(Think In Java P361)
要定义泛型方法,只需将泛型列表置于返回值之前,像这样
public <T> void f(T x){
System.out.println(x.getClass().getName());
}
又或是例如:
public <T> T insert(T obj){
……
return obj;
}
3.泛型的规则和限制,扩展
可参考这篇文章的结尾部分http://blog.csdn.net/bluesmile979/archive/2009/03/10/3976905.aspx
a,extends语句
使用extends语句将限制泛型参数的适用范围,<T extends collection>则表示该泛型参数的使用范围是所有实现了collection接口的class,若传入String则出错。
b,super,<T super List>,表示该泛型参数只能是List或者List的上层父类
c,通配符,使用通配符的目的是为了解决泛型参数被限制死了不能动态根据实例来确定的缺点
举个例子:public class SampleClass < T extends S> {…}
假如A,B,C,…Z这26个class都实现了S接口。我们使用时需要使用到这26个class类型的泛型参数。那实例化的时候怎么办呢?依次写下
SampleClass<A> a = new SampleClass();
SampleClass<B> a = new SampleClass();
…
SampleClass<Z> a = new SampleClass();
这显然很冗余,还不如使用Object而不使用泛型,呵呵,是吧?
别着急,咱们使用通配符,就OK了。
SampleClass<? Extends S> sc = new SampleClass();
只需要声明一个sc变 量,很方便把!