Class<T>在实例化的时候,T要替换成具体类
Class<?>它是个通配泛型,?可以代表任何类型
<? extends T>受限统配,表示T的一个未知子类。
<? super T>下限统配,表示T的一个未知父类。
ava 的泛型,只是编译时作为类型检查,一旦编译完成,泛型就会被擦除,在运行期间是得不到泛型的信息的,包括它的类型参数。有时候我们需要用到泛型的类型参数,反射看起来是取不到的,因反射在运行期间执行,但那时已无泛型的信息。一些构架却办到了,那么它们是怎么实现的呢?请看下面代码:
- import java.lang.reflect.*;
- import java.util.*;
- class Test {
- public static void main(String args[]) throws Exception {
- Method applyMethod=Test.class.getMethod("applyVector", Vector.class);
- Type[] types=applyMethod.getGenericParameterTypes();
- System.out.println(types[0].toString());
- }
- public static void applyVector(Vector<Date> v1){
- }
- }
看到了,实际上是通过获得方法,再取得方法的类型参数,这样泛型的实际类型参数就出来了。上面代码输出:java.util.Vector<java.util.Date>,如果不只一个参数,要具体的类型参数呢?
- import java.lang.reflect.*;
- import java.util.*;
- class Test {
- public static void main(String args[]) throws Exception {
- Method applyMethod=Test.class.getMethod("applyVector", Vector.class);
- Type[] types=applyMethod.getGenericParameterTypes();
- ParameterizedType pType=(ParameterizedType)types[0];
- System.out.println(pType.getActualTypeArguments()[0]);
- System.out.println(pType.getRawType());
- }
- public static void applyVector(Vector<Date> v1){
- }
- }
输出:
class java.util.Date
class java.util.Vector
可见,getActualTypeArguments 能取得实际类型参数,getRawType() 取得原本的类型。
3:T...java中可变参数
Java1.5增加了新特性:可变参数:适用于参数个数不确定,类型确定的情况,java把可变参数当做数组处理。注意:可变参数必须位于最后一项。当可变参数个数多余一个时,必将有一个不是最后一项,所以只支持有一个可变参数。因为参数个数不定,所以当其后边还有相同类型参数时,java无法区分传入的参数属于前一个可变参数还是后边的参数,所以只能让可变参数位于最后一项。
可变参数的特点:
(1)、只能出现在参数列表的最后;
(2)、...位于变量类型和变量名之间,前后有无空格都可以;
(3)、调用可变参数的方法时,编译器为该可变参数隐含创建一个数组,在方法体中一数组的形式访问可变参数。
apache lang 中StringUtils
@Test
public void testJoin_Objects() {
assertEquals("abc", StringUtils.join("a", "b", "c"));
assertEquals("a", StringUtils.join(null, "", "a"));
assertEquals(null, StringUtils.join((Object[])null));
}
public static <T> String join(final T... elements) {
return join(elements, null);
}
public static String join(final Object[] array, final String separator) {
if (array == null) {
return null;
}
return join(array, separator, 0, array.length);
}
public static String join(final Object[] array, String separator, final int startIndex, final int endIndex) {
if (array == null) {
return null;
}
if (separator == null) {
separator = EMPTY;
}
// endIndex - startIndex > 0: Len = NofStrings *(len(firstString) + len(separator))
// (Assuming that all Strings are roughly equally long)
final int noOfItems = endIndex - startIndex;
if (noOfItems <= 0) {
return EMPTY;
}
final StringBuilder buf = new StringBuilder(noOfItems * 16);
for (int i = startIndex; i < endIndex; i++) {
if (i > startIndex) {
buf.append(separator);
}
if (array[i] != null) {
buf.append(array[i]);
}
}
return buf.toString();
}