Java泛型类似C++里面的模板,表示的是一种通用类型,这种技术可以减少因为类型导致的代码重复。
Java系统类库中的有些容器类也是使用泛型进行定义的,如List
、Map
。
对方法可以使用泛型返回值和泛型参数,泛型方法的调用同普通方法,系统会根据传入参数自动填入泛型参数。
泛型参数格式: <T1, T2, ...>
,位置放在方法的返回值之前。
例子:
public class Test {
//泛型方法printArray
public static <E> void printArray(E[] inputArray) {
//输出数组元素
for (E element : inputArray) {
System.out.printf("%s ", element);
}
System.out.println();
}
public static void main(String args[]) {
// 创建不同类型数组: Integer, Double 和 Character
Integer[] intArray = {1, 2, 3, 4, 5};
Double[] doubleArray = {1.1, 2.2, 3.3, 4.4};
Character[] charArray = {'H', 'E', 'L', 'L', 'O'};
System.out.println("整型数组元素为:");
printArray(intArray); // 传递一个整型数组
System.out.println("双精度型数组元素为:");
printArray(doubleArray); // 传递一个双精度型数组
System.out.println("字符型数组元素为:");
printArray(charArray); // 传递一个字符型数组
}
}
输出结果:
整型数组元素为:
1 2 3 4 5
双精度型数组元素为:
1.1 2.2 3.3 4.4
字符型数组元素为:
H E L L O
注意:泛型参数必须是引用类型,所以在上面例子上没有使用基本类型int、double和char,而使用了对应的包装类。这也是包装类的一个重要应用。
对类使用泛型参数,该参数在全类都有效,声明格式同泛型方法,位置放置于类名称之后。如class List<T>
。
泛型类的实例化和普通类不同,需要手动指定泛型参数,格式:
Class<Type> class = new Class(Arguments);
其中Type填入具体类型,注意只能是引用类型,如Integer
,不能只用基本类型。
例子:
public class Test<T> {
private T t;
public void set(T t) {
this.t = t;
}
public T get() {
return t;
}
public static void main(String[] args) {
Test<Integer> i = new Test<Integer>();
Test<String> s = new Test<String>();
i.set(new Integer(10));
s.set(new String("luoluolzb"));
System.out.println(i.get());
System.out.println(s.get());
}
}
输出:
10
luoluolzb
可能有时候,你会想限制传入参数只能使用某个类及其子类类型,如: <T extends Number>
,只接受Number或者Number子类类型。
例子:
class A {}
class B extends A {}
class D<T extends B>{}
public class Test {
public static void main(String[] args) {
//D<Integer> d1 = new D<Integer>(); //错误
//D<A> d2 = new D<A>(); //错误
D<B> d3 = new D<B>(); //正确
}
}
类型通配符是指在泛型参数中是使用?
代替具体的类型参数。
结合extends和super可以指定上下界:
<? extends T>
, 表示该通配符所代表的类型是T类及其子类。<? super T>
, 表示该通配符所代表的类型是T类及其父类。注意:泛型类型通配符只能在方法的参数列表中使用。
例子:
class A {}
class B extends A {}
class C extends B {}
class D<T> {}
public class Test {
static void f1(D<? extends B> b) {} //只能传入B及其子类
static void f2(D<? super B> b) {} //只能传入B及其父类
public static void main(String[] args) {
//f1(new D<A>()); //错误
f1(new D<B>());
f1(new D<C>());
f2(new D<A>());
f2(new D<B>());
//f2(new D<C>()); //错误
}
}
异常也是面对对象编程的重要技术之一。在Java中也毫无例外的提供了异常处理机制。
语法:
try {
throw ExceptObj;
} catch(ExceptionType1 e) {
//异常处理代码
} catch(ExceptionType2 e) {
//异常处理代码
} finally {
//总会被调用的代码
}
使用 throw 抛出一个异常对象(实际上throw可以抛出任何类型),随后的多个 catch 可以捕获类型相同的异常(父类也可以捕获到子类的异常对象)。
最后的 finally 的代码块总会被执行,无论有没有抛出异常。
try 语句块不可以独立存在,必须与 catch 或者 finally 块同存。cath可以有一个或多个,finally可以有也可以没有。
Java类库内置了很多异常类,具体可以查看API,如果开发中找不到合适的,也可以自己写一个异常类,自己写的异常类一般要继承Exception或它子类。
Java内置异常类:
thows 看起来和 throw 很像,这个多余的 s 指的 statement
—— 声明,用来在修饰函数可能会抛出一个异常。
如果一个方法没有捕获异常,那么该方法必须使用 throws 关键字来声明。throws 关键字放在方法的尾部。
例如:
public class Test {
public static void main(String[] args) throws Exception {
throw new Exception();
}
}
本文标签: Java
暂无评论,赶紧发表一下你的看法吧。